#using <mscorlib.dll>
#using <System.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <System.Data.dll>

#include <iostream>
#include <istream>
#include <fstream>
#include "Parameters.h"
#include "SpeciesEntryForm.h"

using namespace std;
using namespace System;
using namespace System::IO;
using namespace System::Drawing;
using namespace System::Collections;
using namespace System::ComponentModel;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Runtime::Serialization;
using namespace System::Runtime::Serialization::Formatters;
using namespace System::Runtime::Serialization::Formatters::Binary;


public __gc class InitialForm : public System::Windows::Forms::Form {
private:
	System::Windows::Forms::Button* btnRun;
	System::Windows::Forms::Button* btnParameter;

	System::Windows::Forms::MainMenu* mainMenu;
	System::Windows::Forms::MenuItem* miFile;
	System::Windows::Forms::MenuItem* miAbout;

	System::Windows::Forms::Label* creditLabel;

	PictureBox* backgroundGraphic;

	Parameters* parameterObject;

    bool openedParameterObject;

	Char delimiter[];

    SpeciesEntryForm* formSpeciesEntry;

	System::Windows::Forms::RadioButton* allCodesOutputRB;
	System::Windows::Forms::RadioButton* selectedCodesOutputRB;
	System::Windows::Forms::GroupBox* radioBtnGroupBox;


public:
    InitialForm() {

		this->set_MaximizeBox(false);

		this->openedParameterObject = false;
		this->parameterObject = new Parameters();

		this->SuspendLayout();
 
		this->creditLabel = new System::Windows::Forms::Label();
		this->creditLabel->Location = System::Drawing::Point(460, 415);
		this->creditLabel->Size = System::Drawing::Size(180,20);
		this->creditLabel->Text = S"Athanasius Kircher, 1665";

        this->allCodesOutputRB = new RadioButton();
        this->allCodesOutputRB->Text = S"All";
		this->allCodesOutputRB->Size = System::Drawing::Size(50, 20);
		this->allCodesOutputRB->Location = System::Drawing::Point(30, 17);
		this->allCodesOutputRB->Click += new EventHandler(this, allCodesOutputRB_Click);

		this->selectedCodesOutputRB = new RadioButton();
        this->selectedCodesOutputRB->Text = S"Selected";
		this->selectedCodesOutputRB->Size = System::Drawing::Size(70, 20);
		this->selectedCodesOutputRB->Location = System::Drawing::Point(90, 17);
        this->selectedCodesOutputRB->Click += new EventHandler(this, selectedCodesOutputRB_Click);

		if ((this->parameterObject->getOutputType())->Equals(S"Selected")) {
            this->selectedCodesOutputRB->set_Checked(true);
 		} else {
			this->allCodesOutputRB->set_Checked(true);
 		}

		this->radioBtnGroupBox = new GroupBox();
		this->radioBtnGroupBox->Name = S"btnGroupBox";
		this->radioBtnGroupBox->Location = System::Drawing::Point(15, 410);
		this->radioBtnGroupBox->Size = System::Drawing::Size(170, 45);
		this->radioBtnGroupBox->Text = S"Output Type";

		this->radioBtnGroupBox->Controls->Add(allCodesOutputRB);
        this->radioBtnGroupBox->Controls->Add(selectedCodesOutputRB);

		this->btnRun = new System::Windows::Forms::Button();
		this->btnRun->Location = System::Drawing::Point(220, 415);
		this->btnRun->Size = System::Drawing::Size(80, 40);
		this->btnRun->Font = new System::Drawing::Font(S"Arial", 20);
		this->btnRun->Text = S"Run";

		this->btnRun->Click += new EventHandler(this, btnRun_Click);

		this->btnParameter = new System::Windows::Forms::Button();
        this->btnParameter->Location = System::Drawing::Point(320, 415);
		this->btnParameter->Size = System::Drawing::Size(80, 40);
		this->btnParameter->Font = new System::Drawing::Font(S"Arial", 10, FontStyle::Bold);
		this->btnParameter->Text = S"Parameter\nEntry";

		this->btnParameter->Click += new EventHandler(this, btnParameter_Click);


  		// Menu Creation
		this->mainMenu = new System::Windows::Forms::MainMenu();
		this->miFile = new MenuItem(S"&File");
		this->mainMenu->MenuItems->Add(this->miFile);
		this->miFile->MenuItems->Add(new MenuItem(S"&Open...", new EventHandler(this, miFile_Open)));

		this->miFile->MenuItems->Add(S"-");
		this->miFile->MenuItems->Add(new MenuItem(S"&Save", new EventHandler(this, miFile_Save)));

		this->miFile->MenuItems->Add(S"-");
		this->miFile->MenuItems->Add(new MenuItem(S"E&xit", new EventHandler(this, miFile_Exit)));

        this->miAbout = new MenuItem(S"&About");
		this->mainMenu->MenuItems->Add(this->miAbout);
		this->miAbout->MenuItems->Add(new MenuItem(S"&About", new EventHandler(this, miAbout_about)));

		this->backgroundGraphic = new PictureBox();
		this->backgroundGraphic->Size = System::Drawing::Size(617, 410);
		this->backgroundGraphic->Dock = DockStyle::Top;
		this->backgroundGraphic->BackColor = Color::White;

		Bitmap* backgroundImage = dynamic_cast<Bitmap*>(Image::FromFile("Athanasius_Kircher's.gif", true));
		this->backgroundGraphic->set_Image(backgroundImage);

		this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
        this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
		this->ClientSize = System::Drawing::Size(617, 458);
		this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::Fixed3D;
		System::Windows::Forms::Control* formControls[] = {this->btnRun, this->btnParameter, this->creditLabel, this->backgroundGraphic, this->radioBtnGroupBox};
        this->Controls->AddRange(formControls);
        this->Text = S"Atlantis - Availability Parameters Calculation Form";
		this->Menu = this->mainMenu;

        this->ResumeLayout(false);

		String* delimiterString = S",";
		this->delimiter = delimiterString->ToCharArray();
	}

	void miFile_Open(Object* sender, EventArgs* e) {

		OpenFileDialog *openParameterFileDialog = new OpenFileDialog();

        openParameterFileDialog->Filter = "parameter files (*.pob)|*.pob" ;
		openParameterFileDialog->FilterIndex = 1;
        openParameterFileDialog->RestoreDirectory = true;

        if (openParameterFileDialog->ShowDialog() == DialogResult::OK) {
            String* parameterFileName = openParameterFileDialog->get_FileName();
            IFormatter *pfileOpenFormatter = new BinaryFormatter();
         	Stream* pfileOpenStream = new FileStream(parameterFileName, FileMode::Open, FileAccess::Read, FileShare::Read);
			this->parameterObject = static_cast<Parameters*>(pfileOpenFormatter->Deserialize(pfileOpenStream));
            pfileOpenStream->Close();
			this->openedParameterObject = true;
            String* outputType = this->parameterObject->getOutputType();
			if (outputType->Equals(S"Selected")) {
                this->selectedCodesOutputRB->set_Checked(true);
 		    } else {
			    this->allCodesOutputRB->set_Checked(true);
 		    }
		}
	}

	void miFile_Exit(Object* sender, EventArgs* e) {
		this->Close();
	}


	void miFile_Save(Object* sender, EventArgs* e) {

		SaveFileDialog *pfileSaveFileDialog = new SaveFileDialog();

        pfileSaveFileDialog->Filter = "parameter object files (*.pob)|*.pob"  ;
        pfileSaveFileDialog->FilterIndex = 1 ;
        pfileSaveFileDialog->RestoreDirectory = true ;
		pfileSaveFileDialog->Title = S"Save Parameter Object File";

	    if (pfileSaveFileDialog->ShowDialog() == DialogResult::OK) {

			String *saveParameterFileName = pfileSaveFileDialog->get_FileName();

			IFormatter *parameterObjectFormatter = new BinaryFormatter();
			Stream *pfileStream = new FileStream(saveParameterFileName, FileMode::Create, FileAccess::Write, FileShare::None);
 
			parameterObjectFormatter->Serialize(pfileStream, this->parameterObject);
            pfileStream->Close();
		}
	}


	void miAbout_about(Object* sender, EventArgs* e) {

          String *message = S"Atlantis Parameter Entry (version 1.0)\nProgram created by Robert J. Gamble\n\nRobert.Gamble@noaa.gov\n\nFront Screen Image published by Athanasius Kircher (1665).";
		  String *caption = S"About";
          MessageBoxButtons buttons = MessageBoxButtons::OK;
          System::Windows::Forms::DialogResult result;
          // Displays the MessageBox.
          result = MessageBox::Show(this, message, caption, buttons);
	}

	void btnRun_Click(Object* sender, EventArgs* e) {

		this->parameterObject->runModel();
	}


	void btnParameter_Click(Object* /*sender*/, EventArgs* /*e*/) {

		this->formSpeciesEntry = new SpeciesEntryForm(this->parameterObject);
	}


	void allCodesOutputRB_Click(Object* /*sender*/, EventArgs* /*e*/) {

        this->parameterObject->setOutputType(S"All");
	}


	void selectedCodesOutputRB_Click(Object* /*sender*/, EventArgs* /*e*/) {

        this->parameterObject->setOutputType(S"Selected");
	}

};


/// The main entry point for the application.
 [STAThread]

int main() {
	Application::Run(new InitialForm());
}