using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;

namespace DEM2Contour
{
	public partial class MainForm : Form
    {
		private DEMData demData;//读取文件得到的DEM数据
		private DEMData calData;//计算出来的DEM数据
		private int amplification = 3;//插值放大倍数

        public MainForm()
        {
            InitializeComponent();
        }

		//加载DEM
		private void button_LoadDEMData_Click(object sender, EventArgs e)
		{
			OpenFileDialog openFileDialog = new OpenFileDialog();
			openFileDialog.Filter = "数据文件(*.csv)|*.csv";

			if (openFileDialog.ShowDialog() == DialogResult.OK)
			{
				FileStream fileStream = new FileStream(openFileDialog.FileName, FileMode.Open);
				StreamReader stream = new StreamReader(fileStream);
				string allData = stream.ReadToEnd();
				fileStream.Close();

				demData = new DEMData(allData);
				pictureBox_initialData.Image = demData.DEMBitmap();
				label_initialData.Text = "最高值：" + demData.MaxValue.ToString("0.##") + "\n最低值：" + demData.MinValue.ToString("0.##");
                button_ChoosePoints.Enabled = true;
            }
		}

		//随机点数据
		private List<AltitudePoint> pointList;

		//插值类
		private InterpolationData interpolation;

		//选取随机点
		private void button_ChoosePoints_Click(object sender, EventArgs e)
		{
			progressBar_Deal.Value = 0;
			pictureBox_InterpolationData.Image = null;
			//不断尝试，直到数据满足要求
			do
			{
				pointList = demData.GetRandomPoints();
				interpolation = new InterpolationData(pointList, demData.row, demData.column);
			}
			while (!interpolation.IsRandomPointsOK());

			Bitmap bitmap = new Bitmap(demData.DEMBitmap());
			int length = demData.DEMCellSize;
			Graphics graphics = Graphics.FromImage(bitmap);

			foreach(AltitudePoint point in pointList)
			{
				graphics.FillEllipse(Brushes.Black,
					new RectangleF((float)point.Y * demData.DEMCellSize,
					(float)point.X * demData.DEMCellSize,
					length,
					length));
            }
			pictureBox_initialData.Image = bitmap;

			button_SavePointsData.Enabled = true;
			button_Interpolation.Enabled = true;
        }

		//保存随机点数据
		private void button_SavePointsData_Click(object sender, EventArgs e)
		{
			//左上角为原点
			SaveFileDialog saveFileDialog = new SaveFileDialog();
			saveFileDialog.FileName = "随机点数据";
			saveFileDialog.Filter = "数据文件(*.csv)|*.csv";

			if (saveFileDialog.ShowDialog() == DialogResult.OK)
			{
				FileStream fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create);
				StreamWriter streamwriter = new StreamWriter(fileStream, Encoding.Default);
				foreach(AltitudePoint point in pointList)
				{
					streamwriter.WriteLine(point.ToString());
                }
				streamwriter.Close();
                fileStream.Close();
            }
		}

		//插值
		private void button_Interpolation_Click(object sender, EventArgs e)
		{
			try
			{
				calData = new DEMData(interpolation.GetInterpolationData(this.progressBar_Deal, amplification));
			}
			catch(Exception exception)
			{
				MessageBox.Show(exception.Message);
				return;
			}
			button_SaveInterpolation.Enabled = true;
			button_DrawContour.Enabled = true;
			textBox_Interval.Enabled = true;

			interpolation.GetDrawingInfo();
            pictureBox_InterpolationData.Image = calData.DEMBitmap();
			demBitmapWithoutContour= calData.DEMBitmap();
			label_InterpolationData.Text = "最高值：" + calData.MaxValue.ToString("0.##") + "\n最低值：" + calData.MinValue.ToString("0.##");
		}

		//保存内插的数据
		private void button_SaveInterpolation_Click(object sender, EventArgs e)
		{
			SaveFileDialog saveFileDialog = new SaveFileDialog();
			saveFileDialog.FileName = "内插值数据";
			saveFileDialog.Filter = "数据文件(*.csv)|*.csv";

			if (saveFileDialog.ShowDialog() != DialogResult.OK) return;

			FileStream fileStream = new FileStream(saveFileDialog.FileName, FileMode.Create);
			int length;
			fileStream.Write(interpolation.GetByteInterpolationData(out length), 0, length);
			fileStream.Close();
		}

		//未绘制等高线的DEM插值图像
		private Image demBitmapWithoutContour;

		//绘制等高线
		private void button_DrawContour_Click(object sender, EventArgs e)
		{
			MarchingSquares marchingSquares = new MarchingSquares(calData.altitudeData, Convert.ToDouble(textBox_Interval.Text), calData.MinValue, calData.MaxValue);
			Bitmap image = new Bitmap(demBitmapWithoutContour);
			Graphics g = Graphics.FromImage(image);
			g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
			int length = calData.DEMCellSize;
			Pen pen = new Pen(Color.Black, calData.DEMCellSize / 5f);

			foreach (var lines in marchingSquares.contourData)
			{
				foreach (var line in lines.Value)
				{
					g.DrawLine(pen, line.startPoint.Y * length, image.Height - line.startPoint.X * length, line.endPoint.Y * length, image.Height - line.endPoint.X * length);
				}
			}
			pictureBox_InterpolationData.Image = image;
		}

		//右键保存图像
		private void ToolStripMenuItem_SavePicture_Click(object sender, EventArgs e)
		{
			PictureBox pictureBox = (PictureBox)((sender as ToolStripMenuItem).Owner as ContextMenuStrip).SourceControl;
            SaveFileDialog saveFileDialog = new SaveFileDialog();
			saveFileDialog.FileName = pictureBox.Name.Split('_').Last() + ".jpg";
			if (saveFileDialog.ShowDialog() != DialogResult.OK) return;
			pictureBox.Image.Save(saveFileDialog.FileName);
        }

		//pictureBox鼠标移动事件
		private void pictureBox_InterpolationData_MouseMove(object sender, MouseEventArgs e)
		{
			if (pictureBox_InterpolationData.Image == null) return;
			int originalWidth = pictureBox_InterpolationData.Image.Width;
			int originalHeight = pictureBox_InterpolationData.Image.Height;

			PropertyInfo rectangleProperty = pictureBox_InterpolationData.GetType().GetProperty("ImageRectangle", BindingFlags.Instance | BindingFlags.NonPublic);
			Rectangle rectangle = (Rectangle)rectangleProperty.GetValue(pictureBox_InterpolationData, null);

			int currentWidth = rectangle.Width;
			int currentHeight = rectangle.Height;

			double rate = (double)currentHeight / (double)originalHeight;

			int black_left_width = (currentWidth == pictureBox_InterpolationData.Width) ? 0 : (pictureBox_InterpolationData.Width - currentWidth) / 2;
			int black_top_height = (currentHeight == pictureBox_InterpolationData.Height) ? 0 : (pictureBox_InterpolationData.Height - currentHeight) / 2;

			int zoom_x = e.X - black_left_width;
			int zoom_y = e.Y - black_top_height;

			double original_x = (double)zoom_x / rate;
			double original_y = (double)zoom_y / rate;

			int x = (int)(original_x / calData.DEMCellSize);
			int y= (int)(original_y / calData.DEMCellSize);

			try
			{
				label_Data.Text = "原始值：" + demData.altitudeData[demData.altitudeData.GetLength(0) - y / amplification, x / amplification].ToString("#.00") + "\n计算值：" + calData.altitudeData[calData.altitudeData.GetLength(0) - y, x].ToString("#.00");
			}
			catch { }
        }
	}
}
