using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Xml.Serialization;
using MyGeometry;


namespace SmartLayout
{
    public partial class FormMain : Form
    {
        // constructor
        public FormMain()
        {
            InitializeComponent();
        }
        // NEW_ADD
        public MeshView GetMeshView()
        {
            return meshView;
        }
        public void UpdataSegProcess(int step)
        {
            this.SegProcess.Increment(step);
        }
        public void EndSegProcess()
        {
            this.SegProcess.Value = this.SegProcess.Maximum;
            this.SegProcess.Hide();
        }
        public void BeginProcess()
        {
            this.SegProcess.Value = this.SegProcess.Minimum;
            this.SegProcess.Show();
        }

		public void SetPropertyGridObject(MeshRecord rec)
		{
			this.propertyGrid1.SelectedObject = rec;
		}

		public void AddTabObject(MeshRecord rec)
		{
			string filename = rec.Filename;
			TabPage p = new TabPage(filename);
			p.Tag = rec;
			rec.TabIndex = (byte)this.tabControlMain.TabPages.Count;
			this.tabControlMain.TabPages.Add(p);
			this.tabControlMain.SelectedTab = p;
		}

		public void SetTabObject(MeshRecord rec)
		{
			if (rec == null) return;
			int index = rec.TabIndex;
			if (index < 0) return;
			TabPage page = this.tabControlMain.TabPages[index];
			this.tabControlMain.SelectedTab = page;
		}
		

        private void SaveCrtCam()
        {
            if (this.meshView.MeshRecord == null)
                return;
            SaveFileDialog d = new SaveFileDialog();
            d.FileName = "";
            d.Filter = "Exist Segmentation File (*.cam)|*.cam|All files (*.*)|*.*";
            d.CheckFileExists = false;
            DialogResult ret = d.ShowDialog(this);

            if (ret == DialogResult.OK)
            {
                string fullPath = d.FileName;
                string extension = fullPath.Substring(fullPath.Length - 4, 4);
                string filename = Path.GetFileName(fullPath);

                
                StreamWriter sw = new StreamWriter(fullPath);
                if (extension.Equals(".cam"))
                    this.meshView.SaveTransformationMatrix(sw);
                sw.Close();
                this.meshView.Refresh();
            }
        }
        private void LoadCrtCam()
        {
            if (this.meshView.MeshRecord == null)
                return;
            OpenFileDialog d = new OpenFileDialog();
            d.FileName = "";
            d.Filter = "Exist Segmentation File (*.cam)|*.cam|All files (*.*)|*.*";
            d.CheckFileExists = true;
            DialogResult ret = d.ShowDialog(this);

            if (ret == DialogResult.OK)
            {
                string fullPath = d.FileName;
                string extension = fullPath.Substring(fullPath.Length - 4, 4);
                string filename = Path.GetFileName(fullPath);

                // load mesh model
                StreamReader sr = new StreamReader(fullPath);
                if (extension.Equals(".cam"))
                    this.meshView.LoadTransformationMatrix(sr);
                sr.Close();
                this.meshView.Refresh();
            }
        }

        // event handlers
		private void FormMain_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
		{
		}
		private void FormMain_KeyUp(object sender, KeyEventArgs e)
		{
			switch (e.KeyData)
			{
				case Keys.F1:
					LoadMesh();
					break;
				case Keys.F2:
					this.meshView.CurrentMode = MeshView.EnumOperationMode.Viewing;
					break;
				case Keys.F3:
					this.meshView.CurrentMode = MeshView.EnumOperationMode.Picking;
					break;
				case Keys.F4:
					this.meshView.ShowVertices = !this.meshView.ShowVertices;
					break;
				case Keys.F5:
					this.meshView.ShowHiddenLine = !this.meshView.ShowHiddenLine;
					break;
				case Keys.F6:
					this.meshView.SmoothShading = !this.meshView.SmoothShading;
					break;
				case Keys.F7:
					this.meshView.Antialiasing = !this.meshView.Antialiasing;
					break;
				case Keys.F8:
					
					break;
				case Keys.F9:
					
					break;
                case Keys.F10:
                    
                    break;
                
			}
		}
        private void FormMain_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.KeyData)
            {
				case Keys.S:
					MeshView activeView = this.meshView;
					if (activeView == null) break;
					//if (activeView.CurrentMode == MeshView.EnumOperationMode.Sketching)
					//{
					//    activeView.CurrentMode = MeshView.EnumOperationMode.Viewing;
					//    toolStripButtonPickTool.Checked = false;
					//}
					//else
					//{
					//    activeView.CurrentMode = MeshView.EnumOperationMode.Sketching;
					//    toolStripButtonPickTool.Checked = true;
					//}
                    break;
                case Keys.C:
                    SaveCrtCam(); 
                    break;
                case Keys.L:
                    LoadCrtCam();
                    break;
                case Keys.D:
                    
                    break;
            }
        }
		private void toolStripButtonOpenFile_Click(object sender, EventArgs e)
        {
            LoadMesh();
        }

        private void toolStripButtonPickTool_Click(object sender, EventArgs e)
        {
			meshView.CurrentMode = MeshView.EnumOperationMode.Sketching;
		}
		private void toolStripButtonShowHideVertices_Click(object sender, EventArgs e)
		{
			this.meshView.ShowVertices = !this.meshView.ShowVertices;
		}
		private void toolStripButtonShowHideEdges_Click(object sender, EventArgs e)
		{
			this.meshView.ShowHiddenLine = !this.meshView.ShowHiddenLine;
		}
		private void toolStripButtonSmoothShading_Click(object sender, EventArgs e)
		{
			this.meshView.SmoothShading = !this.meshView.SmoothShading;
		}
		private void tabControlMain_SelectedIndexChanged(object sender, EventArgs e)
		{
			if (this.tabControlMain.SelectedTab != null)
			{
				MeshRecord rec = (MeshRecord)this.tabControlMain.SelectedTab.Tag;

				if (meshView.meshes.Contains(rec))
					this.meshView.MeshRecord = rec;

				this.propertyGrid1.SelectedObject = rec;
				foreach (MeshView.IMeshDisplay obj in this.meshView.MeshRecord.AlgorithmObjects)
				{
					obj.SetData();
				}
			}
			else
			{
				this.meshView.MeshRecord = null;
				this.propertyGrid1.SelectedObject = null;
			}
		}
		private void buttonCloseModel_Click(object sender, EventArgs e)
		{
			MeshRecord rec = (MeshRecord)this.tabControlMain.SelectedTab.Tag;
			if (rec != null)
			{
				this.tabControlMain.TabPages.Remove(this.tabControlMain.SelectedTab);

				// update the tab index for all meshrecords
				int index = 0;
				foreach (TabPage page in this.tabControlMain.TabPages)
				{
					MeshRecord r = (MeshRecord)page.Tag;
					r.TabIndex = (byte)index++;
				}

				if (this.meshView.meshes.Contains(rec))
				{
					this.meshView.meshes.Remove(rec);
					if (this.meshView.meshes.Count < 1)
						this.meshView.MeshRecord = null;
					this.meshView.Refresh();
				}
				
			}
		}
		private void buttonShowHideRightPanel_Click(object sender, EventArgs e)
        {
            this.splitContainer1.Panel2Collapsed =
                !this.splitContainer1.Panel2Collapsed;
        }
		private void buttonShowHideDownPanel_Click(object sender, EventArgs e)
		{
			this.splitContainer2.Panel2Collapsed =
				!this.splitContainer2.Panel2Collapsed;
		}
		private void buttonClearOutputText_Click(object sender, EventArgs e)
		{
			this.textBoxOutputText.Text = "";
		}
		private void buttonCopyOutputText_Click(object sender, EventArgs e)
		{
			if (this.textBoxOutputText.Text != "")
				Clipboard.SetText(this.textBoxOutputText.Text);
		}
		private void toolStripButtonAntialiasing_Click(object sender, EventArgs e)
		{
			this.meshView.Antialiasing =
				!this.meshView.Antialiasing;
		}
		private void toolStripButtonIsolineSegmentation_Click(object sender, EventArgs e)
		{
			MeshView view = this.meshView;
			if (view == null) return;
			view.CurrentMode = view.CurrentMode == MeshView.EnumOperationMode.Selection ?
				MeshView.EnumOperationMode.Viewing : MeshView.EnumOperationMode.Selection;

			//toolStripButtonIsolineSegmentation.Checked = 
			//    view.CurrentMode == MeshView.EnumOperationMode.Selection;
		}
		private void toolStripButtonRandomWalkSegmentation_Click(object sender, EventArgs e)
		{
			
			MeshView view = this.meshView;
			if (view == null) return;
			view.CurrentMode = view.CurrentMode == MeshView.EnumOperationMode.Picking ?
				MeshView.EnumOperationMode.Viewing : MeshView.EnumOperationMode.Picking;

			//toolStripButtonRandomWalkSegmentation.Checked = 
			//    view.CurrentMode == MeshView.EnumOperationMode.Picking;
		}

        // private functions
		private string objectName = null;
        private Mesh LoadMesh()
        {
            OpenFileDialog d = new OpenFileDialog();
            d.FileName = "";
            //d.Filter = "Wavefront Object File (*.obj)|*.obj|All files (*.*)|*.*";
            d.Filter = "Wavefront Object File (*.obj;*.off)|*.obj;*.off|All files (*.*)|*.*";
            d.CheckFileExists = true;
            DialogResult ret = d.ShowDialog(this);

            if (ret == DialogResult.OK)
            {
                string fullPath = d.FileName;
                char[] delimiters = { '.'};
                string[] tokens = fullPath.Split(delimiters);
                //string extension = fullPath.Substring(fullPath.Length - 3, 3);
                string extension;
                if (tokens.Length > 0)
                    extension = tokens[tokens.Length - 1];
                else
                    extension = "obj";

                string filename = Path.GetFileName(fullPath);

				this.objectName = fullPath.Substring(0, fullPath.Length - 4);

                // load mesh model
                StreamReader sr = new StreamReader(fullPath);
                Mesh m = new Mesh(sr, extension);
                sr.Close();

                // add new tabpage and mesh record
				MeshRecord rec = new MeshRecord(m);
				rec.Filename = filename;


				this.meshView.meshes.Add(rec);
				this.meshView.MeshRecord = rec;

				this.propertyGrid1.SelectedObject = rec;

				this.AddTabObject(rec);


				return m;
            }

            return null;
		}
		private void CreateIsolineSegmenter()

		{
			
		}
		private void CreateRandomWalkSegmenter()
		{
			
		}


		// public functions
		public void OutputText(string s, bool newLine)
		{
			if (newLine)
				this.textBoxOutputText.AppendText(s + System.Environment.NewLine);
			else
				this.textBoxOutputText.AppendText(s);
		}
		public void DisplayData(double[] data1, double[] data2, int index)
		{
			
			
		}

        private void PrevFP_Click(object sender, EventArgs e)
        {
			

        }

        private void NextFP_Click(object sender, EventArgs e)
        {
			
        }

        private void RefreshSegColor_Click(object sender, EventArgs e)
        {
            

        }

        private void toolStripButtonLoadCamera_Click(object sender, EventArgs e)
        {
            LoadCrtCam();
        }

        private void toolStripButtonSaveCamera_Click(object sender, EventArgs e)
        {
            SaveCrtCam();
        }

        private void toolStripButtonSaveSeg_Click(object sender, EventArgs e)
        {
            
        }

        private void toolStripButtonLoadSeg_Click(object sender, EventArgs e)
        {
        }

		private void runSegmentation_Click(object sender, EventArgs e)
		{
			
		}

		

		private void saveCurrCandidateGradient_Click(object sender, EventArgs e)
		{
			
		}

		private void saveSegmentation_Click(object sender, EventArgs e)
		{
			
		}

		private void loadSegmentation_Click(object sender, EventArgs e)
		{
			
		}


		private void buttonMatch_Click(object sender, EventArgs e)
		{
			
		}

		private void toolStripButtonXY_Click(object sender, EventArgs e)
		{
			
		}

		private void toolStripButtonYZ_Click(object sender, EventArgs e)
		{
			
		}

		private void toolStripButtonXZ_Click(object sender, EventArgs e)
		{
			
		}


		private void runUpdateIsosegmentor_Click(object sender, EventArgs e)
		{
			
		}

		private void UpdateDescriptors_Click(object sender, EventArgs e)
		{

		}


		/////////////////////////Han//////////////////////////////////

		private void moveWall_Click(object sender, EventArgs e)
		{
			meshView.toswitch = new int[2, 2] { { -1, -1 }, { -1, -1 } };
			if (meshView.CurrentDisplay == MeshView.DisplayMode.TwoD)
				meshView.CurrentMode = MeshView.EnumOperationMode.MoveWall;
			else
				meshView.CurrentMode = MeshView.EnumOperationMode.Selection;
			moveWall.Checked = true;
		}

		private void color_Click(object sender, EventArgs e)
		{
			if (meshView.editWall != -1)
			{
				ColorDialog colorDialog = new ColorDialog();
				colorDialog.AllowFullOpen = true;
				colorDialog.FullOpen = true;
				colorDialog.ShowHelp = false;
				colorDialog.Color = Color.Black;
				colorDialog.ShowDialog();
				float[] color = new float[4];
				color[0] = (float)colorDialog.Color.R / 255;
				color[1] = (float)colorDialog.Color.G / 255;
				color[2] = (float)colorDialog.Color.B / 255;
				color[3] = (float)colorDialog.Color.A / 255;
				//meshView.UpdateColor(color);
				meshView.Refresh();
			}
			meshView.editWall = -1;
			meshView.currWall = -1;
			meshView.currPlane = -1;
		}

		private void TwoD_Click(object sender, EventArgs e)
		{
			meshView.CurrentDisplay = MeshView.DisplayMode.TwoD;
			meshView.currTransformation = Matrix4d.IdentityMatrix();
		}

		private void ThreeD_Click(object sender, EventArgs e)
		{
			meshView.CurrentDisplay = MeshView.DisplayMode.ThreeD;
		}

		private void texture_Click(object sender, EventArgs e)
		{
			this.meshView.ShowTexture = !this.meshView.ShowTexture;
		}

		private void meshView_Load(object sender, EventArgs e)
		{

		}

		public void SetTextbox(double[] values)
		{
			//slab1.Text = values[0].ToString();
			//slab1.Show();
		}

		public void SetSlabText(int[] value, int tag)
		{
			//use1.Text = value[0].ToString();
			//use1.Show();
			//use2.Text = value[1].ToString();
			//use2.Show();
			//use3.Text = value[2].ToString();
			//use3.Show();
			//int num = 0;
			//for (int i = 0; i < value.Length; i++)
			//    num += value[i];
			//num += meshView.ncuts + meshView.wcuts;
			//if (meshView.trad)
			//{
			//    tradNum.Text = num.ToString();
			//    tradNum.Show();
			//}
			//else
			//{
			//    totalnum.Text = num.ToString();
			//    totalnum.Show();
			//}
		}

		private void view_Click(object sender, EventArgs e)
		{
			meshView.CurrentMode = MeshView.EnumOperationMode.Viewing;
			view.Checked = true;
			moveWall.Checked = false;
		}

		private void slabs_Click(object sender, EventArgs e)
		{
			meshView.CurrentDisplay = MeshView.DisplayMode.ThreeD;

			meshView.trad = false;
			meshView.cast3D = true;
		
			//meshView.ConnectionRepeatCheck();
			meshView.DeleteOpenWalls();
			double trans = meshView.PrecastConcrete(-1);
			trans = Math.Round(trans, 4);
			trans *= 1000;
			//wallmove.Text = trans.ToString();
			//wallmove.Show();

			//int cuts = meshView.ncuts;
			//ncut.Text = cuts.ToString();
			//ncut.Show();
			//cuts = meshView.wcuts;
			//wcut.Text = cuts.ToString();
			//wcut.Show();

			//String str;
			//double ht = meshView.slabHeight * 1000, value = meshView.blocks[0] * 1000;
			//str = ht.ToString();
			//str += " * ";
			//str += value.ToString();
			//slab1.Text = str + ":";
			//slab1.Show();
			//str = ht.ToString() + " * ";
			//value = meshView.blocks[1] * 1000;
			//str += value.ToString();
			//slab2.Text = str + ":";
			//slab2.Show();
			//str = ht.ToString() + " * ";
			//value = meshView.blocks[2] * 1000;
			//str += value.ToString();
			//slab3.Text = str + ":";
			//slab3.Show();

			meshView.Refresh();
		}

		public void SetText(double a, double b)
		{
			//double ar = Math.Round(a, 2);
			//area.Text = ar.ToString();
			//area.Show();
			//cost.Text = Math.Round(b, 2).ToString();
			//cost.Show();
			//meshView.Refresh();
		}

		private void connection_Click(object sender, EventArgs e)
		{
			meshView.AddConnection(0, true);
			meshView.Refresh();
		}

		private void layoutToolStripMenuItem_Click(object sender, EventArgs e)
		{
			meshView.dispRoom = false;
			meshView.numFloor = 1;
			meshView.Input(1, 1);
			meshView.CurrentDisplay = MeshView.DisplayMode.TwoD;
		}

		private void layout2ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			meshView.dispRoom = false;
			meshView.numFloor = 2;
			meshView.Input(2, 2);
			meshView.CurrentDisplay = MeshView.DisplayMode.TwoD;
		}

		private void layout3ToolStripMenuItem_Click(object sender, EventArgs e)
		{
			meshView.dispRoom = false;
			meshView.numFloor = 1;
			meshView.Input(3, 1);
			meshView.CurrentDisplay = MeshView.DisplayMode.TwoD;
		}
		private void consroom_Click(object sender, EventArgs e)
		{
			
			meshView.dispRoom = true;
			if (meshView.LayoutInd == 5)
				meshView.ApartmentLayout();
			else
				meshView.RoomLayout();
			meshView.ConnectGraphAfter();
			meshView.Refresh();

			meshView.BuildWalls();
			meshView.Refresh();
		}

		private void enter_Click(object sender, EventArgs e)
		{
			//meshView.slabHeight = double.Parse(height.Text) / 1000;
			//// blocks[0] = wallthickness/2
			//meshView.blocks[0] = double.Parse(width1.Text) / 1000;
			//meshView.blocks[1] = double.Parse(width2.Text) / 1000;
			//meshView.blocks[2] = double.Parse(width3.Text) / 1000;
			//meshView.slabdefined = true;
		}

		private void switchrooms_Click(object sender, EventArgs e)
		{
			moveWall.Checked = false;
			view.Checked = false;
			meshView.toswitch = new int[2, 2] { { -1, -1 }, { -1, -1 } };
			meshView.CurrentMode = MeshView.EnumOperationMode.Switch;
		}

		private void traditionCast_Click(object sender, EventArgs e)
		{
			meshView.trad = true;
			meshView.DeleteOpenWalls();
			double trans = meshView.PrecastConcrete(-1);

			//int cuts = meshView.ncuts;
			//tcuts.Text = cuts.ToString();
			//tcuts.Show();
			//cuts = meshView.wcuts;
			//wcut.Text = cuts.ToString();
			//wcut.Show();

			//String str;
			//double ht = meshView.slabHeight * 1000, value = meshView.blocks[0] * 1000;
			//str = ht.ToString();
			//str += " * ";
			//str += value.ToString();
			//slab1.Text = str + ":";
			//slab1.Show();
			//str = ht.ToString() + " * ";
			//value = meshView.blocks[1] * 1000;
			//str += value.ToString();
			//slab2.Text = str + ":";
			//slab2.Show();
			//str = ht.ToString() + " * ";
			//value = meshView.blocks[2] * 1000;
			//str += value.ToString();
			//slab3.Text = str + ":";
			//slab3.Show();
			//meshView.Refresh();
		}

		private void input_graph_Click(object sender, EventArgs e)
		{
			meshView.drawLabel = false;
			meshView.dispRoom = false;
			meshView.numFloor = 1;
			meshView.Input(3, 1);
			meshView.CurrentDisplay = MeshView.DisplayMode.TwoD;
		}


    }
}
