#pragma once


namespace Displaymap
{


	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::Drawing::Drawing2D;
	//using namespace System::Drawing;Graphics;
	using namespace System::IO;



	/// <summary> 
	/// Summary for Form1
	///
	/// WARNING: If you change the name of this class, you will need to change the 
	///          'Resource File Name' property for the managed resource compiler tool 
	///          associated with all .resx files this class depends on.  Otherwise,
	///          the designers will not be able to interact properly with localized
	///          resources associated with this form.
	/// </summary>
	public __gc class Form1 : public System::Windows::Forms::Form
	{	
	public:
		String* loadedBGM;
				int lastbox;
		int numBGMlines;
		int NumBoxes;
		//int processedBoxes;
		int NumberOfVertices __nogc[1000];
		//double box __nogc[500][100][2];  //polygon#, vertex#, XorY
		static double box __nogc[1000][100][2];
		bool SpectrumInitialized;
		static SolidBrush* Spectrum[] = new SolidBrush*[100];
		static Color SpectrumColour [] = new Color [100];
		static double northextent = -9e15;
		static double southextent = 9e15;
		static double eastextent = -9e15;
		static double westextent = 9e15;
		double tester;
		double XYtoPanelHoriz;
		double XYtoPanelVert;
		double concentrations __nogc [1000];
		bool vectorread;
		int pensize;
		double concrange, minconc, maxconc;

		
		//Point *PolygonVertices[][] = __gc new Point*[500][100];
		//Point *PolygonVertices __gc [][];
		//PolygonVertices = new Point* __gc[500][100];
		//static Point* PolygonVertices __gc[][] = new Point* PolygonVertices __gc[500][100];
		//Point* PolygonVertices[][];
		//Point *PolygonVertices[][] = new Point* __gc[500][100];

		//static Color SpectrumColour = new array<Color>(100);
		//static Color SpectrumColour__gc[]= new Color __gc[100]
		//static array<SolidBrush^,1>^ Spectrum = new array<SolidBrush^,1>(100);


	public: System::Windows::Forms::Panel *  mappanel;
	private: System::Windows::Forms::Panel *  SpectrumPanel;
	private: System::Windows::Forms::Label *  minscale;
	private: System::Windows::Forms::TextBox *  textBox1;
	private: System::Windows::Forms::Button *  button1;
	private: System::Windows::Forms::TextBox *  textBox2;
	private: System::Windows::Forms::Label *  label2;
	private: System::Windows::Forms::Button *  button2;
	private: System::Windows::Forms::Label *  midscale;
	private: System::Windows::Forms::Button *  button3;
	private: System::Windows::Forms::Label *  label3;
	private: System::Windows::Forms::Label *  maxscale;




	public: Form1(void)
		{
			InitializeComponent();
					
		}
  
	protected:
		void Dispose(Boolean disposing)
		{
			if (disposing && components)
			{
				components->Dispose();
			}
			__super::Dispose(disposing);
		}
	private: System::Windows::Forms::MainMenu *  mainMenu1;
	private: System::Windows::Forms::MenuItem *  menuItem1;
	private: System::Windows::Forms::MenuItem *  menuItem2;
	private: System::Windows::Forms::Label *  label1;


	private:
		/// <summary>
		/// Required designer variable.
		/// </summary>
		System::ComponentModel::Container * components;

		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		void InitializeComponent(void)
		{
			this->mainMenu1 = new System::Windows::Forms::MainMenu();
			this->menuItem1 = new System::Windows::Forms::MenuItem();
			this->menuItem2 = new System::Windows::Forms::MenuItem();
			this->label1 = new System::Windows::Forms::Label();
			this->mappanel = new System::Windows::Forms::Panel();
			this->SpectrumPanel = new System::Windows::Forms::Panel();
			this->minscale = new System::Windows::Forms::Label();
			this->maxscale = new System::Windows::Forms::Label();
			this->textBox1 = new System::Windows::Forms::TextBox();
			this->button1 = new System::Windows::Forms::Button();
			this->textBox2 = new System::Windows::Forms::TextBox();
			this->label2 = new System::Windows::Forms::Label();
			this->button2 = new System::Windows::Forms::Button();
			this->midscale = new System::Windows::Forms::Label();
			this->button3 = new System::Windows::Forms::Button();
			this->label3 = new System::Windows::Forms::Label();
			this->SuspendLayout();
			// 
			// mainMenu1
			// 
			System::Windows::Forms::MenuItem* __mcTemp__1[] = new System::Windows::Forms::MenuItem*[1];
			__mcTemp__1[0] = this->menuItem1;
			this->mainMenu1->MenuItems->AddRange(__mcTemp__1);
			// 
			// menuItem1
			// 
			this->menuItem1->Index = 0;
			System::Windows::Forms::MenuItem* __mcTemp__2[] = new System::Windows::Forms::MenuItem*[1];
			__mcTemp__2[0] = this->menuItem2;
			this->menuItem1->MenuItems->AddRange(__mcTemp__2);
			this->menuItem1->Text = S"File";
			// 
			// menuItem2
			// 
			this->menuItem2->Index = 0;
			this->menuItem2->Text = S"Load BGM";
			this->menuItem2->Click += new System::EventHandler(this, menuItem2_Click);
			// 
			// label1
			// 
			this->label1->Location = System::Drawing::Point(8, 576);
			this->label1->Name = S"label1";
			this->label1->Size = System::Drawing::Size(496, 16);
			this->label1->TabIndex = 0;
			this->label1->Text = S"Load BGM";
			// 
			// mappanel
			// 
			this->mappanel->BackColor = System::Drawing::Color::WhiteSmoke;
			this->mappanel->Location = System::Drawing::Point(8, 8);
			this->mappanel->Name = S"mappanel";
			this->mappanel->Size = System::Drawing::Size(500, 500);
			this->mappanel->TabIndex = 1;
			this->mappanel->Paint += new System::Windows::Forms::PaintEventHandler(this, mappanel_Paint);
			// 
			// SpectrumPanel
			// 
			this->SpectrumPanel->BackColor = System::Drawing::Color::WhiteSmoke;
			this->SpectrumPanel->Location = System::Drawing::Point(8, 512);
			this->SpectrumPanel->Name = S"SpectrumPanel";
			this->SpectrumPanel->Size = System::Drawing::Size(500, 15);
			this->SpectrumPanel->TabIndex = 2;
			this->SpectrumPanel->Paint += new System::Windows::Forms::PaintEventHandler(this, SpectrumPanel_Paint);
			// 
			// minscale
			// 
			this->minscale->Location = System::Drawing::Point(8, 534);
			this->minscale->Name = S"minscale";
			this->minscale->TabIndex = 3;
			this->minscale->Text = S".";
			// 
			// maxscale
			// 
			this->maxscale->Location = System::Drawing::Point(424, 534);
			this->maxscale->Name = S"maxscale";
			this->maxscale->Size = System::Drawing::Size(80, 24);
			this->maxscale->TabIndex = 4;
			this->maxscale->Text = S".";
			this->maxscale->TextAlign = System::Drawing::ContentAlignment::TopRight;
			// 
			// textBox1
			// 
			this->textBox1->AcceptsReturn = true;
			this->textBox1->Location = System::Drawing::Point(520, 8);
			this->textBox1->Multiline = true;
			this->textBox1->Name = S"textBox1";
			this->textBox1->Size = System::Drawing::Size(136, 416);
			this->textBox1->TabIndex = 5;
			this->textBox1->Text = S"Paste concentrations";
			this->textBox1->WordWrap = false;
			// 
			// button1
			// 
			this->button1->Location = System::Drawing::Point(520, 464);
			this->button1->Name = S"button1";
			this->button1->Size = System::Drawing::Size(136, 24);
			this->button1->TabIndex = 6;
			this->button1->Text = S"Display";
			this->button1->Click += new System::EventHandler(this, button1_Click);
			// 
			// textBox2
			// 
			this->textBox2->Location = System::Drawing::Point(520, 552);
			this->textBox2->Name = S"textBox2";
			this->textBox2->Size = System::Drawing::Size(40, 20);
			this->textBox2->TabIndex = 7;
			this->textBox2->Text = S"2";
			// 
			// label2
			// 
			this->label2->Location = System::Drawing::Point(568, 556);
			this->label2->Name = S"label2";
			this->label2->Size = System::Drawing::Size(72, 16);
			this->label2->TabIndex = 8;
			this->label2->Text = S"Pen size";
			// 
			// button2
			// 
			this->button2->Location = System::Drawing::Point(520, 496);
			this->button2->Name = S"button2";
			this->button2->Size = System::Drawing::Size(136, 24);
			this->button2->TabIndex = 9;
			this->button2->Text = S"Save BMP";
			this->button2->Click += new System::EventHandler(this, button2_Click);
			// 
			// midscale
			// 
			this->midscale->Location = System::Drawing::Point(215, 534);
			this->midscale->Name = S"midscale";
			this->midscale->TabIndex = 10;
			this->midscale->Text = S".";
			this->midscale->TextAlign = System::Drawing::ContentAlignment::TopCenter;
			// 
			// button3
			// 
			this->button3->Location = System::Drawing::Point(520, 432);
			this->button3->Name = S"button3";
			this->button3->Size = System::Drawing::Size(136, 23);
			this->button3->TabIndex = 11;
			this->button3->Text = S"Clear";
			this->button3->Click += new System::EventHandler(this, button3_Click);
			// 
			// label3
			// 
			this->label3->Location = System::Drawing::Point(520, 528);
			this->label3->Name = S"label3";
			this->label3->Size = System::Drawing::Size(100, 16);
			this->label3->TabIndex = 12;
			this->label3->Text = S"-1 for land";
			// 
			// Form1
			// 
			this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
			this->ClientSize = System::Drawing::Size(672, 601);
			this->Controls->Add(this->label3);
			this->Controls->Add(this->button3);
			this->Controls->Add(this->button2);
			this->Controls->Add(this->label2);
			this->Controls->Add(this->textBox2);
			this->Controls->Add(this->button1);
			this->Controls->Add(this->textBox1);
			this->Controls->Add(this->maxscale);
			this->Controls->Add(this->minscale);
			this->Controls->Add(this->SpectrumPanel);
			this->Controls->Add(this->mappanel);
			this->Controls->Add(this->label1);
			this->Controls->Add(this->midscale);
			this->Menu = this->mainMenu1;
			this->Name = S"Form1";
			this->Text = S"GoC map";
			this->ResumeLayout(false);

		}	
	
	
	
		
void InitSpectrumPanel()
	{
	double Dred,Dgreen,Dblue;
	int red,green,blue;
	Color thiscolor;
	SpectrumInitialized = true;


		for (int i=0;i<100;i++) //makes a spectrum colour gradient of 100 colours and saves into array
		{

			if (i<25) 
			{
				Dred = 255 - ((i/25.0) * 255);
				Dgreen = 255;
				Dblue = 255;
				red = Convert::ToInt32(Dred);
				green = Convert::ToInt32(Dgreen);
				blue = Convert::ToInt32(Dblue);
				Spectrum[i] = new SolidBrush(Color::FromArgb(red,green,blue));
				thiscolor = Color::FromArgb(red,green,blue);
			}
			else if ((i>=25) && (i<50)) 
			{
				Dred = (((i-25.0)/25.0) * 255);
				Dgreen = 255;
				Dblue = 255-(255*((i-25.0)/25.0));
				red = Convert::ToInt32(Dred);
				green = Convert::ToInt32(Dgreen);
				blue = Convert::ToInt32(Dblue);
				Spectrum[i] = new SolidBrush(Color::FromArgb(red,green,blue));
				thiscolor = Color::FromArgb(red,green,blue);
			}
			else if (i>=50)
			{
				Dred = 255;
				Dgreen = 255-255*((i-50.0)/50.0);
				Dblue = 0;
				red = Convert::ToInt32(Dred);
				green = Convert::ToInt32(Dgreen);
				blue = Convert::ToInt32(Dblue);
				Spectrum[i] = new SolidBrush(Color::FromArgb(red,green,blue));
				thiscolor = Color::FromArgb(red,green,blue);
			}

			SpectrumColour[i]=thiscolor;

		}
	
	Graphics* SpectPanel = SpectrumPanel->CreateGraphics();	
	int rectlength = SpectrumPanel->Width / 100;

	for (int i = 0; i<100;i++)
	{
	Rectangle* ColourRect = __nogc new Rectangle(rectlength*i,0,5,15);
	SpectPanel->FillRectangle(Spectrum[i],*ColourRect);
	}
	
	}	
		
		

		
bool IsNumeric(String* str)
	{
		try
		{
			int ch = Convert::ToInt32(str);
			if(ch >= 0 && ch <= 9)
			{
			return true;
			}
			else
			{
			return false;
			}
		}
		catch(Exception *e)
		{
			return false;
		}
	}
//test







	
	private: System::Void menuItem2_Click(System::Object *  sender, System::EventArgs *  e)
			 {

				 OpenFileDialog* loadBGM = new OpenFileDialog;
loadBGM->Filter = "Box geometry files (*.bgm)|*.bgm|All files (*.*)|*.*";
loadBGM->RestoreDirectory = true;
loadBGM->Title = "Select BGM file";
System::Windows::Forms::DialogResult dr;
dr = loadBGM->ShowDialog();

if ( dr == DialogResult::OK )
	loadedBGM = loadBGM->FileName;
	label1->Text = loadedBGM;

	getBGMdata(loadedBGM);
	InitSpectrumPanel();
	DrawMap();
	;
			 }

void ReadVector()
	{
		String* concs[] = textBox1->Lines;
		//int concsLength = concs->Length-1;
		maxconc = -9e15;
		minconc = 9e15;

		for (int i = 0; i<NumBoxes;i++)
		//for (int i = 0; i<concsLength;i++)
		{
			concentrations[i]=Convert::ToDouble(concs[i]);
			if (concentrations[i]!=-1)
			{
			if (concentrations[i]<minconc) {minconc=concentrations[i];}
			if (concentrations[i]>maxconc) {maxconc=concentrations[i];}
			}
		}
		concrange = maxconc-minconc;
		vectorread = true;
		
	}


int PanelCoordVert(double BGMcoordVert)
		{
			double calc = mappanel->Height - (mappanel->Height*(BGMcoordVert-southextent)/(northextent-southextent));
			return Convert::ToInt32(calc);
		}
int PanelCoordHoriz(double BGMcoordHoriz)
		{
			double calc = (mappanel->Width*(BGMcoordHoriz-westextent)/(eastextent-westextent));
			return Convert::ToInt32(calc);
		}

void DrawLines(){
		for (int i = 0; i<NumBoxes;i++)
		{
		for (int j = 1; j<=NumberOfVertices[i];j++)
		{
			Graphics* MapPanelGraphic = mappanel->CreateGraphics();
			Pen* BlackPen = new Pen(Color::Black,pensize);
			
			double startvertexX = box[i][j][1];
			double startvertexY = box[i][j][2];
			int startX = PanelCoordHoriz(startvertexX);
			int startY = PanelCoordVert(startvertexY);

			double endvertexX;
			double endvertexY;
			if (j==NumberOfVertices[i])
			{
				endvertexX = box[i][1][1];
				endvertexY = box[i][1][2];
			}
			else
			{
				endvertexX  = box[i][j+1][1];
				endvertexY = box[i][j+1][2];
			}
			int endX = PanelCoordHoriz(endvertexX);
			int endY = PanelCoordVert(endvertexY);

			if (pensize!=0)
			{
			MapPanelGraphic->DrawLine(BlackPen,startX,startY,endX,endY);
			}
		}
		}
}

void DrawMap(){

	//extent of polygons is recorded in northextent, southextent, etc.
	//scale output
//XYtoPanelHoriz = mappanel->Width / (eastextent - westextent);
//XYtoPanelVert = mappanel->Height * ()/(northextent - southextent);
	pensize = Convert::ToInt32(textBox2->Text);

//DrawLines();


if (vectorread)
{
for (int i=0;i<NumBoxes+1;i++)
{
		Graphics* MapPanelGraphic = mappanel->CreateGraphics();
		Pen* BlackPen = new Pen(Color::Black,pensize);

		if (concentrations[i]!=-1) //case for water cells
		{
			int thiscolour = Convert::ToInt32(100*(concentrations[i]-minconc)/concrange);
			if (thiscolour<0){thiscolour=0;}
			Form1::minscale->Text = Convert::ToString(minconc);
			Form1::maxscale->Text = Convert::ToString(maxconc);
			Form1::midscale->Text = Convert::ToString(minconc+concrange/2);
			if (thiscolour == 100){thiscolour = 99;}
			int NumVertices = NumberOfVertices[i];
			Point PolygonVertices __gc[]  = new Point[NumVertices];
			for (int j = 0; j<NumVertices;j++)
			{
				double boxtestX = box[i][j+1][1];
				double boxtestY = box[i][j+1][2];
				PolygonVertices[j].X = PanelCoordHoriz(boxtestX);
				PolygonVertices[j].Y = PanelCoordVert(boxtestY);
			}
			MapPanelGraphic->FillPolygon(Spectrum[thiscolour],PolygonVertices);
		}
		else //case for land cells
		{
			int NumVertices = NumberOfVertices[i];
			Point PolygonVertices __gc[]  = new Point[NumVertices];
			for (int j = 0; j<NumVertices;j++)
			{
				double boxtestX = box[i][j+1][1];
				double boxtestY = box[i][j+1][2];
				PolygonVertices[j].X = PanelCoordHoriz(boxtestX);
				PolygonVertices[j].Y = PanelCoordVert(boxtestY);
			}
			//doesn't work
			HatchBrush* LandBrush = new HatchBrush(HatchStyle::DarkHorizontal,Color::Black,Color::Wheat);
			MapPanelGraphic->FillPolygon(LandBrush,PolygonVertices);
			
			//TextureBrush* LandBrush = new HatchBrush(

			//works
			//SolidBrush* LandBrush = new SolidBrush(Color::Black);
			//MapPanelGraphic->FillPolygon(LandBrush,PolygonVertices);
		}
		
}
}

DrawLines();

		}

void getBGMdata(String* File_Name){
		StreamReader* sr1 = new StreamReader(File_Name);
		String* sLine1 = "null";
		//String* outputstring;
		ArrayList *arrText = new ArrayList();

		sLine1 = sr1->ReadLine();
		while (sLine1 != 0)
		{
		     arrText->Add(sLine1);
		     sLine1 = sr1->ReadLine();
		}
		sr1->Close();

		numBGMlines = arrText->Count;
		//double box[500][100][2];  //polygon#, vertex#, XorY
		int vertexNum;
		


		for(int i = 0; i<numBGMlines; i++)
		{
			String* thisline = arrText->Item[i]->ToString();
			int has_bnd_vert = thisline->IndexOf("bnd_vert");
			int has_box = thisline->IndexOf("BOX");
			if (has_box == -1){has_box = thisline->IndexOf("box");} //isaacs BGM used lower case
			int has_vert = thisline->IndexOf("vert ");
			int has_face = thisline->IndexOf("face");
			int has_p1 = thisline->IndexOf("p1");
			int has_p2 = thisline->IndexOf("p2");
			int numbounds = 0;


			
			if (has_box != -1 && has_vert != -1) //will not pick up "vertmix"
			{
				//case for box vertices

				String* numbers[] = thisline->Split(0);
				double vertex1 = Convert::ToDouble(numbers[1]);
				double vertex2 = Convert::ToDouble(numbers[2]);

				String* newstr1 = thisline->Substring(3,1);
				String* newstr2 = thisline->Substring(4,1);
				String* newstr3 = thisline->Substring(5,1);

				if (IsNumeric(newstr2))
				{
					newstr1 = String::Concat(newstr1,newstr2);
				}
				if (IsNumeric(newstr3))
				{
					newstr1 = String::Concat(newstr1,newstr3);
				}

				int thisbox1 = Convert::ToInt32(newstr1);
				
				if (thisbox1 != lastbox)
				{//new polygon
				//NumberOfVertices[lastbox]=vertexNum;
				vertexNum = 1;	
				}
				else
				{
				vertexNum++;
				NumberOfVertices[thisbox1]=vertexNum;
				}
				box[thisbox1][vertexNum][1]=Convert::ToDouble(numbers[1]);
				box[thisbox1][vertexNum][2]=Convert::ToDouble(numbers[2]);
				
				lastbox = thisbox1;
				NumBoxes = thisbox1;

				//determine maximum extent for north, south, east and west	
				//double tester = box[thisbox1][vertexNum][1];
				if (box[thisbox1][vertexNum][1]<westextent){westextent = box[thisbox1][vertexNum][1];}
				if (box[thisbox1][vertexNum][1]>eastextent){eastextent = box[thisbox1][vertexNum][1];}
				if (box[thisbox1][vertexNum][2]>northextent){northextent = box[thisbox1][vertexNum][2];}
				if (box[thisbox1][vertexNum][2]<southextent){southextent = box[thisbox1][vertexNum][2];}

			}

		}



}

	private: System::Void button1_Click(System::Object *  sender, System::EventArgs *  e)
			 {
				 ReadVector();
				 DrawMap();
			 }





private: System::Void button2_Click(System::Object *  sender, System::EventArgs *  e)
		 {

			 Bitmap* image = new Bitmap(500,500);
			 Graphics* gr;
			 gr = Graphics::FromImage(image);
			 Drawing::Size size;
			 size = System::Drawing::Size(500,500);

			 Point *source = __nogc new Point(0,0);
			 Point source2;
			 source2 = mappanel->PointToScreen(*source);
			 Point *destination = __nogc new Point(0,0);
			 
			 //gr->CopyFromScreen(*source,*destination,*size);

			 SaveFileDialog* saveBitmap = new SaveFileDialog;
			 saveBitmap->FileName = "Map";
			 saveBitmap->Filter = "bmp files (*.bmp)|*.bmp|All files (*.*)|*.*";
			 saveBitmap->RestoreDirectory = true;

			 if (saveBitmap->ShowDialog()==DialogResult::OK) 
			 {
				String* SaveBitmapFile = saveBitmap->FileName;
				image->Save(SaveBitmapFile);
			 }	

			 
		 }

private: System::Void mappanel_Paint(System::Object *  sender, System::Windows::Forms::PaintEventArgs *  e)
		 {
			DrawMap();
		 }

private: System::Void button3_Click(System::Object *  sender, System::EventArgs *  e)
		 {
			 Form1::textBox1->Text = "Paste concentrations";
		 }

private: System::Void SpectrumPanel_Paint(System::Object *  sender, System::Windows::Forms::PaintEventArgs *  e)
		 {
			 InitSpectrumPanel();
		 }

};
}


