#pragma once
#include "Kalibrace.h"
#include "Form2.h"
#include "Form4.h"
#define maxiter 1000
namespace Bakalarska_prace {
	
	using namespace System;
	using namespace System::ComponentModel;
	using namespace System::Collections;
	using namespace System::Windows::Forms;
	using namespace System::Data;
	using namespace System::Drawing;
	using namespace System::IO;
	using namespace System::Xml;
	
	
	/// <summary>
	/// Summary for Form1
	/// </summary>
	public ref class Form1 : public System::Windows::Forms::Form
	{
	public:
		Form1(void)
		{
			InitializeComponent();
			Kali= new Kalibrace;
			Kali->SetF(0.5);
			Kali->SetCR(0.99);
			xx = 0;
			yy = 0;
			MyItem = new Teleso();
		}

	protected:
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		~Form1()
		{
			if (components)
			{
				delete components;
			}
			delete(Kali);
			delete(MyItem);
		}
	private: System::Windows::Forms::PictureBox^  pictureBox1;
	protected: 
	private: System::Windows::Forms::Button^  Load_button;
	private: System::Windows::Forms::TextBox^  textBox1;
	private: System::Windows::Forms::ListView^  listView1;
	private: System::Windows::Forms::ColumnHeader^  cis;
	private: System::Windows::Forms::ColumnHeader^  X;

	private: System::Windows::Forms::ColumnHeader^  Y;

	private: System::Windows::Forms::OpenFileDialog^  openFileDialog1;
	private: Image^ MyImage;
	private: System::Int32 ImWidth,ImSize;
	private: double k,xx,yy;
	private: Teleso* MyItem;






	private:
		/// <summary>
		Kalibrace* Kali;
	private: System::Windows::Forms::Button^  button1;
	private: System::Windows::Forms::Label^  label1;
	private: System::Windows::Forms::ProgressBar^  progressBar1;
	private: System::Windows::Forms::Label^  label2;
	private: System::Windows::Forms::Label^  label3;
	private: System::Windows::Forms::Label^  label4;
	private: System::Windows::Forms::Label^  label5;
	private: System::Windows::Forms::Label^  label6;
	private: System::Windows::Forms::Label^  label7;
	private: System::Windows::Forms::Label^  label8;
	private: System::Windows::Forms::Label^  label9;






	private: System::Windows::Forms::Button^  button2;
	private: System::Windows::Forms::Button^  button3;
			 /// </summary>
		System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			System::ComponentModel::ComponentResourceManager^  resources = (gcnew System::ComponentModel::ComponentResourceManager(Form1::typeid));
			this->pictureBox1 = (gcnew System::Windows::Forms::PictureBox());
			this->Load_button = (gcnew System::Windows::Forms::Button());
			this->textBox1 = (gcnew System::Windows::Forms::TextBox());
			this->listView1 = (gcnew System::Windows::Forms::ListView());
			this->cis = (gcnew System::Windows::Forms::ColumnHeader());
			this->X = (gcnew System::Windows::Forms::ColumnHeader());
			this->Y = (gcnew System::Windows::Forms::ColumnHeader());
			this->openFileDialog1 = (gcnew System::Windows::Forms::OpenFileDialog());
			this->button1 = (gcnew System::Windows::Forms::Button());
			this->label1 = (gcnew System::Windows::Forms::Label());
			this->progressBar1 = (gcnew System::Windows::Forms::ProgressBar());
			this->label2 = (gcnew System::Windows::Forms::Label());
			this->label3 = (gcnew System::Windows::Forms::Label());
			this->label4 = (gcnew System::Windows::Forms::Label());
			this->label5 = (gcnew System::Windows::Forms::Label());
			this->label6 = (gcnew System::Windows::Forms::Label());
			this->label7 = (gcnew System::Windows::Forms::Label());
			this->label8 = (gcnew System::Windows::Forms::Label());
			this->label9 = (gcnew System::Windows::Forms::Label());
			this->button2 = (gcnew System::Windows::Forms::Button());
			this->button3 = (gcnew System::Windows::Forms::Button());
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBox1))->BeginInit();
			this->SuspendLayout();
			// 
			// pictureBox1
			// 
			this->pictureBox1->Image = (cli::safe_cast<System::Drawing::Image^  >(resources->GetObject(L"pictureBox1.Image")));
			this->pictureBox1->Location = System::Drawing::Point(12, 12);
			this->pictureBox1->Name = L"pictureBox1";
			this->pictureBox1->Size = System::Drawing::Size(400, 300);
			this->pictureBox1->SizeMode = System::Windows::Forms::PictureBoxSizeMode::Zoom;
			this->pictureBox1->TabIndex = 0;
			this->pictureBox1->TabStop = false;
			this->pictureBox1->MouseDown += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::pictureBox1_MouseDown);
			this->pictureBox1->MouseEnter += gcnew System::EventHandler(this, &Form1::pictureBox1_MouseEnter);
			this->pictureBox1->MouseWheel += gcnew System::Windows::Forms::MouseEventHandler(this, &Form1::pictureBox1_MouseWheel);
			// 
			// Load_button
			// 
			this->Load_button->Location = System::Drawing::Point(645, 289);
			this->Load_button->Name = L"Load_button";
			this->Load_button->Size = System::Drawing::Size(75, 23);
			this->Load_button->TabIndex = 1;
			this->Load_button->Text = L"Load";
			this->Load_button->UseVisualStyleBackColor = true;
			this->Load_button->Click += gcnew System::EventHandler(this, &Form1::Load_button_Click);
			// 
			// textBox1
			// 
			this->textBox1->Enabled = false;
			this->textBox1->Location = System::Drawing::Point(418, 292);
			this->textBox1->Name = L"textBox1";
			this->textBox1->Size = System::Drawing::Size(221, 20);
			this->textBox1->TabIndex = 2;
			this->textBox1->Text = L"Obraz.bmp";
			// 
			// listView1
			// 
			this->listView1->Columns->AddRange(gcnew cli::array< System::Windows::Forms::ColumnHeader^  >(3) {this->cis, this->X, this->Y});
			this->listView1->FullRowSelect = true;
			this->listView1->GridLines = true;
			this->listView1->HeaderStyle = System::Windows::Forms::ColumnHeaderStyle::Nonclickable;
			this->listView1->Location = System::Drawing::Point(418, 12);
			this->listView1->Name = L"listView1";
			this->listView1->Size = System::Drawing::Size(211, 191);
			this->listView1->TabIndex = 3;
			this->listView1->UseCompatibleStateImageBehavior = false;
			this->listView1->View = System::Windows::Forms::View::Details;
			this->listView1->ItemSelectionChanged += gcnew System::Windows::Forms::ListViewItemSelectionChangedEventHandler(this, &Form1::listView1_ItemSelectionChanged);
			this->listView1->KeyDown += gcnew System::Windows::Forms::KeyEventHandler(this, &Form1::listView1_KeyDown);
			// 
			// cis
			// 
			this->cis->Text = L"Číslo";
			this->cis->Width = 36;
			// 
			// X
			// 
			this->X->Text = L"X";
			this->X->Width = 79;
			// 
			// Y
			// 
			this->Y->Text = L"Y";
			this->Y->Width = 91;
			// 
			// openFileDialog1
			// 
			this->openFileDialog1->FileName = L"Obraz";
			// 
			// button1
			// 
			this->button1->Location = System::Drawing::Point(635, 70);
			this->button1->Name = L"button1";
			this->button1->Size = System::Drawing::Size(75, 23);
			this->button1->TabIndex = 5;
			this->button1->Text = L"Start";
			this->button1->UseVisualStyleBackColor = true;
			this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
			// 
			// label1
			// 
			this->label1->AutoSize = true;
			this->label1->Location = System::Drawing::Point(418, 261);
			this->label1->Name = L"label1";
			this->label1->Size = System::Drawing::Size(0, 16);
			this->label1->TabIndex = 6;
			this->label1->UseCompatibleTextRendering = true;
			// 
			// progressBar1
			// 
			this->progressBar1->Location = System::Drawing::Point(418, 209);
			this->progressBar1->Name = L"progressBar1";
			this->progressBar1->Size = System::Drawing::Size(211, 23);
			this->progressBar1->TabIndex = 7;
			// 
			// label2
			// 
			this->label2->AutoSize = true;
			this->label2->Location = System::Drawing::Point(419, 235);
			this->label2->Name = L"label2";
			this->label2->Size = System::Drawing::Size(0, 13);
			this->label2->TabIndex = 8;
			// 
			// label3
			// 
			this->label3->AutoSize = true;
			this->label3->Location = System::Drawing::Point(419, 248);
			this->label3->Name = L"label3";
			this->label3->Size = System::Drawing::Size(0, 13);
			this->label3->TabIndex = 9;
			// 
			// label4
			// 
			this->label4->AutoSize = true;
			this->label4->Location = System::Drawing::Point(527, 235);
			this->label4->Name = L"label4";
			this->label4->Size = System::Drawing::Size(0, 13);
			this->label4->TabIndex = 10;
			// 
			// label5
			// 
			this->label5->AutoSize = true;
			this->label5->Location = System::Drawing::Point(527, 248);
			this->label5->Name = L"label5";
			this->label5->Size = System::Drawing::Size(0, 13);
			this->label5->TabIndex = 11;
			// 
			// label6
			// 
			this->label6->AutoSize = true;
			this->label6->Location = System::Drawing::Point(527, 261);
			this->label6->Name = L"label6";
			this->label6->Size = System::Drawing::Size(0, 13);
			this->label6->TabIndex = 12;
			// 
			// label7
			// 
			this->label7->AutoSize = true;
			this->label7->Location = System::Drawing::Point(620, 235);
			this->label7->Name = L"label7";
			this->label7->Size = System::Drawing::Size(0, 13);
			this->label7->TabIndex = 13;
			// 
			// label8
			// 
			this->label8->AutoSize = true;
			this->label8->Location = System::Drawing::Point(620, 248);
			this->label8->Name = L"label8";
			this->label8->Size = System::Drawing::Size(0, 13);
			this->label8->TabIndex = 14;
			// 
			// label9
			// 
			this->label9->AutoSize = true;
			this->label9->Location = System::Drawing::Point(620, 261);
			this->label9->Name = L"label9";
			this->label9->Size = System::Drawing::Size(0, 13);
			this->label9->TabIndex = 15;
			// 
			// button2
			// 
			this->button2->Location = System::Drawing::Point(635, 12);
			this->button2->Name = L"button2";
			this->button2->Size = System::Drawing::Size(75, 23);
			this->button2->TabIndex = 22;
			this->button2->Text = L"Těleso";
			this->button2->UseVisualStyleBackColor = true;
			this->button2->Click += gcnew System::EventHandler(this, &Form1::button2_Click);
			// 
			// button3
			// 
			this->button3->Location = System::Drawing::Point(635, 41);
			this->button3->Name = L"button3";
			this->button3->Size = System::Drawing::Size(75, 23);
			this->button3->TabIndex = 23;
			this->button3->Text = L"Nastavení";
			this->button3->UseVisualStyleBackColor = true;
			this->button3->Click += gcnew System::EventHandler(this, &Form1::button3_Click);
			// 
			// Form1
			// 
			this->AutoScaleDimensions = System::Drawing::SizeF(6, 13);
			this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
			this->ClientSize = System::Drawing::Size(725, 324);
			this->Controls->Add(this->button3);
			this->Controls->Add(this->button2);
			this->Controls->Add(this->label9);
			this->Controls->Add(this->label8);
			this->Controls->Add(this->label7);
			this->Controls->Add(this->label6);
			this->Controls->Add(this->label5);
			this->Controls->Add(this->label4);
			this->Controls->Add(this->label3);
			this->Controls->Add(this->label2);
			this->Controls->Add(this->progressBar1);
			this->Controls->Add(this->label1);
			this->Controls->Add(this->button1);
			this->Controls->Add(this->listView1);
			this->Controls->Add(this->textBox1);
			this->Controls->Add(this->Load_button);
			this->Controls->Add(this->pictureBox1);
			this->ForeColor = System::Drawing::Color::Black;
			this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::FixedSingle;
			this->Name = L"Form1";
			this->Text = L"Bakalářská práce: Kalibrace kamery pomocí evolučních algorytmů";
			(cli::safe_cast<System::ComponentModel::ISupportInitialize^  >(this->pictureBox1))->EndInit();
			this->ResumeLayout(false);
			this->PerformLayout();

		}
#pragma endregion
	
private: System::Void Load_button_Click(System::Object^  sender, System::EventArgs^  e) {
			 openFileDialog1->ShowDialog();
			 if (openFileDialog1->CheckFileExists == true)
			{	 textBox1->Text = openFileDialog1->FileName;
			 try {
			 IO::FileStream ^imgFile = gcnew IO::FileStream(textBox1->Text, IO::FileMode::Open);
			 MyImage = Image::FromStream(imgFile);
			 imgFile->Close();
			 if (300/MyImage->Height>=400/MyImage->Width)
				 k=MyImage->Width/400.0;
			 else
				 k=MyImage->Height/300.0;
			 Kali->SetCenterOfImage((MyImage->Width+1)/2.0,(MyImage->Height+1)/2.0);
			 ImWidth = 400.0*k;
			 ImSize = 400.0*k;
			 xx = 0;
			 yy = 0;
			 pictureBoxInit();
			 }
			 catch(...){MessageBox::Show("Došlo k chybě při načítání souboru");}
			 
			 pictureBox1->Focus();
			} 

		 }
private: System::Void textBox1_MouseClick(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			 openFileDialog1->ShowDialog();
			 if (openFileDialog1->CheckFileExists == true)
				 textBox1->Text = openFileDialog1->FileName;
		 }
private: System::Void pictureBox1_MouseDown(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			pictureBox1->Focus();
			if (MyImage == nullptr||MyItem->GetCount()==0) return;
			
			System::Windows::Forms::ListView::SelectedListViewItemCollection^ a  = gcnew ListView::SelectedListViewItemCollection(listView1);
			if (a->Count!= 1) {MessageBox::Show("Označte některý z bodů"); return;}
			ListViewItem^ b = a->default[0];
			Kali->SetDisplayedPoint(k*(Control::MousePosition.X-Form::Location.X-pictureBox1->Location.X-2)+xx,0.75*ImSize-k*(Control::MousePosition.Y-Form::Location.Y-pictureBox1->Location.Y-24)-yy,Convert::ToInt16(b->Text)-1);
			this->listViewInit();
			this->pictureBoxInit();
		 }
private: System::Void listViewInit() {
			 listView1->Items->Clear();
			 for(int i=0;i<MyItem->GetCount();i++)
			 {
				ListViewItem^ item = listView1->Items->Add(gcnew System::String((i+1).ToString()));
				if (Kali->GetDisplayedPointX(i)>0)
				{
				item->SubItems->Add(Kali->GetDisplayedPointX(i).ToString());
				item->SubItems->Add(Kali->GetDisplayedPointY(i).ToString());
				}
			 }
		 }
private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
			 /*int Test = 0;
			 for(int i=0;i<8;i++)
				 if (Kali->GetDisplayedPointX(i)>0) Test++;
			 if (Test<5) {MessageBox::Show("Zadejte minimálně 5 bodů"); return;}*/
			 /*try
			 {
				 Kali->BlockAsObject(Convert::ToDouble(textBox2->Text),Convert::ToDouble(textBox3->Text),Convert::ToDouble(textBox4->Text));
			 }
			 catch(...)
			 {MessageBox::Show("Zadejte presne rozmery objektu");return;}*/
			 //for(int i=0;i<Kali->GetCountObjectPoints();i++) Kali->SetDisplayedPoint(Kali->GetDisplayedPointX(i),Kali->GetDisplayedPointY(i),i);
			 Kali->Start_Evoluce();
			 double A[9];
			 int i = 0;
			 progressBar1->Maximum = maxiter;
			 while((i<maxiter)&&(Kali->StandartDeviation()>0.01))

			 {
				 progressBar1->Value = i++;	
				 Kali->Reprodukce();
				 File::AppendAllText("Data.txt", (Kali->HodnotaElita().ToString() + "\t" + Kali->StandartDeviation().ToString() + "\r\n"));
				
			 }
			 progressBar1->Value = progressBar1->Maximum;
			 XmlTextWriter ^xmlTxtWriter = gcnew XmlTextWriter("Vysledek.xml", System::Text::Encoding::UTF8);
			 xmlTxtWriter->Formatting = Formatting::Indented;
			 xmlTxtWriter->WriteStartDocument();
			 xmlTxtWriter->WriteStartElement("Jedinec");
			 Kali->Elita(A);
			 xmlTxtWriter->WriteStartElement("Odchylka");
			 label1->Text = "Fitness= " +  A[8].ToString("0.00");
			 xmlTxtWriter->WriteString(Convert::ToString(A[8]));
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteStartElement("focus in px");
			 label2->Text = "fx= "+A[0].ToString("0.00");
			 xmlTxtWriter->WriteString(Convert::ToString(A[0]));
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteStartElement("focus in py");
			 label3->Text = "fy= "+ A[1].ToString("0.00");
			 xmlTxtWriter->WriteString(Convert::ToString(A[1]));
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteStartElement("X rotation");
			 label4->Text = "Alfa= "+ A[2].ToString("0.00");
			 xmlTxtWriter->WriteString(Convert::ToString(A[2]));
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteStartElement("Y rotation");
			 label5->Text = "Beta= "+A[3].ToString("0.00");
			 xmlTxtWriter->WriteString(Convert::ToString(A[3]));
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteStartElement("Z rotation");
			 label6->Text = "Gama= "+A[4].ToString("0.00");
			 xmlTxtWriter->WriteString(Convert::ToString(A[4]));
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteStartElement("X translation");
			 label7->Text = "X= "+A[5].ToString("0.00");
			 xmlTxtWriter->WriteString(Convert::ToString(A[5]));
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteStartElement("Y translation");
			 label8->Text = "Y= "+A[6].ToString("0.00");
			 xmlTxtWriter->WriteString(Convert::ToString(A[6]));
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteStartElement("Z translation");
			 label9->Text = "Z= "+A[7].ToString("0.00");
			 xmlTxtWriter->WriteString(Convert::ToString(A[7]));
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteEndElement();
			 xmlTxtWriter->WriteEndDocument();
			 xmlTxtWriter->Flush();
			 xmlTxtWriter->Close();
			
		 }
private: System::Void listView1_ItemSelectionChanged(System::Object^  sender, System::Windows::Forms::ListViewItemSelectionChangedEventArgs^  e) {
			 listView1->Focus();
		 }
private: System::Void listView1_KeyDown(System::Object^  sender, System::Windows::Forms::KeyEventArgs^  e) {
			 if (e->KeyCode == Keys::Delete)
			 {
				 System::Windows::Forms::ListView::SelectedListViewItemCollection^ a  = gcnew ListView::SelectedListViewItemCollection(listView1);
				 if (a->Count!= 1) {MessageBox::Show("Označte některý z bodů"); return;}
				 ListViewItem^ b = a->default[0];
				 Kali->SetDisplayedPoint(0,0,Convert::ToInt16(b->Text)-1);
				 this->listViewInit();
				 this->pictureBoxInit();
			 }
		 }
private: System::Void pictureBoxInit(){
			 
			 Bitmap^ Obr = gcnew Bitmap(400,300,System::Drawing::Imaging::PixelFormat::Format24bppRgb);
			 Obr->SetResolution(MyImage->HorizontalResolution,MyImage->VerticalResolution);
			 Graphics^ Gra = Graphics::FromImage(Obr);
			 Gra->InterpolationMode= System::Drawing::Drawing2D::InterpolationMode::HighQualityBicubic;
			 Rectangle Novy = Rectangle(0,0,400,300);
			 Rectangle Stary = Rectangle(xx,yy,ImWidth,ImWidth*0.75);
			 Gra->DrawImage(MyImage,Novy,Stary,System::Drawing::GraphicsUnit::Pixel);
			
			 for(int i=0;i<Kali->GetCountObjectPoints();i++)
				 if ((Kali->GetDisplayedPointX(i)!=0)&&((Kali->GetDisplayedPointX(i)-xx)/k-2>=0)&&((Kali->GetDisplayedPointX(i)-xx)/k+2<=400)&&((MyImage->Height-Kali->GetDisplayedPointY(i)-yy)/k-2>=0)&&((MyImage->Height-Kali->GetDisplayedPointY(i)-yy)/k+2<=300))
				 {
					 for(int j= -2;j<3;j++)
					 Obr->SetPixel((Kali->GetDisplayedPointX(i)-xx)/k+j,(MyImage->Height-Kali->GetDisplayedPointY(i)-yy)/k,Color::Red);
					 for(int j= -2;j<3;j++)
					 Obr->SetPixel((Kali->GetDisplayedPointX(i)-xx)/k,(MyImage->Height-Kali->GetDisplayedPointY(i)-yy)/k+j,Color::Red);
				 }
			 pictureBox1->Image = Obr;

		 }
private: System::Void pictureBox1_MouseWheel(System::Object^  sender, System::Windows::Forms::MouseEventArgs^  e) {
			 ImWidth -= e->Delta;
			 if (ImWidth>ImSize) ImWidth=ImSize;
			 if (ImWidth<10) {ImWidth=10; return;}
			 k = ImWidth/400.0;
			 xx+= e->Delta*(Control::MousePosition.X-Form::Location.X-pictureBox1->Location.X-3)/400.0;
			 yy+= e->Delta*0.75*(Control::MousePosition.Y-Form::Location.Y-pictureBox1->Location.Y-24)/300.0;
			 if (xx<0) xx = 0;
			 if (yy<0) yy = 0;
			 if (xx+ImWidth>ImSize) xx = ImSize-ImWidth;
			 if (yy+0.75*ImWidth>0.75*ImSize) yy = 0.75*(ImSize-ImWidth);
			 pictureBoxInit();
		 }
private: System::Void pictureBox1_MouseEnter(System::Object^  sender, System::EventArgs^  e) {
			 pictureBox1->Focus();
		 }
private: System::Void button2_Click(System::Object^  sender, System::EventArgs^  e) {
			 Form2^ GenTeles = gcnew Form2(MyItem);
			 GenTeles->ShowDialog();
			 Kali->SetObject(*MyItem);
			 this->listViewInit();
		 }
private: System::Void button3_Click(System::Object^  sender, System::EventArgs^  e) {
			 Form4^ Nastaveni = gcnew Form4(Kali);
			 Nastaveni->ShowDialog();
		 }
};
}

