#pragma once
#include <QDialog>
#include <QObject>
#include <QTableWidget>
#include <QMessageBox>
#include "ui_InstantiateTemplate.h"
#include "Des.h"
//#include "TemplateNameParser.h"
#include "DesTypes.h"
#include "NameValidator.h"
#include <map>
#include <vector>
#include "ProjectEditor.h"


namespace DESpot
{
	class TemplateNameParser;
	class InstantiateTemplate: public QDialog, public Ui::InstantiateTemplate
	{
	      Q_OBJECT
	
	public:	typedef std::vector<std::wstring> Parameters;
		typedef Parameters::const_iterator ParametersCItr;
		typedef Parameters::iterator ParametersItr;
		typedef std::vector<Des*> DesArray;
		typedef DesArray::iterator DesArrayItr;
		typedef DesArray::const_iterator DesArrayCItr;
		typedef std::vector<TemplateNameParser::TemplateParameter> InstantiatedTemplate;
		typedef InstantiatedTemplate::iterator InstantiatedTemplateItr;
		typedef InstantiatedTemplate::const_iterator InstantiatedTemplateCItr;
//FOR RANGE		
		typedef std::map<InstantiateTemplate::Parameters,InstantiateTemplate::Parameters> TemplateParameter_2;
		typedef TemplateParameter_2::const_iterator ParametersCItr_2;
		typedef TemplateParameter_2::iterator ParametersItr_2;
		typedef std::vector<InstantiateTemplate::TemplateParameter_2> InstantiatedTemplate_2;
		typedef InstantiatedTemplate_2::iterator InstantiatedTemplateItr_2;
		typedef InstantiatedTemplate_2::const_iterator InstantiatedTemplateCItr_2;


	public:
		InstantiateTemplate(const Des& templateDes,QWidget* parent = null);
		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=null);
		~InstantiateTemplate(void);
		const Des& m_TemplateDes;
		std::wstring InstInfoDlgName;
		std::vector<std::wstring> m_RangeInput;
		std::wstring m_TupleInput;
		int countBracket;
		static std::wstring* getNameFromInstantiatedTemplate( const std::wstring& name,TemplateNameParser:: TemplateParameter instantiation);
		TemplateNameParser::TemplateParameter* getParameter();
		DesLevel getLevel();
		static InstantiateTemplate::DesArray* generateDesFromTemplate( const Des* templateinput,const InstantiateTemplate::InstantiatedTemplate* IT );

		static InstantiateTemplate::InstantiatedTemplate* generateTemplateParameterFromTemplate(TemplateNameParser::TemplateParameter Template );
		static InstantiateTemplate::InstantiatedTemplate* generateTemplateParameterFromTuple(TemplateNameParser::TemplateParameter Template );

		//static bool validateParametersName(const TemplateNameParser::TemplateParameter& parameters);
		/*enum InputType
		{
			eRange,
			eTuple
		};*/
		static InputType getInputType();
		static InputType m_Option;
		std::wstring getInstantiationName() const;
		std::vector<std::wstring> getRangeInput();
		std::wstring getTupleInput();
		void setRangeInput(std::wstring input);
		void setTupleInput(std::wstring input);
		bool checkRangeInput(std::wstring input);
		/*void setInstInfoMap(InstInfoMap_Vector* instinfomap_vector);
		InstInfoMap_Vector* getInstInfoMap_Vector();*/
		static void Replace(std::wstring& oriStr,const std::wstring& oldStr,const std::wstring& newStr);
		static bool parserTupleValueToArray(std::wstring value, std::vector<std::wstring> &vTupleArray);
		static bool parserOneTupleValueToArray(std::wstring value, std::vector<std::wstring> &vTupleArray);
		static void parserTemplateToArray(std::wstring value, std::vector<std::wstring> &vArray);
	protected:
		 void accept();
		 void reject();
		
	private:
		void GenerateTableforRange();
		void LoadTableforRange(TemplateNameParser::TemplateParameter* parameter,std::vector<std::wstring> rangeinput);
		void LoadTableforTuple(TemplateNameParser::TemplateParameter* parameter,std::wstring tupleinput);
		void GenerateTableforTuple();
		bool CheckLevel();
		bool CheckInputOption();
		
		DesLevel m_deslevel;
		static std::wstring instantiationname;
		//static std::wstring m_RangeInput;
		//static std::wstring m_TupleInput;
		
		TemplateNameParser::TemplateParameter* m_parameters;
		TemplateNameParser::TemplateParameter* n_parameters;
		TemplateNameParser::TemplateParameter* count_parameters;
		enum RangeType
		{
			eNumber,
			eUAlphabet,
			eLAlphabet,
			eWrongType
		};
		void setupConnections();
		bool validInstantiateActName(const std::wstring& name);
		bool extractInputforRange();
		bool extractInputforTuple();
		static bool doCheck(wchar_t ch);
		//check if the user give the right range format to the parameters
		static NameValidator m_rangeInputNameValidator;
		//check if the user give the right range format to the parameters
		static NameValidator m_tupleInputNameValidator;
		static NameValidator m_InstantiateActNameValidator;
		static NameValidator m_tuplevalueNameValidator;
		static bool matchDot(const std::wstring& name);
		
		static bool matchbracket();
		//const TemplateNameParser::TemplateParameter& parameters;
		//TemplateNameParser::TemplateParameterCItr citerator;
		static int countDot(const std::wstring& name);
		int countParameters();
		static InstantiateTemplate::Parameters* getSingleParameters(const std::wstring& name);
		static InstantiateTemplate::Parameters* splitComma(const std::wstring& name);
		static InstantiateTemplate::Parameters* splitBracket(const std::wstring& name);
		static bool generateFromRange(InstantiateTemplate::Parameters& parameters,std::wstring& SingleString);
		static RangeType getParameterType(std::wstring& parameter);
		
		static int convertChartoNumber(const std::wstring& input_char);
		static bool allNumber(const std::wstring& input_char);
		static bool generateFromNumber(Parameters& parameter,int start,int end);
		static bool generateFromAlphabet(Parameters& parameter,wchar_t start,wchar_t end);
		
	public slots:
		void onHideTuple();
		void onHideRange();
		void onChangeType_1();
		void onChangeType_2();
	

	};
}	
