#ifndef GUARD_PreyCompositionForm
#define GUARD_PreyCompositionForm

// PreyCompositionForm.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"
#include "PredatorParameterForm.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;


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

private:

	ArrayList* elementsList;
	ArrayList* elementsLabelsList;

	ArrayList* textBoxListColumns;
	ArrayList* textBoxListRows;

	System::Windows::Forms::Button* pcBtnBack;
	System::Windows::Forms::Button* pcBtnNext;

	Parameters *parameterObjectReference;

	int xSize;
	int ySize;

	bool validData;

	String* errorMessage;

	ArrayList* compositionList;

	DataGrid* compositionDataGrid;

	DataGridTableStyle* compositionTableStyle;

	DataGridColumnStyle* compositionColumnStyle;
	DataGridColumnStyle* headerColumnStyle;
	DataGridColumnStyle* predatorAgeColumnStyle;
	DataGridColumnStyle* preyAgeColumnStyle;

	DataTable* compositionDataTable;

	DataColumn* compositionDataColumn;
	DataColumn* headerDataColumn;
    DataColumn* predatorAgeDataColumn;
	DataColumn* preyAgeDataColumn;

	DataRow* compositionDataRow;

	DataRowCollection* compositionDataRowCollection;
	DataColumnCollection* compositionDataColumnCollection;

	PredatorParameterForm* formPredatorParameters;

	Label* tableTitle;
	ToolTip* titleToolTip;
    
	Button* lastBtnBack;
	Button* lastBtnNext;

	Button* pasteBtn;
	Label* pasteBtnLabel;

	System::Windows::Forms::ContextMenu* cdgContextMenu;

	Hashtable* dietValueHash;

public:

	PreyCompositionForm(Parameters *parameterObject, Button* prevBtnBack, Button* prevBtnNext) {

		this->parameterObjectReference = parameterObject;
		this->lastBtnBack = prevBtnBack;
		this->lastBtnNext = prevBtnNext;
		this->Closing += new System::ComponentModel::CancelEventHandler(this, ApplicationExit);
		this->set_AutoScroll(true);
		this->set_MaximizeBox(false);

		this->SuspendLayout();
		this->initializeMembers();
		this->initializeFromParameterObject(parameterObject);
 		this->initializeTable();
		this->initializePreyCompositionForm();
		this->ResumeLayout();
		this->Visible = true;
		this->initializeTableTitle();
	}


private:

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

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


	void initializeMembers() {
		this->validData = true;
		this->dietValueHash = new Hashtable();
	}


	void initializeFromParameterObject(Parameters* parameterObject) {
 
		this->elementsList = this->parameterObjectReference->getCodesList();
		this->elementsLabelsList = new ArrayList();
		this->textBoxListColumns = new ArrayList();
		this->textBoxListRows = new ArrayList();

        this->compositionList = parameterObject->getPreyCompositionList();
	}


	void initializeTable() {
		
		this->compositionDataGrid = new DataGrid();
		this->compositionDataGrid->BeginInit();

		this->compositionDataGrid->BackgroundColor = System::Drawing::Color::LightGray;
		this->compositionDataGrid->DataMember = S"Prey Composition Values";
		this->compositionDataGrid->Location = System::Drawing::Point(15, 40);
		this->compositionDataGrid->Name = S"compositionDataGrid";
		this->compositionDataGrid->set_AllowSorting(false);

		this->cdgContextMenu = new System::Windows::Forms::ContextMenu();
		this->cdgContextMenu->MenuItems->Add(new MenuItem(S"&Paste", new EventHandler(this, pasteBtn_Click)));
        
		this->initializeTableStyles();

		this->compositionDataGrid->EndInit();
	}


	void initializeTableStyles() {

        this->compositionDataTable = new DataTable(S"Prey Composition Values");

        this->headerDataColumn = this->compositionDataTable->Columns->Add("Species");
		this->headerDataColumn->ReadOnly = true;

		this->predatorAgeDataColumn = this->compositionDataTable->Columns->Add("PredatorCategory");
		this->predatorAgeDataColumn->ReadOnly = true;

		this->preyAgeDataColumn = this->compositionDataTable->Columns->Add("PreyCategory");
		this->preyAgeDataColumn->ReadOnly = true;

        this->compositionTableStyle = new DataGridTableStyle();
        this->compositionTableStyle->MappingName = S"Prey Composition Values";

		this->compositionTableStyle->HeaderBackColor = System::Drawing::Color::AliceBlue;
		this->compositionTableStyle->AlternatingBackColor = System::Drawing::Color::LightGray;

		this->headerColumnStyle = new DataGridTextBoxColumn();

		this->headerColumnStyle->MappingName = S"Species";
		this->headerColumnStyle->HeaderText = S"Species";
		this->headerColumnStyle->Width = 60;
		this->headerColumnStyle->ReadOnly = true;

		this->predatorAgeColumnStyle = new DataGridTextBoxColumn();

		this->predatorAgeColumnStyle->MappingName = S"PredatorCategory";
		this->predatorAgeColumnStyle->HeaderText = S"Predator Category";
		this->predatorAgeColumnStyle->Width = 100;
		this->predatorAgeColumnStyle->ReadOnly = true;

		this->preyAgeColumnStyle = new DataGridTextBoxColumn();

		this->preyAgeColumnStyle->MappingName = S"PreyCategory";
		this->preyAgeColumnStyle->HeaderText = S"Prey Category";
		this->preyAgeColumnStyle->Width = 100;
		this->preyAgeColumnStyle->ReadOnly = true;

		this->compositionTableStyle->GridColumnStyles->Add(this->headerColumnStyle);
		this->compositionTableStyle->GridColumnStyles->Add(this->predatorAgeColumnStyle);
		this->compositionTableStyle->GridColumnStyles->Add(this->preyAgeColumnStyle);

		this->initializeColumns();

     	this->compositionDataGrid->SetDataBinding(this->compositionDataTable, S"");

        this->initializeRows();
		this->compositionDataGrid->Size = System::Drawing::Size(640, 400);

    	this->compositionDataGrid->Refresh();
	}


	void initializeColumns() {

		ArrayList* codeCategoryList = this->parameterObjectReference->getCodeCategoryList();
		ArrayList* codesList = this->parameterObjectReference->getCodesList();
		int numElements = codeCategoryList->get_Count();

		IEnumerator* codeCategoryListEnumerator = codeCategoryList->GetEnumerator();

		for (int colHeaderValue = 2; colHeaderValue <= numElements+1; colHeaderValue++) {
			codeCategoryListEnumerator->MoveNext();
   			String* colHeaderString = System::Convert::ToString(codeCategoryListEnumerator->Current);

			DataGridTextBoxColumn* testColumn = new DataGridTextBoxColumn();
			this->compositionColumnStyle = testColumn;
	        this->compositionColumnStyle->Width = 40;
			TextBox* testBox = testColumn->get_TextBox();
            testBox->set_ContextMenu(this->cdgContextMenu);
			if (!codesList->Contains(colHeaderString)) {
				this->compositionColumnStyle->set_ReadOnly(true);
        		testBox->set_BackColor(System::Drawing::Color::LightSalmon);
			}

			this->compositionDataColumn = this->compositionDataTable->Columns->Add(colHeaderString);

			this->compositionColumnStyle->MappingName = colHeaderString;
			this->compositionColumnStyle->HeaderText = colHeaderString;
			this->compositionTableStyle->GridColumnStyles->Add(this->compositionColumnStyle);

			this->compositionDataGrid->TableStyles->Add(this->compositionTableStyle);
		}
		this->compositionDataColumnCollection = this->compositionDataTable->Columns;
	}


	void initializeRows() {
        // Iterate through each coefficient list

		IEnumerator* containerListEnumerator = this->compositionList->GetEnumerator();

		while (containerListEnumerator->MoveNext()) {
    		// Create a new row
			ArrayList* internalCompositionList = static_cast<ArrayList*>(containerListEnumerator->Current);
            IEnumerator* internalCompositionListEnumerator = internalCompositionList->GetEnumerator();
 
			// The first item in the coefficient list is the name, add it to the first column
            internalCompositionListEnumerator->MoveNext();
			String* codeString = static_cast<String*>(internalCompositionListEnumerator->Current); 

    		String* elementDelimiterString = S",";
        	Char elementDelimiter[];

		    elementDelimiter = elementDelimiterString->ToCharArray();
     		String* elementArray[] = codeString->Split(elementDelimiter);
        	String* species = elementArray[0];
			String* category = elementArray[1];

			String* speciesCategoryString = this->parameterObjectReference->getCategoryCode(species);
			if (category->Equals(S"Juvenile") && (speciesCategoryString->Equals(S"0") || speciesCategoryString->Equals(S"1"))) {

				this->initializeIndividualRow(internalCompositionListEnumerator, species, category, S"Juvenile", S"2");
                this->initializeIndividualRow(internalCompositionListEnumerator, S"", S"", S"Adult", S"1");
			}

			if (category->Equals(S"Adult") && (speciesCategoryString->Equals(S"0") || speciesCategoryString->Equals(S"2"))) {

				this->initializeIndividualRow(internalCompositionListEnumerator, species, category, S"Juvenile", S"2");
                this->initializeIndividualRow(internalCompositionListEnumerator, S"", S"", S"Adult", S"1");
			}
		}

		this->compositionDataRowCollection = this->compositionDataTable->Rows;
	}


	void initializeIndividualRow(IEnumerator* internalCompositionListEnumerator, String* speciesHeader, String* predatorCategory, String* preyCategory, String* testCode) {

     	this->compositionDataRow = this->compositionDataTable->NewRow();
     	this->compositionDataRow->Item[S"Species"] = speciesHeader;
        this->compositionDataRow->Item[S"PredatorCategory"] = predatorCategory;
	    this->compositionDataRow->Item[S"PreyCategory"] = preyCategory;

    	// For each item remaining in the coefficient list, add it to the next column in the same row
		ArrayList* allCodes = this->parameterObjectReference->getCodeCategoryList();
		int codesCount = allCodes->get_Count();
    
		ArrayList* usedCodes = this->parameterObjectReference->getCodesList();
		DataGridTextBoxColumn* testColumn = new DataGridTextBoxColumn();

   		for (int col = 3; col < codesCount+3; col++) {
       	    internalCompositionListEnumerator->MoveNext();
        	String* speciesCode = static_cast<String*>(allCodes->Item[col-3]);
            String* preyCategoryString = this->parameterObjectReference->getCategoryCode(speciesCode);
			if (preyCategoryString->Equals(S"3")) {
				preyCategoryString = S"2";
			}
			if ((!usedCodes->Contains(speciesCode)) || (preyCategoryString->Equals(testCode))) {
		        TextBox* testBox = testColumn->get_TextBox();
       		    testBox->set_BackColor(System::Drawing::Color::LightSalmon);
				testBox->set_ReadOnly(true);
				testColumn->set_ReadOnly(true);
			    this->compositionDataRow->Item[col] = S"n/a";
    		} else {
   	    		String* compositionString = static_cast<String*>(internalCompositionListEnumerator->Current); 
   		        this->compositionDataRow->Item[col] = this->standardizeComposition(compositionString);
    		}
	    }
   		this->compositionDataTable->Rows->Add(this->compositionDataRow);
	}


	String* standardizeComposition(String* composition) {

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

		String* compositionArray[] = composition->Split(delimiter);

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

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

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


	void initializePreyCompositionForm() {

		this->StartPosition = System::Windows::Forms::FormStartPosition::CenterScreen;
		this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
 		this->FormBorderStyle = System::Windows::Forms::FormBorderStyle::Fixed3D;
        this->Text = S"Diet Composition";

		this->ClientSize = System::Drawing::Size(740, 500);

		this->pcBtnBack = new System::Windows::Forms::Button();
		this->pcBtnBack->Location = System::Drawing::Point(600, 465);
		this->pcBtnBack->Size = System::Drawing::Size(50, 24);
		this->pcBtnBack->Text = S"Back";
		this->pcBtnBack->Click += new EventHandler(this, pcBtnBack_Click);
		this->Controls->Add(pcBtnBack);

		this->pcBtnNext = new System::Windows::Forms::Button();
		this->pcBtnNext->Location = System::Drawing::Point(665, 465);
		this->pcBtnNext->Size = System::Drawing::Size(50, 24);
		this->pcBtnNext->Text = S"Next";
		this->pcBtnNext->Click += new EventHandler(this, pcBtnNext_Click);
		this->Controls->Add(pcBtnNext);

		this->pasteBtn = new System::Windows::Forms::Button();
		this->pasteBtn->Location = System::Drawing::Point(25, 465);
		this->pasteBtn->Size = System::Drawing::Size(50, 24);
		this->pasteBtn->Text = S"Paste";
		this->pasteBtn->Click += new EventHandler(this, pasteBtn_Click);
		this->Controls->Add(pasteBtn);

		this->pasteBtnLabel = new System::Windows::Forms::Label();
		this->pasteBtnLabel->Location = System::Drawing::Point(85, 460);
		this->pasteBtnLabel->Size = System::Drawing::Size(200, 60);
		this->pasteBtnLabel->Text = S"Click on the correct starting row and cell and then click the Paste button.  Only one row may be pasted at a time.";
        this->Controls->Add(pasteBtnLabel);

		this->Controls->Add(this->compositionDataGrid);
	}


	void initializeTableTitle() {

		this->tableTitle = new Label();
		this->tableTitle->Location = System::Drawing::Point(310, 15);
		this->tableTitle->Size = System::Drawing::Size(100, 40);
		this->tableTitle->Text = S"Diet Composition";

		this->titleToolTip = new ToolTip();
 
        // Set up the delays for the ToolTip.
        this->titleToolTip->AutoPopDelay = 500000;
        this->titleToolTip->InitialDelay = 1000;
        this->titleToolTip->ReshowDelay = 100;
        // Force the ToolTip text to be displayed whether or not the form is active.
        this->titleToolTip->ShowAlways = true;
      
        // Set up the ToolTip text for the Table Title
        this->titleToolTip->SetToolTip(this->tableTitle, S"Each value in the table is the diet composition (as a proportion of the total)\nof a prey item in the row for a predator in the column.  Values must be between 0-1.");
        this->Controls->Add(this->tableTitle);
	}


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

        this->ResetDataFlags();

		this->populateLocalList();
		this->saveLocalParameters();

   		if (this->validData) {
            this->Close();
		}
	}


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

        this->ResetDataFlags();

		// Populate local lists with data
        this->populateLocalList();

        // Save local parameters to the permanent parameter object
        this->saveLocalParameters();
		
		if (this->validData) {
			this->pcBtnBack->set_Enabled(false);
			this->pcBtnNext->set_Enabled(false);
 		    this->formPredatorParameters = new PredatorParameterForm(this->parameterObjectReference, this->pcBtnBack, this->pcBtnNext);
		}
	}


	void ResetDataFlags() {

		this->validData = true;
		this->errorMessage = S"ERROR: Some values are invalid.  These values have been replaced with 'INV'.";
	}


	void populateLocalList() {

		this->compositionList->Clear();
		ArrayList* codeCategoryList = this->parameterObjectReference->getCodeCategoryList();
        int numElements = codeCategoryList->get_Count();

		int rowIndex = 1;

		IEnumerator* compositionDataRowEnumerator = this->compositionDataRowCollection->GetEnumerator();

		String* categoryString;
		String* speciesCommaString;
		String* elementString;
		String* finalElementString;
		String* trimDelim = S" ";
		ArrayList* newSpecificCompositionList;
		ArrayList* tempCategoryList = this->parameterObjectReference->getCodeCategoryList();
		Hashtable* tempCategoryHash = this->parameterObjectReference->getCodeCategoryHash();
        String* lastPredatorCategory = S"";
		String* lastPredatorSpecies = S"";
        String* predatorSpecies = S"";
		String* compositionString = S"";
		double predatorSum = 0.0;
		bool incorrectSum = false;
		String* incorrectSumMessage = S"All Diet Composition values for a given species should equal 0.0 or 1.0.\nListed below are the species that do not meet this criteria and the sums of their diet composition values:";  

		while (compositionDataRowEnumerator->MoveNext()) {

			DataRow* currentCompositionDataRow = static_cast<DataRow*>(compositionDataRowEnumerator->Current);
  
			String* rowPredatorCategory = static_cast<String*>(currentCompositionDataRow->Item[1]);
			if (rowPredatorCategory->Equals(S"")) {
			    rowPredatorCategory = lastPredatorCategory;
			} else {
				lastPredatorCategory = rowPredatorCategory;
				predatorSum = 0.0;
			}

			if (rowPredatorCategory->Equals(S"Adult")) {
				predatorSpecies = static_cast<String*>(currentCompositionDataRow->Item[0]);
				if (predatorSpecies->Equals(S"")) {
					predatorSpecies = lastPredatorSpecies;
				} else {
					lastPredatorSpecies = predatorSpecies;
 				}

				String* predatorCategoryString = static_cast<String*>(tempCategoryHash->get_Item(predatorSpecies));
				predatorCategoryString = predatorCategoryString->Trim(trimDelim->ToCharArray());                       
				if (predatorCategoryString->Equals(S"1")) {
                    DataRow* tempDataRow = this->compositionDataRowCollection->Item[rowIndex];
					for (int i=3; i < numElements+3; i++) {
						String* currentString = static_cast<String*>(currentCompositionDataRow->Item[i]);
						if (!currentString->Equals(S"n/a")) {
    					    currentCompositionDataRow->Item[i] = S"0.0";
						    tempDataRow->Item[i] = S"0.0";
						}
					}
				}
			}

			if (rowPredatorCategory->Equals(S"Juvenile")) {
				String* predatorSpecies = static_cast<String*>(currentCompositionDataRow->Item[0]);
				if (predatorSpecies->Equals(S"")) {
					predatorSpecies = lastPredatorSpecies;
				} else {
					lastPredatorSpecies = predatorSpecies;
 				}

				String* predatorCategoryString = static_cast<String*>(tempCategoryHash->get_Item(predatorSpecies));

				predatorCategoryString = predatorCategoryString->Trim(trimDelim->ToCharArray());                       

				if (predatorCategoryString->Equals(S"2")) {
					DataRow* tempDataRow = this->compositionDataRowCollection->Item[rowIndex];
					for (int i=3; i < numElements+3; i++) {
						String* currentString = static_cast<String*>(currentCompositionDataRow->Item[i]);
						if (!currentString->Equals(S"n/a")) {
    					    currentCompositionDataRow->Item[i] = S"0.0";
						    tempDataRow->Item[i] = S"0.0";
						}
					}
				}
			}

			String* speciesString = static_cast<String*>(currentCompositionDataRow->Item[0]);
			if (!(speciesString->Equals(S""))) {
    			newSpecificCompositionList = new ArrayList();

				categoryString = static_cast<String*>(currentCompositionDataRow->Item[1]); 
	    		speciesCommaString = System::String::Concat(speciesString, S",");
		    	elementString = System::String::Concat(speciesCommaString, categoryString);

                finalElementString = elementString->Trim(trimDelim->ToCharArray());

			    newSpecificCompositionList->Add(elementString);
			}


			for (int compositionIndex = 3; compositionIndex <= numElements+2; compositionIndex++) {
				compositionString = static_cast<String*>(currentCompositionDataRow->Item[compositionIndex]);
				try {
					if (!(compositionString->Equals(S"n/a"))) {
    				   double compositionStringValue = System::Convert::ToDouble(compositionString);
   	    			   if ((compositionStringValue < 0) || (compositionStringValue > 1) || (compositionString->Equals(S"INV"))) {
                            currentCompositionDataRow->Item[compositionIndex] = S"INV";
     	    			    this->validData = false;
					   }
					}

					String* rowPreyCategory = static_cast<String*>(currentCompositionDataRow->Item[2]);

					if (rowPreyCategory->Equals(S"Adult")) {
						int preyIndex = compositionIndex-3;
						String* preySpecies = static_cast<String*>(tempCategoryList->Item[preyIndex]);
						Hashtable* tempCategoryHash = this->parameterObjectReference->getCodeCategoryHash();
						String* preyCategoryString = static_cast<String*>(tempCategoryHash->get_Item(preySpecies));
                        preyCategoryString = preyCategoryString->Trim(trimDelim->ToCharArray());                       
						if (preyCategoryString->Equals(S"1")) {
							currentCompositionDataRow->Item[compositionIndex] = S"n/a";
							compositionString = S"0.0";
						}
					}

					if (rowPreyCategory->Equals(S"Juvenile")) {
						int preyIndex = compositionIndex-3;
						String* preySpecies = static_cast<String*>(tempCategoryList->Item[preyIndex]);
						Hashtable* tempCategoryHash = this->parameterObjectReference->getCodeCategoryHash();
						String* preyCategoryString = static_cast<String*>(tempCategoryHash->get_Item(preySpecies));
                        preyCategoryString = preyCategoryString->Trim(trimDelim->ToCharArray());                       
						if (preyCategoryString->Equals(S"2") || preyCategoryString->Equals(S"3")) {
							currentCompositionDataRow->Item[compositionIndex] = S"n/a";
							compositionString = S"0.0";
						}
					}

				} catch (System::FormatException*) {
                    currentCompositionDataRow->Item[compositionIndex] = S"INV";
					compositionString = S"0.0";
   				    this->validData = false;
				}

				if (compositionString->Equals(S"n/a")) {
					compositionString = S"0.0";
				}
				newSpecificCompositionList->Add(compositionString);

				double compositionValue = System::Convert::ToDouble(compositionString);
	    		predatorSum += compositionValue;
			}

			if (speciesString->Equals(S"")) {
			    this->compositionList->Add(newSpecificCompositionList);
                System::Decimal predatorSumDecimal = predatorSum;
		    	predatorSumDecimal = System::Decimal::Round(predatorSumDecimal, 5);
				if (predatorSumDecimal != 1.0 && predatorSumDecimal != 0.0) {
					incorrectSum = true;
					String* predatorSumString = System::Convert::ToString(predatorSum);
					String* incorrectValueString = S"";
					incorrectValueString = incorrectValueString->Concat(incorrectValueString, finalElementString);
					incorrectValueString = incorrectValueString->Concat(incorrectValueString, S" (");
					incorrectValueString = incorrectValueString->Concat(incorrectValueString, predatorSumString);
					incorrectValueString = incorrectValueString->Concat(incorrectValueString, S")");
					incorrectSumMessage = incorrectSumMessage->Concat(incorrectSumMessage, S"\n");
					incorrectSumMessage = incorrectSumMessage->Concat(incorrectSumMessage, incorrectValueString);
				}
			}

			rowIndex++;
		}
		if (incorrectSum) {
			this->errorMessage = incorrectSumMessage;
			this->validData = false;
		}

	}


	void saveLocalParameters() {

		if (this->validData) {
            this->parameterObjectReference->setPreyCompositionList(this->compositionList);
		} else {
			String* message = this->errorMessage;
			String* caption = S"ERROR: Incorrect Values";
			MessageBoxButtons buttons = MessageBoxButtons::OK;
			System::Windows::Forms::DialogResult result;
   			// Pop up warning box informing the user that some values need to be changed
			result = MessageBox::Show(this, message, caption, buttons);
		}
	}

	void pasteFromMenu(Object* /*sender*/, EventArgs* /*e*/) {
		System::Console::WriteLine(S"InsideMenuPaste");
	}

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

		ArrayList* usedCodes = this->parameterObjectReference->getCodesList();
		ArrayList* allCodes = this->parameterObjectReference->getCodeCategoryList();
		DataGridCell currentCell = this->compositionDataGrid->get_CurrentCell();

		int row = currentCell.get_RowNumber();
		int column = currentCell.get_ColumnNumber();

		if (column > 2) {
    		IDataObject *data = Clipboard::GetDataObject();
            // If the data is text, then set the text of the 
            // TextBox to the text in the Clipboard.
    		if (data->GetDataPresent(DataFormats::Text)) {
	    		String* pastedString = data->GetData(DataFormats::Text)->ToString();

    			String* pastedDelimiterString = S",";
        	    Char pastedDelimiter[];

	    	    pastedDelimiter = pastedDelimiterString->ToCharArray();
  		        String* pastedStringLineArray[] = pastedString->Split(pastedDelimiter);
                int count = pastedStringLineArray->get_Count();
    			DataRow *currentDataRow = static_cast<DataRow*>(this->compositionDataRowCollection->get_Item(row));
				
				int index = column;
                String* codeString;

				for (int i = 0; i < count; i++) {
                    codeString = static_cast<String*>(allCodes->Item[index-3]);
					if (usedCodes->Contains(codeString)) {
                        String* currentValue = static_cast<String*>(currentDataRow->Item[index]);
						if (!currentValue->Equals(S"n/a")) {
						    currentDataRow->Item[index] = pastedStringLineArray[i];
						}
					}
					index++;
				}
			}
		}
	}

};
#endif