#include "InstantiateTemplate.h"
#include "ui_InstantiateTemplate.h"
#include "DesTypes.h"
//test
#include <iostream>
#include <sstream>
#include "Des.h"
#include <QSize>
#include "DesEvent.h"
#include <vector>
#include "TemplateNameParser.h"
#include <QMessageBox>

namespace DESpot
{
	NameValidator InstantiateTemplate::m_rangeInputNameValidator(new AlphaNumValidator(new WordSepValidator(new DotValidator(new CommaValidator()))));
	NameValidator InstantiateTemplate::m_tupleInputNameValidator(new AlphaNumValidator(new WordSepValidator(new BracketValidator(new CommaValidator()))));
	NameValidator InstantiateTemplate::m_InstantiateActNameValidator(new AlphaNumValidator(new WordSepValidator(new DotValidator())));
	NameValidator InstantiateTemplate::m_tuplevalueNameValidator(new AlphaNumValidator(new WordSepValidator(new DotValidator())));
	InputType InstantiateTemplate::m_Option;
	InstantiateTemplate::InstantiateTemplate(const Des& templateDes,QWidget* parent):QDialog(parent),m_TemplateDes(templateDes)
	{
		
		setupUi(this);
		setupConnections();
		m_parameters=TemplateNameParser::getVariablesFromName(m_TemplateDes.getName());
		GenerateTableforRange();
		GenerateTableforTuple();
		m_Range->setChecked(true);
		CheckInputOption();
		if(m_TemplateDes.getType()==eInterfaceTemplateDes)
		{
			m_supDesLevelWidg->setChecked(true);
			m_plantDesLevelWidg->setEnabled(false);
			m_supDesLevelWidg->setEnabled(false);
		}
		else
		{
			m_plantDesLevelWidg->setChecked(true);
		}
		
		
		

	}

	InstantiateTemplate::InstantiateTemplate(const Des& templateDes,DesLevel deslevel,TemplateNameParser::TemplateParameter*  m_parameter,const std::wstring InstInfoDlgName,std::vector<std::wstring> rangeinput,std::wstring tupleinput,InputType inputtype,QWidget* parent):QDialog(parent),m_TemplateDes(templateDes),m_RangeInput(rangeinput),m_TupleInput(tupleinput)
	{
		setupUi(this);
		setupConnections();
		m_parameters=TemplateNameParser::getVariablesFromName(m_TemplateDes.getName());
		if(inputtype==DESpot::eRange)
		{
			LoadTableforRange(m_parameters,rangeinput);
			GenerateTableforTuple();
			m_Range->setChecked(true);
		}
		else
		{		
			LoadTableforTuple(m_parameters,tupleinput);
			GenerateTableforRange();
			m_Tuple->setChecked(true);
		}
		
		CheckInputOption();
		NameValue->setText(QString::fromStdWString(InstInfoDlgName));
		if(m_TemplateDes.getType()==eInterfaceTemplateDes)
		{
			m_supDesLevelWidg->setChecked(true);
			m_plantDesLevelWidg->setEnabled(false);
			m_supDesLevelWidg->setEnabled(false);
		}
		else if(deslevel==ePlantDes)
		{
			m_plantDesLevelWidg->setChecked(true);
		}
		else if(deslevel==eSupervisorDes)
		{
			m_supDesLevelWidg->setChecked(true);
		}
		//m_parameters=TemplateNameParser::getVariablesFromName(m_TemplateDes.getName());
		

	}


	InstantiateTemplate::~InstantiateTemplate(void)
	{
		//delete m_parameters;
	}

	std::wstring InstantiateTemplate::getInstantiationName() const
	{
		//std::wstring instantiationname = new wstring;
		//instantiationname = NameValue->text().toStdWString();
		return  NameValue->text().toStdWString();
	}

	bool InstantiateTemplate::validInstantiateActName(const std::wstring& name)
	{ 

		if(name.empty())
		{
			QMessageBox::information(NULL, "DESpot","Error: Name field can not be left blank.");
           		return false;

	
		}
		else
		{
			if(m_InstantiateActNameValidator.validate(name))
			{
				return true;
			}
			else
			{
				QMessageBox::information(NULL, "DESpot","Error: Use an alpha-numeric string (a-z;A-Z;0-9;.-_");
				return false;
			}
		}
		
	}
		
	void InstantiateTemplate::GenerateTableforRange()
	{
		//m_parameters=TemplateNameParser::getVariablesFromName(m_TemplateDes.getName());
		TemplateNameParser::TemplateParameterItr iterator=m_parameters->begin();
		int rowcount=0;
		
		while(iterator!=m_parameters->end())
		{	
			QTableWidgetItem* m_item=new QTableWidgetItem(QTableWidgetItem::Type);
			RangeTable->insertRow(rowcount);
			m_item->setText(QString::fromStdWString(iterator->first));
			m_item->setFlags(m_item->flags()&~Qt::ItemIsEditable);
			RangeTable->setItem(rowcount,0,m_item);
			RangeTable->setItem(rowcount,1,new QTableWidgetItem);
			rowcount++;
			iterator++;
			
		}
	}

	void InstantiateTemplate::LoadTableforRange(TemplateNameParser::TemplateParameter* parameter,std::vector<std::wstring> rangeinput)
	{
		TemplateNameParser::TemplateParameterItr iterator=parameter->begin();
		int rowcount=0;
		
		while(iterator!=parameter->end())
		{	
			QTableWidgetItem* m_item=new QTableWidgetItem(QTableWidgetItem::Type);
			QTableWidgetItem* m_item2=new QTableWidgetItem;
			RangeTable->insertRow(rowcount);
			m_item->setText(QString::fromStdWString(iterator->first));
			m_item->setFlags(m_item->flags()&~Qt::ItemIsEditable);
			m_item2->setText(QString::fromStdWString(rangeinput[rowcount]));
			RangeTable->setItem(rowcount,0,m_item);
			RangeTable->setItem(rowcount,1,m_item2);
			rowcount++;
			iterator++;
			
		}
	}
	
	void InstantiateTemplate::GenerateTableforTuple()
	{
		//m_parameters=TemplateNameParser::getVariablesFromName(m_TemplateDes.getName());
		TemplateNameParser::TemplateParameterItr iterator_2=m_parameters->begin();
		iterator_2++;
		if(iterator_2==m_parameters->end())
		{
			m_Tuple->setEnabled(false);
		}
		else
		{
			iterator_2--;
			int rowcount_2=0;
			TupleTable->insertRow(rowcount_2);
			QTableWidgetItem* n_item=new QTableWidgetItem(QTableWidgetItem::Type);
			QString* TupleFormat=new QString;
			TupleFormat->append(QString::fromStdWString(iterator_2->first));
			iterator_2++;
			while(iterator_2!=m_parameters->end())
		{	
			TupleFormat->append(",");
			TupleFormat->append(QString::fromStdWString(iterator_2->first));	
			iterator_2++;

		}
			n_item->setText("("+*TupleFormat+")");
			n_item->setFlags(n_item->flags()&~Qt::ItemIsEditable);
			TupleTable->setItem(rowcount_2,0,n_item);
			TupleTable->setItem(rowcount_2,1,new QTableWidgetItem);
		}
		

	}
		
	void InstantiateTemplate::LoadTableforTuple(TemplateNameParser::TemplateParameter* parameter,std::wstring tupleinput)
	{
		
		TemplateNameParser::TemplateParameterItr iterator_2=parameter->begin();
		iterator_2++;
		if(iterator_2==parameter->end())
		{
			m_Tuple->setEnabled(false);
		}
		else
		{
			iterator_2--;
			int rowcount_2=0;
			TupleTable->insertRow(rowcount_2);
			QTableWidgetItem* n_item=new QTableWidgetItem(QTableWidgetItem::Type);
			QString* TupleFormat=new QString;
			TupleFormat->append(QString::fromStdWString(iterator_2->first));
			QString* TupleInput=new QString;
			TupleInput->append(QString::fromStdWString(iterator_2->second));
			iterator_2++;
			while(iterator_2!=parameter->end())
			{	
				TupleFormat->append(",");
				TupleFormat->append(QString::fromStdWString(iterator_2->first));	
				iterator_2++;

		}
		n_item->setText("("+*TupleFormat+")");
		n_item->setFlags(n_item->flags()&~Qt::ItemIsEditable);
		TupleTable->setItem(rowcount_2,0,n_item);
		QTableWidgetItem* n_item_2 = new QTableWidgetItem;
		n_item_2->setText(QString::fromStdWString(tupleinput));
		TupleTable->setItem(rowcount_2,1,n_item_2);
		}
	}
		
		

	bool InstantiateTemplate::CheckLevel()
	{
		if(m_supDesLevelWidg->isChecked())
		{
			m_deslevel=eSupervisorDes;
			return true;
		}
		if(m_plantDesLevelWidg->isChecked())
		{
			m_deslevel=ePlantDes;
			return true;
		}

		return false;
	}

	bool InstantiateTemplate::CheckInputOption()
	{
		if(m_Tuple->isChecked())
		{
			onHideRange();
			m_Option=eTuple;
			return true;
		}
		if(m_Range->isChecked())
		{
			onHideTuple();
			m_Option=eRange;
			return true;
			
		}
		return false;
	}	
	
	InputType InstantiateTemplate::getInputType()
	{
		return m_Option;
	}

	void InstantiateTemplate::accept()
	{
		if(m_Option==eRange&&CheckLevel()&&extractInputforRange()&&CheckInputOption()&&validInstantiateActName(NameValue->text().toStdWString()))
		{	
			QDialog::accept();
		}

		if(m_Option==eTuple&&CheckLevel()&&extractInputforTuple()&&CheckInputOption()&&validInstantiateActName(NameValue->text().toStdWString()))
		{	
			QDialog::accept();
		}

	}

	void InstantiateTemplate::reject()
	{
		QDialog::reject();
	
	}

	void InstantiateTemplate::setupConnections()
	{
		InstantiateTemplate::connect(m_Tuple,SIGNAL(clicked()),this,SLOT(onHideRange()));
		InstantiateTemplate::connect(m_Range,SIGNAL(clicked()),this,SLOT(onHideTuple()));
		InstantiateTemplate::connect(m_plantDesLevelWidg,SIGNAL(clicked()),this,SLOT(onChangeType_1()));
		InstantiateTemplate::connect(m_supDesLevelWidg,SIGNAL(clicked()),this,SLOT(onChangeType_2()));

	}
	
	void InstantiateTemplate::onHideRange()
	{
		RangeTable->setVisible(false);
		TupleTable->setVisible(true);
		m_Tuple->setChecked(true);
		m_Range->setChecked(false);
		m_Option=eTuple;
	}

	void InstantiateTemplate::onHideTuple()
	{	
		RangeTable->setVisible(true);
		TupleTable->setVisible(false);
		m_Range->setChecked(true);
		m_Tuple->setChecked(false);
		m_Option=eRange;
	}
	
	void InstantiateTemplate::onChangeType_1()
	{
		m_plantDesLevelWidg->setChecked(true);
		m_supDesLevelWidg->setChecked(false);	
		
	}
	
	void InstantiateTemplate::onChangeType_2()
	{
		m_plantDesLevelWidg->setChecked(false);
		m_supDesLevelWidg->setChecked(true);	
		
	}

		
	bool InstantiateTemplate::extractInputforRange()
	{
		m_RangeInput.clear();
		int rowcount=RangeTable->rowCount();

		for(int i=0;i<rowcount;i++)
		{
			if(RangeTable->item(i,1)->text().isEmpty()==false)
			{
				(*m_parameters)[RangeTable->item(i,0)->text().toStdWString()]=RangeTable->item(i,1)->text().toStdWString();
				setRangeInput(RangeTable->item(i,1)->text().toStdWString());
				
				if(!checkRangeInput(RangeTable->item(i,1)->text().toStdWString()))
				{
					return false;
				}

			}
			else
			{
				return false;
			}
		}
		return true;
	}

	bool InstantiateTemplate::extractInputforTuple()
	{
		
		 if(TupleTable->item(0,1)->text().isEmpty())
      		 {
           		return false;
       		 }

      	  	 std::wstring variable = TupleTable->item(0, 1)->text().toStdWString();
		 setTupleInput(variable);

       		 std::wstring value = TupleTable->item(0, 1)->text().toStdWString();
		 int nVarNum = m_parameters->size();
       		 std::vector<std::wstring> vTupleArray;

       		 if ( !parserTupleValueToArray(value, vTupleArray) )
        	 {
          	  	return false;
       		 }

       		 
       		 for (int i = 0; i < (int)vTupleArray.size(); i++)
       		 {
       	    		 std::vector<std::wstring> vOneTupleArray;
           		 if (!parserOneTupleValueToArray(vTupleArray[i], vOneTupleArray))
           		 {
                		return false;
            			}			
           		 if ((int)vOneTupleArray.size() != nVarNum)
           		 {
				QMessageBox::information(NULL, "DESpot","Error: the number of values doesn't match the number of variables.");
             		 	return false;
           		 }
			TemplateNameParser::TemplateParameterItr itr=m_parameters->begin();
          		  for (int j = 0; j < (int)vOneTupleArray.size(); j++)
           		 {
				
				if(itr!=m_parameters->end())
				{
					
					std::wstring string = vOneTupleArray[j];
					if (i != (int)vTupleArray.size() - 1)
					{ 
						string+=L',';
					}
					itr->second+=string;
				}
				itr++;	
				 	//(*m_parameters)[vVarArray[j]] += vOneTupleArray[j];
               				 
                   	 		//(*m_parameters)[vVarArray[j]] += L',';
           		 }
      		  }


		return true;

	}
	
	bool InstantiateTemplate::parserTupleValueToArray(std::wstring value, std::vector<std::wstring> &vTupleArray)
    	{
        int len = value.length();
        int beg = 0;
        int end = 0;
        int i = 0;
	//int nVarNum = m_parameters->size();
        if (i < len && value[i] != L'(')
        {
              	QMessageBox::information(NULL, "DESpot","Error in bracket.");
           	return false;
        }
	  beg = i;

        int bracket = 1;
	int nQuot=0;
        while (i < len)
        {
            if (value[i] == L')')
            {
                if(i+1<len&&value[i+1]!=L',')
		{
			QMessageBox::information(NULL, "DESpot","Error:Each tuple must be seperated by comma");
            		//error=3;
                        return false;
		}
                end = i;
                std::wstring str = value.substr(beg, end - beg + 1);
                vTupleArray.push_back(str);
                i++;
                i++;
		nQuot++;
                
                if (i < len && value[i] == L'(')
                {
		    bracket++;
                    beg=i;
                    i++;  
                }
		else
		{
			if(i<len)
			{
				QMessageBox::information(NULL, "DESpot","Error in bracket.");
				//error=1;
				return false;
			}
		}
               // beg = i;
                i++;
//		nQuot = 0;
            }
           /* else if(value[i] == L',')
	    {
		nQuot++;
		i++;
	    }*/
            else
            {
		i++;
	    }
        }
	if(bracket!=nQuot)
	{
		QMessageBox::information(NULL, "DESpot","Error in paired bracket");
		return false;
	}
        return true;
    }

    bool InstantiateTemplate::parserOneTupleValueToArray(std::wstring value, std::vector<std::wstring> &vTupleArray)
    {
        int len = value.length();
        int beg = 0;
        int end = 0;
        int i = 0;
        if(value[i]!=L'(')
        {
	       QMessageBox::information(NULL, "DESpot","Error in bracket.");
        }
        i++;
        beg = i;


        while (i < len)
        {
            if (value[i] == L')' || value[i] == L',')
            {
                end = i;
        // if (end == beg && (value[i] == L',' || value[i] == L')'))
          //          throw EX("6 Error in comma")
                std::wstring str = value.substr(beg, end - beg);
                vTupleArray.push_back(str);
                if(value[i]==L','&&(value[i+1]==L','||value[i+1]==L')'))
                {
			QMessageBox::information(NULL, "DESpot","Error in comma/bracket.");
                }

                i++;

                while (i < len && value[i] == L'(')
                    i++;
                beg = i;
            }
            else
            {
                if (!doCheck(value[i]))
			QMessageBox::information(NULL, "DESpot","Error: use an alpha-numeric string.");
                i++;
            }
        }

        return true;
    }
	
    bool InstantiateTemplate::doCheck(wchar_t ch)
    {
        if ((ch >= L'a' && ch <= L'z') || (ch >= L'A' && ch <= L'Z'))
            return true;
        if (ch >= L'0' && ch <= L'9')
            return true;
        if (ch == L'-' || ch == L'_' || ch == L'.')
            return true;

        return false;
    }
//for tuple
	InstantiateTemplate::InstantiatedTemplate* InstantiateTemplate::generateTemplateParameterFromTuple(TemplateNameParser::TemplateParameter Template )
    {
        InstantiateTemplate::InstantiatedTemplate* result=new InstantiateTemplate::InstantiatedTemplate;
        std::vector<std::vector<std::wstring> > vAllArrays;
        TemplateNameParser::TemplateParameterItr itr1=Template.begin();
        for (int i = 0; i < Template.size(); i++)
        {
            std::vector<std::wstring> vArray;
            parserTemplateToArray(itr1->second, vArray);
            vAllArrays.push_back(vArray);
            itr1++;
        }

        int count = vAllArrays[0].size();
        for (int i = 0; i < count; i++)
        {
            TemplateNameParser::TemplateParameter param;
            TemplateNameParser::TemplateParameterItr itr=Template.begin();
            for (int j = 0; j < vAllArrays.size(); j++)
            {
                std::wstring name=itr->first;
                param.insert(TemplateNameParser::TemplateParameter::value_type(name,vAllArrays[j][i]));
                itr++;
            }
            result->push_back(param);
        }

        return result;
    }
	
	void InstantiateTemplate::parserTemplateToArray(std::wstring value, std::vector<std::wstring> &vArray)
    {
        int len = value.length();
        int beg = 0;
        int end = 0;
        int i = 0;

        while (i < len)
        {
            if (value[i] == L',')
            {
                end = i;
                std::wstring str = value.substr(beg, end - beg);
                vArray.push_back(str);
                i++;
                beg = i;
            }
            else
                i++;
        }

        if (beg < len)
        {
            std::wstring str = value.substr(beg, len - beg);
            vArray.push_back(str);
        }
    }


	
	bool InstantiateTemplate::matchDot(const std::wstring& name)

	{
		int dotcount=countDot(name);
		if(dotcount==2&&dotcount==0&&m_rangeInputNameValidator.validate(name))
		{
			return true;
		}
		else
		{
			return false;
			
		}
	}
	
	/*bool InstantiateTemplate::validateParametersName(const TemplateNameParser::TemplateParameter& parameters)
	{
		TemplateNameParser::TemplateParameterCItr citerator=parameters.begin();
		while(citerator!=parameters.end())
		{
			if(matchDot(citerator->second)==false)
			{
				return false;
			}
			citerator++;
		}
		return true;
	}*/

	InstantiateTemplate::Parameters* InstantiateTemplate::getSingleParameters(const std::wstring& name)
	{	
		//if(m_Option==eRange)	
		{
			Parameters* separateParameter=new InstantiateTemplate::Parameters;
			Parameters* temp=splitComma(name);
			ParametersItr iterator=temp->begin();
			while(iterator!=temp->end())
			{
				if(countDot(*iterator)==0)
				{
					separateParameter->push_back(*iterator);
				}
				else if(countDot(*iterator)==2)
				{	
					generateFromRange(*separateParameter,*iterator);		
				}
				else 
				{
					QMessageBox::information(NULL, "DESpot","too much '.' in range format");
					//break;
\
				}
				iterator++;
			}	
			return separateParameter;
		}
		/*if(m_Option==eTuple)
		{
			Parameters* separateParameter=new InstantiateTemplate::Parameters;
			Parameters* temp=splitBracket(name);
			Parameters* temp_2=new InstantiateTemplate::Parameters;
			ParametersItr iterator=temp->begin();
			ParametersItr iterator_2=temp_2->begin();
			while(iterator!=temp->end())
			{
				temp_2=splitComma(*iterator);
				//separateParameter->push_back(	
			}
		}*/
		
	

	}

//For range
	InstantiateTemplate::InstantiatedTemplate* InstantiateTemplate::generateTemplateParameterFromTemplate(TemplateNameParser::TemplateParameter Template )
	{
		/*  if (m_Option == eTuple)
       		 {
         	  	return generateTemplateParameterFromTuple(Template);
      		 }*/
		InstantiateTemplate::InstantiatedTemplate* result=new InstantiateTemplate::InstantiatedTemplate;
		TemplateNameParser::TemplateParameterItr itr=Template.begin();
		if(itr!=Template.end())
		{
			TemplateNameParser::TemplateParameter* af=new TemplateNameParser::TemplateParameter;
			std::wstring name=itr->first;
			InstantiateTemplate::Parameters* pars=getSingleParameters(itr->second);
			itr++;
			while(itr!=Template.end())
			{
				af->insert(TemplateNameParser::TemplateParameter::value_type(itr->first,itr->second));
				itr++;
			}
			InstantiateTemplate::InstantiatedTemplate* temp=generateTemplateParameterFromTemplate(*af);
			InstantiateTemplate::ParametersItr pItr=pars->begin();
			if(temp->size()!=0)
			{
				while(pItr!=pars->end())
				{
					
					InstantiateTemplate::InstantiatedTemplateItr eItr=temp->begin();
					while(eItr!=temp->end())
					{
						TemplateNameParser::TemplateParameter t=*eItr;
						t.insert(TemplateNameParser::TemplateParameter::value_type(name,*pItr));
						result->push_back(t);
						eItr++;
					}
					pItr++;
				}

			}
			else
			{
				while(pItr!=pars->end())
				{
					TemplateNameParser::TemplateParameter* t=new TemplateNameParser::TemplateParameter;
					t->insert(TemplateNameParser::TemplateParameter::value_type(name,*pItr));
					result->push_back(*t);
					pItr++;
				}
			}

		}
		return result;
	}


	InstantiateTemplate::Parameters* InstantiateTemplate::splitComma(const std::wstring& name)
	{
		Parameters* result=new Parameters;
		result->push_back(*(new std::wstring));
		if(name[0]==L',')
		{
			QMessageBox::information(NULL, "DESpot","Error in comma.");
			//throw EX("Error in comma.");
		}
		else
		{
		for(int i=0;i<name.size();i++)
		{	
			if(name[i]==L',')
			{
				result->push_back(*(new std::wstring));
				if(name[i+1]==L',')
				{
					QMessageBox::information(NULL, "DESpot","Error in comma.");
					//throw EX("Error in comma.");
				}
			}
			else
			{
				(result->back())+=name[i];
			}
		}
		return result;
		}

	}

	InstantiateTemplate::Parameters* InstantiateTemplate::splitBracket(const std::wstring& name)
	{
		Parameters* result=new Parameters;
		int countBracket=0;
		result->push_back(*(new std::wstring));
		if(name[0]!=L'(')
		{
			throw EX("Error in Bracket.");
		}
		else
		{
		for(int i=0;i<name.size();i++)
		{	
			if(name[i]==L')')
			{
				result->push_back(*(new std::wstring));
				countBracket++;
				if(name[i+1]!=L'(')
				{
					throw EX("Error in Bracket.");
				}

			}
			else if(name[i+1]==L'(')
			{
				i++;
			}
			else 
			{
				(result->back())+=name[i];
			}
		}
		return result;
		}

	}



	bool InstantiateTemplate::generateFromRange(InstantiateTemplate::Parameters& parameters,std::wstring& SingleString)
	{
	
		int index=0;
		std::wstring parameter_1;
		std::wstring parameter_2;
		if(SingleString[0]!=L'.')
		{
		while(index<SingleString.size()&&SingleString[index]!=L'.')
		{
			parameter_1+=SingleString[index];
			index++;
		}
		for(int i=0;i<1;i++)
		{
			index++;
			if (index>SingleString.size()||SingleString[index]!=L'.')
			{
				QMessageBox::information(NULL, "DESpot","Error:Not enough ... to match");
				return false;	
				//throw EX("Error:Not enough ... to match");
			}
		}
		while(index<SingleString.size()-1)
		{
			index++;
			parameter_2+=SingleString[index];
		}
		if(getParameterType(parameter_1)==eWrongType||getParameterType(parameter_2)==eWrongType)
		{
			return false;
		}
		if(getParameterType(parameter_1)!=getParameterType(parameter_2))
		{
			QMessageBox::information(NULL, "DESpot","Error: can only use '..' with only numbers or only letters.");	
			return false;		
			//throw EX("Error:Not match dot parameter type");
		}
		
		switch(getParameterType(parameter_1))
		{
		case eNumber:
			if(!generateFromNumber(parameters,convertChartoNumber(parameter_1),convertChartoNumber(parameter_2)))
			{
				return false;
			}
			return true;
			//break;
		case eLAlphabet:
			if(!generateFromAlphabet(parameters,parameter_1.c_str()[0],parameter_2.c_str()[0]))
			{
				return false;
			}
			return true;
			//break;
		case eUAlphabet:
			if(!generateFromAlphabet(parameters,parameter_1.c_str()[0],parameter_2.c_str()[0]))
			{
				return false;
			}
			return true;
			//break;
		default:
			return false;
		}
		}
		else
		{
			QMessageBox::information(NULL, "DESpot","Error:the first input could not be dot.");
			return false;
			//throw EX("Error:the first input could not be dot.");
		}


	}
	
	InstantiateTemplate::RangeType InstantiateTemplate::getParameterType(std::wstring& parameter)	
	{
	
		wchar_t temp=(parameter.c_str())[0];
		if(temp>=L'a'&&temp<=L'z')
		{
			if(parameter.size()>1)
			{
				QMessageBox::information(NULL, "DESpot","Error: can only use '..'with numbers and single letters.");
				return eWrongType;
			}
			return eLAlphabet;
		}
		if(temp>=L'A'&&temp<=L'Z')
		{
			if(parameter.size()>1)
			{
				QMessageBox::information(NULL, "DESpot","Error: can only use '..'with numbers and single letters.");
				return eWrongType;
			}
			return eUAlphabet;
		}
		if(allNumber(parameter))
		{
			convertChartoNumber(parameter);
			return eNumber;
		}
		else
		{
			QMessageBox::information(NULL, "DESpot","Error:Range can not contain both number and alphabet.");
			return eWrongType;
		}
		
		

	}



	bool InstantiateTemplate::generateFromNumber( Parameters&  parameter,int start,int end )
	{

		if(start>end)
		{
			QMessageBox::information(NULL, "DESpot","Error:Start is larger than end");
			return false;
			//throw EX("Error:Start is larger than end");
		}
		while(start<=end)
		{
			std::wstringstream ws;
			ws<<start;
				parameter.push_back(ws.str());
			start++;
		}
		return true;
	}

	bool InstantiateTemplate::generateFromAlphabet( Parameters&  parameter,wchar_t start,wchar_t end )
	{
		if(start>end)
		{
			QMessageBox::information(NULL, "DESpot","Error:Start is larger than end");
			//throw EX("Error:Start is larger than end");
			return false;
		}
		while(start<=end)
		{
			std::wstringstream ws;
			ws<<start;
				parameter.push_back(ws.str());
			start++;
		}
			return true;
	}

	bool InstantiateTemplate::matchbracket()

	{
		return true;
	}

	int  InstantiateTemplate::countDot(const std::wstring& name)
	{		
		int dotcount=0;
		for(int index=0;index<name.size();index++)
		{
			if(name[index]==L'.')
			{
				dotcount++;
			}

		}
		return dotcount;
	}
	
	int InstantiateTemplate::countParameters()
	{
		int countparameter=0;
		TemplateNameParser::TemplateParameter* count_parameter=new TemplateNameParser::TemplateParameter;
		count_parameter=TemplateNameParser::getVariablesFromName(m_TemplateDes.getName());
		TemplateNameParser::TemplateParameterItr count_iterator=count_parameters->begin();
		countparameter++;
		while(count_iterator!=count_parameters->end())
		{	
			countparameter++;
			count_iterator++;
		}
		return countparameter;
	}


	int InstantiateTemplate::convertChartoNumber(const std::wstring& input_char)
	{
		int result;
		std::wstringstream input_stream(input_char);
		input_stream>>result;
		return result;
	}

	bool InstantiateTemplate::allNumber(const std::wstring& input_char)
	{
		wchar_t char0=L'0';
		wchar_t char9=L'9';
		for(int i=0;i<input_char.size();i++)
		{
			if(input_char[i]<char0&&input_char[i]>char9)
			{
				//throw EX("Error:Not support...");
				return false;
			}
		}
		
		return true;

	}

	std::wstring*  InstantiateTemplate::getNameFromInstantiatedTemplate( const std::wstring& name,TemplateNameParser:: TemplateParameter instantiation)
	{
		std::wstring* result=new std::wstring(name);

		TemplateNameParser::TemplateParameterCItr itr=instantiation.begin();
		while(itr!=instantiation.end())
		{
			Replace(*result,L'%'+itr->first+L'%',itr->second);
			itr++;
		}
		return result;
	}

	void  InstantiateTemplate::Replace(std::wstring& oriStr,const std::wstring& oldStr,const std::wstring& newStr )
	{
		int pos = 0; 
		std::wstring::size_type newStrLen = newStr.length(); 
		std::wstring::size_type oldStrLen = oldStr.length(); 
		while(true) 
		{    
			pos = oriStr.find(oldStr, pos); 
			if (pos == std::wstring::npos) break; 

			oriStr.replace(pos, oldStrLen, newStr);         
			pos += newStrLen;

		}
	}

	TemplateNameParser::TemplateParameter* InstantiateTemplate::getParameter()
	{
		return m_parameters;
	}
	
	DESpot::DesLevel InstantiateTemplate::getLevel()
	{
		return m_deslevel;
	}

	InstantiateTemplate::DesArray*  InstantiateTemplate::generateDesFromTemplate( const Des* templateinput,const InstantiateTemplate::InstantiatedTemplate* IT )
	{
		DesArray* result=new DesArray;
		InstantiatedTemplateCItr itr=IT->begin();
		while(IT->end()!=itr)
		{
			result->push_back(const_cast<Des* const>(templateinput)->instantiateDesfromTemplate(&*itr));
			itr++;
		}
		return result;
	}

	void InstantiateTemplate::setRangeInput(std::wstring input)
	{
	
		m_RangeInput.push_back(input);

	}
	
	std::vector<std::wstring> InstantiateTemplate::getRangeInput()
	{
		return m_RangeInput;
	}

	void InstantiateTemplate::setTupleInput(std::wstring input)
	{
	
		m_TupleInput=input;

	}
	
	std::wstring InstantiateTemplate::getTupleInput()
	{
		return m_TupleInput;
	}
	/*void InstantiateTemplate::setInstInfoMap(ProjectEditor::InstInfoMap_Vector* instinfomap_vector)
	{
		m_InstInfoMap_Vector=instinfomap_vector;
	}
	
	ProjectEditor::InstInfoMap_Vector* InstantiateTemplate::getInstInfoMap_Vector()
	{
		return m_InstInfoMap_Vector;
	}*/
	bool InstantiateTemplate::checkRangeInput(std::wstring input)
	{
		
		if(!m_rangeInputNameValidator.validate(input))
		{
			QMessageBox::information(NULL, "DESpot","Error: Use an alpha-numeric string (a-z;A-Z;0-9;.-_");
			return false;
		}
		Parameters* separateParameter=new InstantiateTemplate::Parameters;
		Parameters* temp=splitComma(input);
		ParametersItr iterator=temp->begin();
		while(iterator!=temp->end())
		{
			if(countDot(*iterator)==0)
			{
				separateParameter->push_back(*iterator);
			}
			else if(countDot(*iterator)==2)
			{	
				if(!generateFromRange(*separateParameter,*iterator))
				{
					return false;
				}		
			}
			else 
			{
				QMessageBox::information(NULL, "DESpot","too much '.' in range format");
				return false;
					//break;
			}
			iterator++;
		}	
		return true;
	}
		




}
