#ifndef GUARD_PredatorParameterForm
#define GUARD_PredatorParameterForm

// PredatorParameterForm.h header file

#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"

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::Reflection;
using namespace System::Drawing;
using namespace System::Runtime::Serialization;
using namespace System::Runtime::Serialization::Formatters;
using namespace System::Runtime::Serialization::Formatters::Binary;

public __gc class PredatorParameterForm : public System::Windows::Forms::Form {

private:
	System::Windows::Forms::Label* speciesLabel;
 	System::Windows::Forms::Label* growthRateLabel;
	System::Windows::Forms::Label* initialBiomassLabel;
	System::Windows::Forms::Label* efficiencyLabel;
 	System::Windows::Forms::Label* clearanceRateLabel;
	System::Windows::Forms::Label* svarLabel;

	System::Windows::Forms::ToolTip* labelsToolTip;

	ArrayList* speciesList;
	ArrayList* speciesLabelsList;
	ArrayList* growthRateTextBoxList;
	ArrayList* initialBiomassTextBoxList;
	ArrayList* efficiencyTextBoxList;
    ArrayList* clearanceRateTextBoxList;
	ArrayList* svarTextBoxList;

    Hashtable* growthRateHash;
	Hashtable* initialBiomassHash;
	Hashtable* efficiencyHash;
	Hashtable* clearanceRateHash;
	Hashtable* svarHash;

	System::Windows::Forms::Button* prpfBtnRun;
	System::Windows::Forms::Button* prpfBtnBack;

	Parameters *parameterObjectReference;

	bool validData;
	bool suspectData;
	String* errorMessage;

	Button* lastBtnBack;
	Button* lastBtnNext;
	int yPos;


public:
	PredatorParameterForm(Parameters *parameterObject, Button* prevBtnBack, Button* prevBtnNext) {

		this->lastBtnBack = prevBtnBack;
		this->lastBtnNext = prevBtnNext;
		this->Closing += new System::ComponentModel::CancelEventHandler(this, applicationExit);

		this->set_AutoScroll(true);
		this->set_MaximizeBox(false);
		this->parameterObjectReference = parameterObject;

		this->SuspendLayout();
        this->initializeLabels();
		this->initializeFromParameterObject(parameterObject);
    	this->initializeTextBoxes();
		this->initializeButtons();
		this->initializePredatorParameterForm();
		this->ResumeLayout();
		this->Visible = true;
        this->initializeToolTips();
	}

private:
	void applicationExit(Object* sender, System::ComponentModel::CancelEventArgs* e) {

        this->lastBtnBack->set_Enabled(true);
		this->lastBtnNext->set_Enabled(true);
	}

	void initializeLabels() {
		
		// Set up the species column label
		this->speciesLabel = new System::Windows::Forms::Label();
		this->speciesLabel->Location = System::Drawing::Point(30, 30);
		this->speciesLabel->Size = System::Drawing::Size(140, 24);
		this->speciesLabel->Text = S"Species";
 
		// Set up the growth rate column label
		this->growthRateLabel = new System::Windows::Forms::Label();
		this->growthRateLabel->Location = System::Drawing::Point(220, 16);
		this->growthRateLabel->Size = System::Drawing::Size(90, 48);
		this->growthRateLabel->Text = S"Growth Rate (g)\n(/day)";
		this->growthRateLabel->set_TextAlign(System::Drawing::ContentAlignment::TopCenter);

		// Set up the initial biomass column label
		this->initialBiomassLabel = new System::Windows::Forms::Label();
		this->initialBiomassLabel->Location = System::Drawing::Point(310, 16);
		this->initialBiomassLabel->Size = System::Drawing::Size(100, 48);
		this->initialBiomassLabel->Text = S"Initial Biomass (B)\n(mt)";
		this->initialBiomassLabel->set_TextAlign(System::Drawing::ContentAlignment::TopCenter);

        // Set up the efficiency column label
		this->efficiencyLabel = new System::Windows::Forms::Label();
		this->efficiencyLabel->Location = System::Drawing::Point(420, 16);
		this->efficiencyLabel->Size = System::Drawing::Size(95, 24);
		this->efficiencyLabel->Text = S"Efficiency (E)";

		// Set up the clearance rate label
		this->clearanceRateLabel = new System::Windows::Forms::Label();
		this->clearanceRateLabel->Location = System::Drawing::Point(515, 16);
		this->clearanceRateLabel->Size = System::Drawing::Size(120, 48);
		this->clearanceRateLabel->Text = S"Clearance Rate (C)\n(mg3 / mg N) / day";
		this->clearanceRateLabel->set_TextAlign(System::Drawing::ContentAlignment::TopCenter);

		// Set up the Mean Stomach Weight Label
		this->svarLabel = new System::Windows::Forms::Label();
		this->svarLabel->Location = System::Drawing::Point(620, 16);
		this->svarLabel->Size = System::Drawing::Size(140, 48);
		this->svarLabel->Text = S"S\n(/day)";
		this->svarLabel->set_TextAlign(System::Drawing::ContentAlignment::TopCenter);

	}


	void initializePredatorParameterForm() {
		this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
		this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
 		this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::Fixed3D;
		System::Windows::Forms::Control* formControls[] = {this->speciesLabel, this->growthRateLabel, this->initialBiomassLabel, this->efficiencyLabel, this->clearanceRateLabel, this->svarLabel};
        this->Controls->AddRange(formControls);
        this->Text = S"Species Parameters";

		if (this->yPos >= 525) {
		    this->ClientSize = System::Drawing::Size(800, 600);
		} else {
			this->ClientSize = System::Drawing::Size(800, this->yPos+75);
		}
	}

	void initializeButtons() {

		this->prpfBtnRun = new System::Windows::Forms::Button();
		this->prpfBtnRun->Location = System::Drawing::Point(740, this->yPos + 30);
		this->prpfBtnRun->Size = System::Drawing::Size(50, 24);
		this->prpfBtnRun->Text = S"Run";
		this->prpfBtnRun->Click += new EventHandler(this, prpfBtnRun_Click);
		this->Controls->Add(prpfBtnRun);

		this->prpfBtnBack = new System::Windows::Forms::Button();
		this->prpfBtnBack->Location = System::Drawing::Point(675, this->yPos + 30);
		this->prpfBtnBack->Size = System::Drawing::Size(50, 24);
		this->prpfBtnBack->Text = S"Back";
		this->prpfBtnBack->Click += new EventHandler(this, prpfBtnBack_Click);
		this->Controls->Add(prpfBtnBack);
	}


	void initializeFromParameterObject(Parameters* parameterObject) {
 
		this->speciesList = parameterObject->getCompleteCodesList();
    	this->speciesLabelsList = new ArrayList();
    	this->growthRateTextBoxList = new ArrayList();
    	this->initialBiomassTextBoxList = new ArrayList();
    	this->efficiencyTextBoxList = new ArrayList();
        this->clearanceRateTextBoxList = new ArrayList();
		this->svarTextBoxList = new ArrayList();

        this->growthRateHash = parameterObject->getGrowthRateHash();
	    this->initialBiomassHash = parameterObject->getInitialBiomassHash();
    	this->efficiencyHash = parameterObject->getEfficiencyHash();
	    this->clearanceRateHash = parameterObject->getClearanceRateHash();
		this->svarHash = parameterObject->getSvarHash();

		this->validData = true;
		this->suspectData = false;
	}


	void initializeTextBoxes() {

		this->initializeLists();

        // Set initial X and Y positions
 		int xPos = 30;
		this->yPos = 55;

		IEnumerator* speciesListEnumerator = this->speciesList->GetEnumerator();
		IEnumerator* speciesLabelsListEnumerator = this->speciesLabelsList->GetEnumerator();
		IEnumerator* growthRateTextBoxListEnumerator = this->growthRateTextBoxList->GetEnumerator();
		IEnumerator* initialBiomassTextBoxListEnumerator = this->initialBiomassTextBoxList->GetEnumerator();
        IEnumerator* efficiencyTextBoxListEnumerator = this->efficiencyTextBoxList->GetEnumerator();
		IEnumerator* clearanceRateTextBoxListEnumerator = this->clearanceRateTextBoxList->GetEnumerator();
        IEnumerator* svarTextBoxListEnumerator = this->svarTextBoxList->GetEnumerator();

		Object* speciesObject;
		String* speciesString;
		Object* speciesLabelObject;
		Object* growthRateObject;
		Object* initialBiomassObject;
		Object* efficiencyObject;
		Object* clearanceRateObject;
		Object* svarObject;

		System::Windows::Forms::Label *speciesLabel;
		System::Windows::Forms::TextBox *growthRateTextBox;
		System::Windows::Forms::TextBox *initialBiomassTextBox;
		System::Windows::Forms::TextBox *efficiencyTextBox;
		System::Windows::Forms::TextBox *clearanceRateTextBox;
		System::Windows::Forms::TextBox *svarTextBox;

		String* commaDelimString=S",";
        Char commaDelim[];

		commaDelim = commaDelimString->ToCharArray();

		while (speciesListEnumerator->MoveNext()) {
			speciesLabelsListEnumerator->MoveNext();
			growthRateTextBoxListEnumerator->MoveNext();
			initialBiomassTextBoxListEnumerator->MoveNext();
			efficiencyTextBoxListEnumerator->MoveNext();
			clearanceRateTextBoxListEnumerator->MoveNext();
			svarTextBoxListEnumerator->MoveNext();

			speciesLabelObject = speciesLabelsListEnumerator->Current;
			speciesLabel = static_cast<System::Windows::Forms::Label*>(speciesLabelObject);
			speciesLabel->Size = System::Drawing::Size(200, 24);
			speciesObject = speciesListEnumerator->Current;
			speciesString = speciesObject->ToString();
     	    String* speciesCodeArray[] = speciesString->Split(commaDelim);
            String* speciesCode = speciesCodeArray[0];
			String* speciesCategory = this->parameterObjectReference->getCategoryCode(speciesCode);

			speciesLabel->Location = System::Drawing::Point(xPos, yPos + 3);
			// If the 'species' is detritus don't add adult/juvenile modifier
			if (speciesCategory->Equals(S"3")) { 
				speciesLabel->Text = System::String::Concat(speciesCode, S" (Prey Only)");
			} else {
			    speciesLabel->Text = speciesString;
			}

			initialBiomassObject = initialBiomassTextBoxListEnumerator->Current;
			initialBiomassTextBox = static_cast<System::Windows::Forms::TextBox*>(initialBiomassObject);
			initialBiomassTextBox->Size = System::Drawing::Size(50, 15);
			initialBiomassTextBox->Location = System::Drawing::Point(xPos + 303, yPos + 3);

			growthRateObject = growthRateTextBoxListEnumerator->Current;
			growthRateTextBox = static_cast<System::Windows::Forms::TextBox*>(growthRateObject);
			growthRateTextBox->Size = System::Drawing::Size(50, 15);
			growthRateTextBox->Location = System::Drawing::Point(xPos + 200, yPos + 3);

			efficiencyObject = efficiencyTextBoxListEnumerator->Current;
			efficiencyTextBox = static_cast<System::Windows::Forms::TextBox*>(efficiencyObject);
			efficiencyTextBox->Size = System::Drawing::Size(50, 15);
			efficiencyTextBox->Location = System::Drawing::Point(xPos + 396, yPos + 3);

			clearanceRateObject = clearanceRateTextBoxListEnumerator->Current;
			clearanceRateTextBox = static_cast<System::Windows::Forms::TextBox*>(clearanceRateObject);
			clearanceRateTextBox->Size = System::Drawing::Size(50, 15);
			clearanceRateTextBox->Location = System::Drawing::Point(xPos + 500, yPos + 3);

			svarObject = svarTextBoxListEnumerator->Current;
			svarTextBox = static_cast<System::Windows::Forms::TextBox*>(svarObject);
			svarTextBox->Size = System::Drawing::Size(50, 15);
			svarTextBox->Location = System::Drawing::Point(xPos + 625, yPos + 3);

			// Make the boxes for detritus unable to be modified by the user, except for biomass
			if (speciesCategory->Equals(S"3")) {
				growthRateTextBox->set_Enabled(false);
				efficiencyTextBox->set_Enabled(false);
				clearanceRateTextBox->set_Enabled(false);
				svarTextBox->set_Enabled(false);
			}

			String* growthRateString = this->getHashValue(this->growthRateHash, speciesString);
            growthRateTextBox->Text = this->standardizeCoefficient(growthRateString);

			String* initialBiomassString = this->getHashValue(this->initialBiomassHash, speciesString);
			initialBiomassTextBox->Text = initialBiomassString;

			String* efficiencyString = this->getHashValue(this->efficiencyHash, speciesString);
			efficiencyTextBox->Text = this->standardizeCoefficient(efficiencyString);

			String* clearanceRateString = this->getHashValue(this->clearanceRateHash, speciesString);
			clearanceRateTextBox->Text = this->standardizeCoefficient(clearanceRateString);

			String* svarString = this->getHashValue(this->svarHash, speciesString);
			svarTextBox->Text = this->standardizeCoefficient(svarString);

			this->Controls->Add(speciesLabel);
			this->Controls->Add(growthRateTextBox);
			this->Controls->Add(initialBiomassTextBox);
			this->Controls->Add(efficiencyTextBox);
			this->Controls->Add(clearanceRateTextBox);
			this->Controls->Add(svarTextBox);

			this->yPos += 22;
		}

	}


	void initializeLists() {

	    int numSpecies = this->speciesList->get_Count();

		for (int speciesIndex = 0; speciesIndex < numSpecies; speciesIndex++) {
			this->speciesLabelsList->Add(new System::Windows::Forms::Label());
			this->growthRateTextBoxList->Add(new System::Windows::Forms::TextBox());
			this->initialBiomassTextBoxList->Add(new System::Windows::Forms::TextBox());
			this->efficiencyTextBoxList->Add(new System::Windows::Forms::TextBox());
			this->clearanceRateTextBoxList->Add(new System::Windows::Forms::TextBox());
			this->svarTextBoxList->Add(new System::Windows::Forms::TextBox());
		}
	}


	String* standardizeCoefficient(String* coefficient) {

		String* delimStr = S".";
        Char delimiter[] = delimStr->ToCharArray();

		String* coefficientArray[] = coefficient->Split(delimiter);

		int coefficientArraySize = coefficientArray->Count;
		if ((coefficientArraySize == 1) || (coefficientArray[1] == S"")) {    // Example: coefficient = "2" or "2."	
			return String::Concat(coefficientArray[0], S".0");
		}

		if (coefficientArray[0] == S"") {       // Example: coefficient = ".2"
			return String::Concat(S"0.", coefficientArray[1]);
		}

		return coefficient;                     // If coefficient string was 'valid', Example: "2.0"
	}


	String* getHashValue(Hashtable* selectedHash, String* keyString) {

		String* valueString;
    	if (selectedHash->ContainsKey(keyString)) {
			valueString = System::Convert::ToString(selectedHash->get_Item(keyString));
		} else {
			valueString = S"0";
		}   
		return valueString;
	}


	void initializeToolTips() {
		this->labelsToolTip = new ToolTip();
 
        // Set up the delays for the ToolTip.
        this->labelsToolTip->AutoPopDelay = 500000;
        this->labelsToolTip->InitialDelay = 1000;
        this->labelsToolTip->ReshowDelay = 100;
        // Force the ToolTip text to be displayed whether or not the form is active.
        this->labelsToolTip->ShowAlways = true;
      
        // Set up the ToolTip text for the Button and Checkbox.
        this->labelsToolTip->SetToolTip(this->growthRateLabel, S"Values must be greater than 0.");
        this->labelsToolTip->SetToolTip(this->initialBiomassLabel, S"Values must be greater than or equal to 0.  Values of 0 are considered unusual.");
        this->labelsToolTip->SetToolTip(this->efficiencyLabel, S"Values must be >= 0 and <= 1.0."); 
        this->labelsToolTip->SetToolTip(this->clearanceRateLabel, S"Values must be greater than 0.");
	}


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

		this->resetDataFlags();

		// Populate local hashes with data
		this->populateLocalHashes();

		this->saveLocalParametersBack();
	}


	void resetDataFlags() {

		this->validData = true;
		this->suspectData = false;
		this->errorMessage = S"ERROR: Some values are incorrect.  These values are indicated in Red.  All values must be numbers and must be within the limits of the parameter.  These can be seen by holding the mouse over the column label.  These parameters must be fixed before continuing.";
	}


	void populateLocalHashes() {

		this->populateLocalHash(this->growthRateHash, this->growthRateTextBoxList, S"GrowthRateErrorCheck"); 
		this->populateLocalHash(this->initialBiomassHash, this->initialBiomassTextBoxList, S"BiomassErrorCheck");
		this->populateLocalHash(this->efficiencyHash, this->efficiencyTextBoxList, S"EfficiencyErrorCheck");
		this->populateLocalHash(this->clearanceRateHash, this->clearanceRateTextBoxList, S"ClearanceRateErrorCheck");
        this->populateLocalHash(this->svarHash, this->svarTextBoxList, S"SvarErrorCheck");
	}


	void populateLocalHash(Hashtable* &selectedHash, ArrayList* &selectedTextBoxList, String* errorCheckType) {

		selectedHash->Clear();
		IEnumerator *speciesListEnumerator = this->speciesList->GetEnumerator();
		IEnumerator *selectedTextBoxListEnumerator = selectedTextBoxList->GetEnumerator();

		Object* speciesObject;
		String* speciesString;

		String* selectedString;

		Object* selectedObject;
		TextBox* selectedTextBox;

		double selectedValue;

		while (speciesListEnumerator->MoveNext()) {

			selectedTextBoxListEnumerator->MoveNext();

			speciesObject = speciesListEnumerator->Current;
			speciesString = speciesObject->ToString();

			selectedObject = selectedTextBoxListEnumerator->Current;
			selectedTextBox = static_cast<System::Windows::Forms::TextBox*>(selectedObject);

			selectedString = selectedTextBox->get_Text();
			selectedTextBox->set_BackColor(System::Drawing::Color::White);

			selectedValue = this->returnNumberFromString(selectedString, selectedTextBox);

			if (errorCheckType->Equals(S"GrowthRateErrorCheck")) {
				this->checkGrowthRateValue(selectedValue, selectedTextBox);
			} else if (errorCheckType->Equals(S"BiomassErrorCheck")) {
				this->checkBiomassValue(selectedValue, selectedTextBox);
			} else if (errorCheckType->Equals(S"EfficiencyErrorCheck")) {
				this->checkEfficiencyValue(selectedValue, selectedTextBox);
			} else if (errorCheckType->Equals(S"ClearanceRateErrorCheck")) {
				this->checkClearanceRateValue(selectedValue, selectedTextBox);
			} else if (errorCheckType->Equals(S"SvarErrorCheck")) {
				this->checkSvarValue(selectedValue, selectedTextBox);
			} else {
				Console::WriteLine(S"WARNING: No appropriate Error Check selected in PredatorParameterForm::PopulateLocalHash");
			}

			if (selectedHash->ContainsKey(speciesString)) {
				selectedHash->Remove(speciesString);
			}
			selectedHash->Add(speciesString, selectedString);
		}
	}


	double returnNumberFromString(String* valueString, TextBox* selectedTextBox) {

		double value;
    	try {
			value = System::Convert::ToDouble(valueString);
		} catch (System::FormatException*) {
			this->flagInvalidData(selectedTextBox);
		}
		return value;
	}


	void checkGrowthRateValue(double growthRate, TextBox* growthRateTB) {

		if (growthRate <= 0 && growthRateTB->Enabled == true) {
			this->flagInvalidData(growthRateTB);
			return;
		}

//		if (growthRate >= 4) {
//            this->createWarning(growthRateTB);
//		}
	}


	void checkBiomassValue(double biomass, TextBox* biomassTB) {
		
		if (biomass <= 0) {
			this->flagInvalidData(biomassTB);
		}

//		if (biomass == 0) {
//			this->createWarning(biomassTB);
//		}
	}


	void checkEfficiencyValue(double efficiencyCoefficient, TextBox* efficiencyTB) {

		if (((efficiencyCoefficient < 0) || (efficiencyCoefficient > 1)) && efficiencyTB->Enabled == true) {
			this->flagInvalidData(efficiencyTB);
		}
	}


	void checkClearanceRateValue(double clearanceRate, TextBox* clearanceRateTB) {

		if (clearanceRate <= 0 && clearanceRateTB->Enabled == true) {
			this->flagInvalidData(clearanceRateTB);
//			return;
		}

//		if (clearanceRate >= 4) {
//            this->createWarning(clearanceRateTB);
//		}
	}

	void checkSvarValue(double svar, TextBox* svarTB) {
		if (svar < 0 && svarTB->Enabled == true) {
			this->flagInvalidData(svarTB);
		}
	}

	void createWarning(TextBox* textBox) {

		textBox->set_BackColor(System::Drawing::Color::Yellow);
		this->suspectData = true;
	}


	void flagInvalidData(TextBox* textBox) {

		textBox->set_BackColor(System::Drawing::Color::LightSalmon);
		this->validData = false;
	}



	void saveLocalParametersBack() {

		// If data is valid
		if (this->validData) {
    		// Check for possibly incorrect data
	    	// If data is suspect
			if (this->suspectData) {
                // Initialize the Message Box components
				String* message = S"WARNING: Some values are outside the usually accepted bounds (normal bounds can be seen by holding the mouse over the column label).  These values are indicated in Yellow.  Do you wish to re-enter data?  If 'No', the current values will be saved.";
				String* caption = S"WARNING: Unusual values";
				MessageBoxButtons buttons = MessageBoxButtons::YesNo;
				System::Windows::Forms::DialogResult result;
    			// Pop up warning box asking if the user wants to continue
				result = MessageBox::Show(this, message, caption, buttons);
				// If No, allow user to change the data
 			    if (result == DialogResult::Yes) {
                    return;
				}
			}	
		    this->copyLocalHashesToParameterObject();
			this->parameterObjectReference->setInitialized();
		    this->Close();
		} else {
			String* message = this->errorMessage;
			String* caption = S"ERROR: Incorrect Values";
			MessageBoxButtons buttons = MessageBoxButtons::OK;
			System::Windows::Forms::DialogResult result;
   			// Pop up warning box asking if the user wants to continue
			result = MessageBox::Show(this, message, caption, buttons);
		}
	}


	void copyLocalHashesToParameterObject() {

		this->parameterObjectReference->setGrowthRateHash(this->growthRateHash);
		this->parameterObjectReference->setInitialBiomassHash(this->initialBiomassHash);
		this->parameterObjectReference->setEfficiencyHash(this->efficiencyHash);
		this->parameterObjectReference->setClearanceRateHash(this->clearanceRateHash);
        this->parameterObjectReference->setSvarHash(this->svarHash);
	}


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

		this->resetDataFlags();

		// Populate local hashes with data
		this->populateLocalHashes();

		// If data is valid
		if (this->validData) {
    		// Check for possibly incorrect data
	    	// If data is suspect
			if (this->suspectData) {
                // Initialize the Message Box components
				String* message = S"WARNING: Some values are outside the usually accepted bounds (normal bounds can be seen by holding the mouse over the column label).  These values are indicated in Yellow.  Do you wish to re-enter data?  If 'No', the current values will be saved.";
				String* caption = S"WARNING: Unusual values";
				MessageBoxButtons buttons = MessageBoxButtons::YesNo;
				System::Windows::Forms::DialogResult result;
    			// Pop up warning box asking if the user wants to continue
				result = MessageBox::Show(this, message, caption, buttons);
				// If No, allow user to change the data
 			    if (result == DialogResult::Yes) {
                    return;
				}
			}	
		    this->copyLocalHashesToParameterObject();
			this->parameterObjectReference->setInitialized();
			this->saveFileCheck();
    		this->parameterObjectReference->runModel();
		} else {
			String* message = this->errorMessage;
			String* caption = S"ERROR: Incorrect Values";
			MessageBoxButtons buttons = MessageBoxButtons::OK;
			System::Windows::Forms::DialogResult result;
   			// Pop up warning box asking if the user wants to continue
			result = MessageBox::Show(this, message, caption, buttons);
		}

	}

	void saveFileCheck() {
        String *message = S"Do you want to Save?";
		String *caption = S"Warning: Save?";
        MessageBoxButtons buttons = MessageBoxButtons::YesNo;
        System::Windows::Forms::DialogResult result;

        // Displays the MessageBox.
        result = MessageBox::Show(this, message, caption, buttons);

		if (result == DialogResult::Yes) {
			this->file_SaveAs(); 
		} else {
		    return;
		}
	}


	void file_SaveAs() {

		SaveFileDialog *pfileSaveFileDialog = new SaveFileDialog();

        pfileSaveFileDialog->Filter = "parameter 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->parameterObjectReference);
            pfileStream->Close();
		}
	}

};
#endif