using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Scoring
{
    public partial class Form1 : Form
    {
        Individual test;
        public Form1()
        {
            InitializeComponent();

            target.Image = Image.FromFile("C:\\Users\\alexa\\OneDrive\\Desktop\\Capstone26\\code\\genetic algorithm\\scoring\\Scoring\\bart.bmp");
            //****IMPORTANT NOTE: the individual needs to be the same size (in pixels) as the target IMAGE [not the picturebox]*****************************
            Console.WriteLine("target, width: " + target.Image.Width);
            Console.WriteLine("target, height: " + target.Image.Height);
            //test = new Individual(target.Image.Width, target.Image.Height);
            //toScore.Image = test.TheImage;
            //toScore.Image = Image.FromFile("C:\\Users\\alexa\\OneDrive\\Desktop\\Capstone26\\code\\genetic algorithm\\scoring\\Scoring\\red.bmp");
           
        }
        //FUNCTION: scoreV1
        //PARAMETERS: 2 'image' objects
        //PURPOSE: Given a target image and an image to score (assuming both images are solid colors), the function will
        //         score the pixel at (0,0) by taking the sum of the absolute value of the difference in RGB values...
        //         observe: |target.RED - toScore.RED| + |target.GREEN - toScore.GREEN| + |target.BLUE - toScore.BLUE|
        public void scoreV0(Image targetImage, Image toScoreImage)
        {
            Bitmap targetBtmp = (Bitmap)targetImage;      
            Bitmap toScoreBtmp = (Bitmap)toScoreImage;

            Color targetPx = targetBtmp.GetPixel(0, 0);     
            Color toScorePx = toScoreBtmp.GetPixel(0, 0);

            int score = Math.Abs(targetPx.R - toScorePx.R) + Math.Abs(targetPx.G - toScorePx.G) + Math.Abs(targetPx.B - toScorePx.B);
            tbScore.Text = (score).ToString();
        }
        //FUNCTION: scoreV1
        //PARAMETERS: 2 'image' objects
        //PURPOSE: Given a target image and an image to score (assuming both images are solid colors), the function will
        //         score the pixel at (0,0) by taking the sum of the absolute value of the difference in RGB values multipled by
        //         the total number of pixel in the bitmap image...
        //         observe: (|target.RED - toScore.RED| + |target.GREEN - toScore.GREEN| + |target.BLUE - toScore.BLUE|) * (width*height)
        public void scoreV1(Image targetImage, Image toScoreImage)
        {
            Bitmap targetBtmp = (Bitmap)targetImage;
            Bitmap toScoreBtmp = (Bitmap)toScoreImage;

            int width = targetBtmp.Width;
            int height = targetBtmp.Height;

            Color targetPx = targetBtmp.GetPixel(0, 0);
            Color toScorePx = toScoreBtmp.GetPixel(0, 0);

            int score = (Math.Abs(targetPx.R - toScorePx.R) + Math.Abs(targetPx.G - toScorePx.G) + Math.Abs(targetPx.B - toScorePx.B)) * (width*height);
            tbScore.Text = (score).ToString();
        }
        //FUNCTION: scoreV2
        //PARAMETERS: 2 'image' objects
        //PURPOSE: Given a target image and an image to score (either can be a solid color or two different colors
        //         [eg. half blue, half purple - split horizonally]). The function will score two pixels (0,0) and (0,[(width/2)+2])...sum the scores
        //         which is the score of the image-to-score.
        //         observe: (|target.RED - toScore.RED| + |target.GREEN - toScore.GREEN| + |target.BLUE - toScore.BLUE|)
        public void scoreV2(Image targetImage, Image toScoreImage)
        {
            Bitmap targetBtmp = (Bitmap)targetImage;
            Bitmap toScoreBtmp = (Bitmap)toScoreImage;

            int width = targetBtmp.Width;
            int height = targetBtmp.Height;

            Color targetPx, toScorePx;

            int score = 0;
            int stride = (width / 2) + 2;
            Console.WriteLine("jump: " + stride);
            int x; int y = 0; 
          
            for(x = 0; x < width; x += stride)
            {
                targetPx = targetBtmp.GetPixel(x, y);
                toScorePx = toScoreBtmp.GetPixel(x, y);

                score += (Math.Abs(targetPx.R - toScorePx.R) + Math.Abs(targetPx.G - toScorePx.G) + Math.Abs(targetPx.B - toScorePx.B));
            }
            tbScore.Text = (score).ToString();
        }
        //FUNCTION: scoreV3
        //PARAMETERS: 2 'image' objects
        //PURPOSE: Given a target image and an image to score (either can be a solid color or two different colors
        //         [eg. half blue, half purple - split horizonally]). The function will score two pixels (0,0) and (0,[(width/2)+2])...sum the scores
        //         which is the score of the image-to-score.
        //         observe: (|target.RED - toScore.RED| + |target.GREEN - toScore.GREEN| + |target.BLUE - toScore.BLUE|) * (width*height) 
        public void scoreV3(Image targetImage, Image toScoreImage)
        {
            Bitmap targetBtmp = (Bitmap)targetImage;
            Bitmap toScoreBtmp = (Bitmap)toScoreImage;

            int width = targetBtmp.Width;
            int height = targetBtmp.Height;

            Color targetPx, toScorePx;

            int score = 0;
            int stride = (width / 2) + 2;
            Console.WriteLine("jump: " + stride);
            int x; int y = 0;

            for (x = 0; x < width; x += stride)
            {
                targetPx = targetBtmp.GetPixel(x, y);
                toScorePx = toScoreBtmp.GetPixel(x, y);

                score += (Math.Abs(targetPx.R - toScorePx.R) + Math.Abs(targetPx.G - toScorePx.G) + Math.Abs(targetPx.B - toScorePx.B)) * (width * height);
            }
            tbScore.Text = (score).ToString();
        }
        //FUNCTION: scoreV4
        //PARAMETERS: 2 'image' objects
        //PURPOSE: Given a target image and an image to score (either can be a solid color or multi-colored), compute the score of the image to score compared
        //         to the target image using the given formula;
        //         observe: (|target.RED - toScore.RED| + |target.GREEN - toScore.GREEN| + |target.BLUE - toScore.BLUE|) * (width * height)
        //         This version of the function compares every pixel of the given images.
        public void scoreV4(Image targetImage, Image toScoreImage)
        {
            Bitmap targetBtmp = (Bitmap)targetImage;
            Bitmap toScoreBtmp = (Bitmap)toScoreImage;

            int width = targetBtmp.Width;
            int height = targetBtmp.Height;
            Console.WriteLine("width: " + width);
            Console.WriteLine("height: " + height);

            Color targetPx, toScorePx;

            int score = 0;

            for(int y = 0; y < height; y++)
            {
                for(int x = 0; x < width; x++)
                {
                    targetPx = targetBtmp.GetPixel(x, y);
                    toScorePx = toScoreBtmp.GetPixel(x, y);

                    score += (Math.Abs(targetPx.R - toScorePx.R) + Math.Abs(targetPx.G - toScorePx.G) + Math.Abs(targetPx.B - toScorePx.B)) * (width * height);
                    Console.WriteLine("current score: " + score.ToString());
                }
            }
            tbScore.Text = (score).ToString();
        }
        //FUNCTION: scoreV5
        //PARAMETERS: target 'Image' and an 'Individual'
        //PURPOSE: The function 'scoreV5' is called on an 'Individual' and takes a target image - a cartoon like image and to compute the  
        //         Individual's score. The function uses the Red, Green, Blue (RGB) values of pixels to compute the score AND updates the 'Individual's' score
        //         observe: (|target.RED - toScore.RED| + |target.GREEN - toScore.GREEN| + |target.BLUE - toScore.BLUE|)
        //***NOTE: the images must be the same pixel size

        private void btnClick(object sender, EventArgs e)
        {
            //test.scoreIndividual(target.Image);
            test = new Individual(target.Image.Width, target.Image.Height, target.Image);
            toScore.Image = test.TheImage;
            tbScore.Text = test.Score.ToString();
        }
    }
}
