using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ImageBlockz.Operations;
using ImageBlockz.Api;

namespace ImageBlockz.Operations.Controls
{
    public partial class ConvolutionControl : OperationControl
    {
        
        private ImageBlockz.Operations.Convolutions.Convolution convolution;

        public ConvolutionControl()
            : base(typeof(ImageBlockz.Operations.Convolutions.Convolution).FullName)
        {
            IsPreview = true;
            InitializeComponent();
        }

        public override IOperation GetOperation()
        {
            convolution.Kernel = Matrix;
            return convolution;
        }

        public override void SetOperation(IOperation operation)
        {
            base.SetOperation(operation);

            if (operation is ImageBlockz.Operations.Convolutions.Convolution == false)
            {
                throw new ArgumentException("operation", "Argument operation is not instance of "
                    + typeof(ImageBlockz.Operations.Convolutions.Convolution).FullName);
            }

            convolution = (ImageBlockz.Operations.Convolutions.Convolution)operation;
        }

        public override bool OnOK()
        {
            convolution.Kernel = Matrix;
            return true;
        }

        public override void ShowData()
        {
            if (IsNew)
            {
                Matrix = ZerosMatrix;

            }
            else
            {
                convolution.Kernel = Matrix;
            }
        }

        public int[,] Matrix
        {
            get
            {
                try
                {
                    int[,] matrix = new int[3, 3];
                    matrix[0, 0] = Int32.Parse(eTopLeft.Text);
                    matrix[0, 1] = Int32.Parse(eTopMid.Text);
                    matrix[0, 2] = Int32.Parse(eTopRight.Text);
                    matrix[1, 0] = Int32.Parse(eMidLeft.Text);
                    matrix[1, 1] = Int32.Parse(eMidMid.Text);
                    matrix[1, 2] = Int32.Parse(eMidRight.Text);
                    matrix[2, 0] = Int32.Parse(eBottomLeft.Text);
                    matrix[2, 1] = Int32.Parse(eBottomMid.Text);
                    matrix[2, 2] = Int32.Parse(eBottomRight.Text);

                    return matrix;
                }
                catch
                {
                    MessageBox.Show("Wrong value. Use integer numbers only. Identity is used for now.");
                    
                    return IdentityMatrix;
                }
            }
            set
            {
                eTopLeft.Text = value[0,0].ToString();
                eTopMid.Text = value[0,1].ToString();
                eTopRight.Text = value[0,2].ToString();
                eMidLeft.Text = value[1,0].ToString();
                eMidMid.Text = value[1,1].ToString();
                eMidRight.Text = value[1,2].ToString();
                eBottomLeft.Text = value[2,0].ToString();
                eBottomMid.Text = value[2,1].ToString();
                eBottomRight.Text = value[2,2].ToString();
            }
        }

        private int[,] GaussMatrix
        {
            get
            {
                int[,] matrix = new int[3, 3];
                matrix[0, 0] = 1;
                matrix[0, 1] = 2;
                matrix[0, 2] = 1;
                matrix[1, 0] = 2;
                matrix[1, 1] = 4;
                matrix[1, 2] = 2;
                matrix[2, 0] = 1;
                matrix[2, 1] = 2;
                matrix[2, 2] = 1;

                return matrix;
            }
        }

        private int[,] SharpMatrix
        {
            get
            {
                int[,] matrix = new int[3, 3];
                matrix[0, 0] =  0;
                matrix[0, 1] = -2;
                matrix[0, 2] =  0;
                matrix[1, 0] = -2;
                matrix[1, 1] = 11;
                matrix[1, 2] = -2;
                matrix[2, 0] =  0;
                matrix[2, 1] = -2;
                matrix[2, 2] =  0;

                return matrix;
            }
        }

        private int[,] SmoothMatrix
        {
            get
            {
                int[,] matrix = new int[3, 3];
                matrix[0, 0] = 1;
                matrix[0, 1] = 1;
                matrix[0, 2] = 1;
                matrix[1, 0] = 1;
                matrix[1, 1] = 1;
                matrix[1, 2] = 1;
                matrix[2, 0] = 1;
                matrix[2, 1] = 1;
                matrix[2, 2] = 1;

                return matrix;
            }
        }

        private int[,] MeanRemMatrix
        {
            get
            {
                int[,] matrix = new int[3, 3];
                matrix[0, 0] = -1;
                matrix[0, 1] = -1;
                matrix[0, 2] = -1;
                matrix[1, 0] = -1;
                matrix[1, 1] =  9;
                matrix[1, 2] = -1;
                matrix[2, 0] = -1;
                matrix[2, 1] = -1;
                matrix[2, 2] = -1;

                return matrix;
            }
        }

        private int[,] EmbossMatrix
        {
            get
            {   // to emboss is offset needed
                int[,] matrix = new int[3, 3];
                matrix[0, 0] = -1;
                matrix[0, 1] =  0;
                matrix[0, 2] = -1;
                matrix[1, 0] =  0;
                matrix[1, 1] =  4;
                matrix[1, 2] =  0;
                matrix[2, 0] = -1;
                matrix[2, 1] =  0;
                matrix[2, 2] = -1;

                return matrix;
            }
        }

        private int[,] EdgeDetectionMatrix
        {
            get
            {
                int[,] matrix = new int[3, 3];
                matrix[0, 0] = 1;
                matrix[0, 1] = 1;
                matrix[0, 2] = 1;
                matrix[1, 0] = 0;
                matrix[1, 1] = 0;
                matrix[1, 2] = 0;
                matrix[2, 0] = -1;
                matrix[2, 1] = -1;
                matrix[2, 2] = -1;

                return matrix;
            }
        }

        private int[,] ZerosMatrix
        {
            get
            {
                int[,] matrix = new int[3, 3];
                matrix[0, 0] = 0;
                matrix[0, 1] = 0;
                matrix[0, 2] = 0;
                matrix[1, 0] = 0;
                matrix[1, 1] = 0;
                matrix[1, 2] = 0;
                matrix[2, 0] = 0;
                matrix[2, 1] = 0;
                matrix[2, 2] = 0;

                return matrix;
            }
        }

        private int[,] IdentityMatrix
        {
            get
            {
                int[,] matrix = new int[3, 3];
                matrix[0, 0] = 0;
                matrix[0, 1] = 0;
                matrix[0, 2] = 0;
                matrix[1, 0] = 0;
                matrix[1, 1] = 1;
                matrix[1, 2] = 0;
                matrix[2, 0] = 0;
                matrix[2, 1] = 0;
                matrix[2, 2] = 0;

                return matrix;
            }
        }

        private void bGauss_Click(object sender, EventArgs e)
        {
            Matrix = GaussMatrix;
        }

        private void bSharp_Click(object sender, EventArgs e)
        {
            Matrix = SharpMatrix;
        }

        private void bSmooth_Click(object sender, EventArgs e)
        {
            Matrix = SmoothMatrix;
        }

        private void bMeanRem_Click(object sender, EventArgs e)
        {
            Matrix = MeanRemMatrix;
        }

        private void bEmboss_Click(object sender, EventArgs e)
        {
            Matrix = EmbossMatrix;
        }

        private void bEdgeDet_Click(object sender, EventArgs e)
        {
            Matrix = EdgeDetectionMatrix;
        }

        private void bZeros_Click(object sender, EventArgs e)
        {
            Matrix = ZerosMatrix;
        }

        private void bIdentity_Click(object sender, EventArgs e)
        {
            Matrix = IdentityMatrix;
        }
    }
}
