using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using C1.Silverlight.Imaging;
using C1.Silverlight;
using System.IO;
using System.Reflection;

namespace Crop
{
    public partial class MainPage : UserControl
    {
        C1Bitmap bitmap = new C1Bitmap();
        Rect selection;
        
        public MainPage()
        {
            InitializeComponent();

            LoadDefaultImage();
            image.Source = bitmap.ImageSource;

            var mouseHelper = new C1DragHelper(imageGrid);
            mouseHelper.DragStarted += OnDragStarted;
            mouseHelper.DragDelta += OnDragDelta;
        }

        Point _startPosition;
        void OnDragStarted(object sender, C1DragStartedEventArgs e)
        {
            _startPosition = e.GetPosition(null);
        }

        void OnDragDelta(object sender, C1DragDeltaEventArgs e)
        {
            var transform = Application.Current.RootVisual.TransformToVisual(image);
            var start = transform.Transform(_startPosition);
            var end = transform.Transform(e.GetPosition(null));
            start.X = Math.Min(Math.Max(start.X, 0), bitmap.Width);
            end.X = Math.Min(Math.Max(end.X, 0), bitmap.Width);
            start.Y = Math.Min(Math.Max(start.Y, 0), bitmap.Height);
            end.Y = Math.Min(Math.Max(end.Y, 0), bitmap.Height);

            selection = new Rect(new Point(
                Math.Round(Math.Min(start.X, end.X)),
                Math.Round(Math.Min(start.Y, end.Y))),
                new Size(Math.Round(Math.Abs(start.X - end.X)), Math.Round(Math.Abs(start.Y - end.Y))));

            UpdateMask();
        }

        void UpdateMask()
        {
            topMask.Height = selection.Top;
            bottomMask.Height = bitmap.Height - selection.Bottom;
            leftMask.Width = selection.Left;
            rightMask.Width = bitmap.Width - selection.Right;
        }

        void LoadDefaultImage()
        {
            LoadImageStream(Application.GetResourceStream(new Uri("/" + new AssemblyName(Assembly.GetExecutingAssembly().FullName).Name + ";component/Lenna.jpg", UriKind.Relative)).Stream);
        }

        private void LoadImage(object sender, RoutedEventArgs e)
        {
            var dialog = new OpenFileDialog
            {
                Filter = "Image files (png, jpeg or gif)|*.png;*.jpg;*.gif;*.jpeg|All files|*.*"
            };

            dialog.ShowDialog();
            if (dialog.File != null)
            {
                using (var fileStream = dialog.File.OpenRead())
                {
                    try
                    {
                        LoadImageStream(fileStream);
                    }
                    catch (Exception ex)
                    {
                        LoadDefaultImage();
                        C1MessageBox.Show("Image format not supported, error: \n" + ex.Message, "", C1MessageBoxIcon.Error);
                    }
                }
            }
        }

        void LoadImageStream(Stream stream)
        {
            bitmap.SetStream(stream);
            
            imageGrid.Width = bitmap.Width;
            imageGrid.Height = bitmap.Height;

            selection = new Rect(0, 0, bitmap.Width, bitmap.Height);
            UpdateMask();
        }

        private void ExportImage(object sender, RoutedEventArgs e)
        {
            if(selection.Width == 0 || selection.Height == 0)
            {
                C1MessageBox.Show("Can't export, selection is empty");
                return;
            }
            var dialog = new SaveFileDialog 
            { 
                DefaultExt=".png", 
                Filter="PNG Files | *.png" 
            };
            var save = dialog.ShowDialog();
            if (save.HasValue && save.Value)
            {
                var saveStream = dialog.OpenFile();
                var crop = new C1Bitmap((int)selection.Width, (int)selection.Height);
                crop.BeginUpdate();
                for (int x = 0; x < selection.Width; ++x)
                {
                    for (int y = 0; y < selection.Height; ++y)
                    {
                        crop.SetPixel(x, y, bitmap.GetPixel(x + (int)selection.X, y + (int)selection.Y));
                    }
                }
                crop.EndUpdate();
                var readStream = crop.GetStream(ImageFormat.Png, true);
                var data = new byte[readStream.Length];
                readStream.Read(data, 0, (int)readStream.Length);
                saveStream.Write(data, 0, data.Length);
                saveStream.Close();
            }
        }
    }
}
