using MainShell.Common;
using System;

namespace MainShell.Vision
{
    /// <summary>
    /// 视觉失败分类。
    /// </summary>
    public enum VisionFailureCategory
    {
        None = 0,
        Validation = 1,
        Cancelled = 2,
        Capture = 3,
        Algorithm = 4,
        Driver = 5,
    }

    /// <summary>
    /// 视觉错误码定义。
    /// </summary>
    public enum VisionErrorCode
    {
        None = 0,

        RequestInvalid = 1000,
        TimeoutInvalid = 1001,
        TemplatePathEmpty = 1002,
        RoiNameEmpty = 1003,
        MinScoreInvalid = 1004,

        OperationCancelled = 1100,

        CameraNotFound = 1200,
        CameraNotOpen = 1201,
        CameraNotGrabbing = 1202,
        CaptureTimeout = 1203,
        NoFrame = 1204,
        SoftTriggerFailed = 1205,
        DriverError = 1206,
        ImageNull = 1207,

        TemplateAlgorithmNotImplemented = 1300,
        TemplateMatchFailed = 1301,
        TemplateResultInvalid = 1302,
        CommonAlgorithmNotSupported = 1400,
        CommonAlgorithmExecutionFailed = 1401,
        ChipMapSortInputInvalid = 1402,
    }

    /// <summary>
    /// Vision 报警号定义。
    /// </summary>
    public static class VisionAlarmIds
    {
        public const int CameraNotFound = 13000;
        public const int CameraNotOpen = 13001;
        public const int CameraNotGrabbing = 13002;
        public const int CaptureTimeout = 13003;
        public const int NoFrame = 13004;
        public const int SoftTriggerFailed = 13005;
        public const int DriverError = 13006;
        public const int ImageNull = 13007;
        public const int RequestInvalid = 13008;

        public const int TemplatePathEmpty = 13100;
        public const int TemplateRoiInvalid = 13103;
        public const int TemplateMinScoreInvalid = 13104;
        public const int TemplateAlgorithmNotImplemented = 13105;
        public const int TemplateMatchFailed = 13106;
        public const int TemplateResultInvalid = 13107;
        public const int CommonAlgorithmNotSupported = 13200;
        public const int CommonAlgorithmExecutionFailed = 13201;
        public const int ChipMapSortInputInvalid = 13202;
    }

    /// <summary>
    /// Vision 结果映射帮助类。
    /// </summary>
    public static class VisionResultMapper
    {
        public static VisionProcessResult CreateCaptureFailure(ImageCaptureResult captureResult)
        {
            if (captureResult == null)
            {
                return VisionProcessResult.Failure(
                    VisionFailureCategory.Capture,
                    VisionErrorCode.NoFrame,
                    VisionAlarmIds.NoFrame,
                    MessageKey.VisionNoFrameReturned,
                    "Vision capture result is null.");
            }

            switch (captureResult.Status)
            {
                case ImageCaptureStatus.Cancelled:
                    return VisionProcessResult.Failure(
                        VisionFailureCategory.Cancelled,
                        VisionErrorCode.OperationCancelled,
                        null,
                        MessageKey.VisionOperationCancelled,
                        captureResult.Message,
                        captureResult.Exception);

                case ImageCaptureStatus.CameraNotFound:
                    return VisionProcessResult.Failure(
                        VisionFailureCategory.Capture,
                        VisionErrorCode.CameraNotFound,
                        VisionAlarmIds.CameraNotFound,
                        MessageKey.VisionCameraNotFound,
                        captureResult.Message,
                        captureResult.Exception);

                case ImageCaptureStatus.CameraNotOpen:
                    return VisionProcessResult.Failure(
                        VisionFailureCategory.Capture,
                        VisionErrorCode.CameraNotOpen,
                        VisionAlarmIds.CameraNotOpen,
                        MessageKey.VisionCameraNotOpen,
                        captureResult.Message,
                        captureResult.Exception);

                case ImageCaptureStatus.CameraNotGrabbing:
                    return VisionProcessResult.Failure(
                        VisionFailureCategory.Capture,
                        VisionErrorCode.CameraNotGrabbing,
                        VisionAlarmIds.CameraNotGrabbing,
                        MessageKey.VisionCameraNotGrabbing,
                        captureResult.Message,
                        captureResult.Exception);

                case ImageCaptureStatus.Timeout:
                    return VisionProcessResult.Failure(
                        VisionFailureCategory.Capture,
                        VisionErrorCode.CaptureTimeout,
                        VisionAlarmIds.CaptureTimeout,
                        MessageKey.VisionCaptureTimeout,
                        captureResult.Message,
                        captureResult.Exception);

                case ImageCaptureStatus.NoFrame:
                    return VisionProcessResult.Failure(
                        VisionFailureCategory.Capture,
                        VisionErrorCode.NoFrame,
                        VisionAlarmIds.NoFrame,
                        MessageKey.VisionNoFrameReturned,
                        captureResult.Message,
                        captureResult.Exception);

                case ImageCaptureStatus.SoftTriggerFailed:
                    return VisionProcessResult.Failure(
                        VisionFailureCategory.Driver,
                        VisionErrorCode.SoftTriggerFailed,
                        VisionAlarmIds.SoftTriggerFailed,
                        MessageKey.VisionSoftTriggerFailed,
                        captureResult.Message,
                        captureResult.Exception);

                default:
                    return VisionProcessResult.Failure(
                        VisionFailureCategory.Driver,
                        VisionErrorCode.DriverError,
                        VisionAlarmIds.DriverError,
                        MessageKey.VisionDriverError,
                        captureResult.Message,
                        captureResult.Exception);
            }
        }

        public static int? GetAlarmId(VisionErrorCode errorCode)
        {
            switch (errorCode)
            {
                case VisionErrorCode.RequestInvalid:
                case VisionErrorCode.TimeoutInvalid:
                    return VisionAlarmIds.RequestInvalid;

                case VisionErrorCode.TemplatePathEmpty:
                    return VisionAlarmIds.TemplatePathEmpty;

                case VisionErrorCode.RoiNameEmpty:
                    return VisionAlarmIds.TemplateRoiInvalid;

                case VisionErrorCode.MinScoreInvalid:
                    return VisionAlarmIds.TemplateMinScoreInvalid;

                case VisionErrorCode.CameraNotFound:
                    return VisionAlarmIds.CameraNotFound;

                case VisionErrorCode.CameraNotOpen:
                    return VisionAlarmIds.CameraNotOpen;

                case VisionErrorCode.CameraNotGrabbing:
                    return VisionAlarmIds.CameraNotGrabbing;

                case VisionErrorCode.CaptureTimeout:
                    return VisionAlarmIds.CaptureTimeout;

                case VisionErrorCode.NoFrame:
                    return VisionAlarmIds.NoFrame;

                case VisionErrorCode.SoftTriggerFailed:
                    return VisionAlarmIds.SoftTriggerFailed;

                case VisionErrorCode.DriverError:
                    return VisionAlarmIds.DriverError;

                case VisionErrorCode.ImageNull:
                    return VisionAlarmIds.ImageNull;

                case VisionErrorCode.TemplateAlgorithmNotImplemented:
                    return VisionAlarmIds.TemplateAlgorithmNotImplemented;

                case VisionErrorCode.TemplateMatchFailed:
                    return VisionAlarmIds.TemplateMatchFailed;

                case VisionErrorCode.TemplateResultInvalid:
                    return VisionAlarmIds.TemplateResultInvalid;

                case VisionErrorCode.CommonAlgorithmNotSupported:
                    return VisionAlarmIds.CommonAlgorithmNotSupported;

                case VisionErrorCode.CommonAlgorithmExecutionFailed:
                    return VisionAlarmIds.CommonAlgorithmExecutionFailed;

                case VisionErrorCode.ChipMapSortInputInvalid:
                    return VisionAlarmIds.ChipMapSortInputInvalid;

                default:
                    return null;
            }
        }
    }
}
