/*------------------------------------------------------------------------------*
 * File Name:WksListControl.h													*
 * Creation: CPY 6/28/2003														*
 * Purpose: OriginC Class for managing list of worksheets. This class is used in*
 * the Select Columns for Plotting dialog										*
 * Copyright (c) Originlab Corp. 2003, 2004, 2005, 2006, 						*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	CPY 8/21/03 QA70-5034 COL_WKS_CONTEXT_MENU_IMPROVEMENT						*
 *	CPY 9/8/03 v7.5688 WKS_MAT_SEL_CHECK_CONSISTENT								*
 *	CPY 10/26/03 AUTO_SEL_LAST_ACTIVE_WKS_MATRIX								*
 *------------------------------------------------------------------------------*/

#ifndef _WKS_LIST_CONTORL_H
#define _WKS_LIST_CONTORL_H
////////////////////////////////////////////////////////
// class WksListControl - Available Data List (AD)    
////////////////////////////////////////////////////////
// supported col types


enum {DATACOMBO_CURRENT, DATACOMBO_FOLDER, DATACOMBO_PROJECT, DATACOMBO_MAT_FOLDER, DATACOMBO_MAT_PROJECT, DATACOMBO_LOOSEDATA, DATACOMBO_FUNCTIONS};
enum {WLCMENU_HIDE, WLCMENU_SHOW_ALL, WLCMENU_SEPARATOR, WLCMENU_APPLY_DESIGNATIONS, WLCMENU_SEPARATOR1, WLCMENU_INCREASE_SIZE, WLCMENU_DECREASE_SIZE};


class AvailDataList : public ComboBox
{
private:
	//bool	m_bIncludeMatrices; this is no longer an option, too complicated
public:
	AvailDataList()
	{
		m_nPageTypeChoice = -1;
	}
		
	Init(bool bIncludeMatrices)
	{
		//m_bIncludeMatrices = bIncludeMatrices;
		AddString(_L("Current Worksheet"));
		AddString(_L("Worksheets in Folder"));
		AddString(_L("Worksheets in Project"));
		//if(m_bIncludeMatrices)
		//{
			AddString(_L("Matrices in Folder"));
			AddString(_L("Matrices in Project"));
		//}
		AddString(_L("Loose Datasets"));
		AddString(_L("Function Plots"));
		
		//-------- CPY 8/21/03 QA70-5034 COL_WKS_CONTEXT_MENU_IMPROVEMENT
		//SetCurSel(DATACOMBO_PROJECT);
		//--------
	}
	int	GetSelectedPageType()
	{
		return comboIndexToPageType(GetCurSel());
	}
	// return true if sel has been changed
	bool SelectByPageType(int nPageType)
	{
		int nIndex = pageTypeToComboIndex(nPageType);
		if(nIndex == m_nPageTypeChoice)
			return false;
		SetCurSel(nIndex);
		return true;
	}
	int GetCurSel()
	{
		m_nPageTypeChoice = ComboBox::GetCurSel();
		/*
		if(m_nPageTypeChoice > DATACOMBO_PROJECT)
		{
			if(!m_bIncludeMatrices)
				return DATACOMBO_LOOSEDATA;
		}
		*/
		return m_nPageTypeChoice;
	}
private:
	int comboIndexToPageType(int nComboIndex)
	{
		if(nComboIndex > DATACOMBO_PROJECT)
		{
			//if(m_bIncludeMatrices && m_nPageTypeChoice < DATACOMBO_LOOSEDATA )
			if(nComboIndex < DATACOMBO_LOOSEDATA )
				return EXIST_MATRIX;
			if(nComboIndex > DATACOMBO_LOOSEDATA)
				return EXIST_FUNC_PLOT;
			
			return EXIST_DATA;
		}
		return EXIST_WKS;
	}
	int pageTypeToComboIndex(int nPageType)
	{
		switch(nPageType)
		{
		case EXIST_WKS:
		case EXIST_EXTERN_WKS:
			return DATACOMBO_PROJECT;
		case EXIST_MATRIX:
			return DATACOMBO_MAT_PROJECT;
		case EXIST_FUNC_PLOT:
			return DATACOMBO_FUNCTIONS;
		}
		return DATACOMBO_LOOSEDATA;
	}
private:
	int	m_nPageTypeChoice;
};

enum {WKSPAGE_NAME, WKSPAGE_LABEL, WKSPAGE_N_COLS, WKSPAGE_N_ROWS, WKSPAGE_FILEPATH, WKSPAGE_FILENAME, WKSPAGE_FILEDATE, WKSPAGE_PATH, WKSPAGE_CREATED, WKSPAGE_MODIFIED, WKSPAGE_TOTAL_COLS};
	
class WksListControl : public GridListControl
{
	WksListControl()
	{
		// must match enum {WKSPAGE_NAME, WKSPAGE_LABEL,
		GetFormatStrAsArray("Name|Label|Cols|Rows|File Path|File Name|File Date|Folder|Created|Modified", m_vsColHeadings, _CAT);
	}
	
public:
	void Init(int nID, Dialog& dlg, bool bMakeNewPlot, const string& strRegDlgName, int nApplyWks, int nAvilDataCombo)
	{
		vector<byte> vbDefaultShowCols = {0,0,0,0,0,1,0,0};
		//m_comboAvailData = dlg.GetItem(nAvilDataCombo);
		//m_comboAvailData.SetCurSel(DATACOMBO_PROJECT);
		m_AvailData = dlg.GetItem(nAvilDataCombo);
		m_AvailData.Init(true);//bMakeNewPlot? false:true);
		
		GridListControl::Init(nID, dlg);
		// should init from registry, but hardcoded for now
//		vector<uint> vnColsTemp = {WKSPAGE_NAME, WKSPAGE_LABEL, WKSPAGE_N_COLS, WKSPAGE_FILEPATH, WKSPAGE_FILEDATE, WKSPAGE_PATH};  
//		m_vnCols = vnColsTemp;

		m_chkApplyWks = dlg.GetItem(nApplyWks);
		m_flx.Cols = WKSPAGE_TOTAL_COLS;
		m_flx.FormatString = makeColHeadings();
		m_flx.SelectionMode = flexSelectionListBox;
		m_flx.AllowSelection = true;
		m_flx.ExplorerBar = flexExSortShow;
		m_flx.Ellipsis = flexEllipsisPath;// if str too long, show ... in the middle
		LoadHideCols(strRegDlgName, "WksListCols", &vbDefaultShowCols);
//		updateList(bMakeNewPlot);
	}
	void OnReady(int nAvilDataType, bool bMakeNewPlot, DWORD dwAuxTypeInfo)
	{
		//-------- CPY 8/21/03 QA70-5034 COL_WKS_CONTEXT_MENU_IMPROVEMENT
		//updateList(bSelCurrentWks);
		if(nAvilDataType  < DATACOMBO_CURRENT || nAvilDataType > DATACOMBO_FUNCTIONS)
			nAvilDataType = DATACOMBO_PROJECT;
		
		bool bSelCurrentWks = checkAvailDataConsistentWithPlotType(nAvilDataType, bMakeNewPlot, dwAuxTypeInfo);
		
		m_AvailData.SetCurSel(nAvilDataType);
		int nSel = m_AvailData.GetCurSel();
		if(nSel > DATACOMBO_MAT_PROJECT)
			bSelCurrentWks = false;
		
		updateList(bSelCurrentWks);	
		//--------
	}
	void OnAvilableDataComboChange()
	{
		updateList(false);
	}
	int GetAvailableDataChoice() { return m_AvailData.GetCurSel();}
	int OnOK() // return Available Data choice
	{
		SaveHideCols();
		return GetAvailableDataChoice();
	}
	bool IsApplyWks()
	{
		return m_chkApplyWks.Check;
	}
	//virtual 
	string GetRuntimeClass()
	{
		return "WksListControl";
	}
	//virtual 
	int GetDefaultSize(){return 178;}
	//---- CPY 9/25/03 v7.5707 EDIT_PLOT_SHOW_HIGHLIGHT_IN_WKS_LIST
	void OnStartEdit(const vector<string>& vsWksDatasetNames, int nPageType)
	{
		m_AvailData.SelectByPageType(nPageType);
		updateList(false);
		// select all the given wks names
		//		m_flx.Col = m_nNameCol;
		//		m_flx.Row = FindRow(wkspg.GetName(), m_nNameCol);
		vector<int> vnRows;
		int nSel = -1;
		for(int ii = 0; ii < vsWksDatasetNames.GetSize(); ii++)
		{
			if((nSel = FindRow(vsWksDatasetNames[ii], m_nNameCol)) < 0)
			{
				printf("%d:%s not found\n", ii+1, vsWksDatasetNames[ii]);
			}
			else // OK
				vnRows.Add(nSel);
		}
		SelRows(vnRows);
		//printf("OnStartEdit has selected %d rows\n", vnRows.GetSize());
	}
	//---- end EDIT_PLOT_SHOW_HIGHLIGHT_IN_WKS_LIST
private:
	//----- CPY 9/8/03 v7.5688 WKS_MAT_SEL_CHECK_CONSISTENT
	// return true for selecting current wks/matrix window
	bool checkAvailDataConsistentWithPlotType(int& nAvilDataType, bool bMakeNewPlot, DWORD dwAuxTypeInfo)
	{
		DWORD dwLayerBits = dwAuxTypeInfo & MASK_PCD_LAYER_BITS;
		
		return true;
	}
	//----- end WKS_MAT_SEL_CHECK_CONSISTENT
	void updateList(bool bSelCurrent)
	{
		ClearAll();
		string str;
		int nSel = m_AvailData.GetCurSel();
		DWORD dwInfo = 0;// dataset
		int	nSelPageType = bSelCurrent? EXIST_WKS:EXIST_NONE;
		
		switch(nSel)
		{
		case DATACOMBO_PROJECT:
			foreach(WorksheetPage wkspg in Project.WorksheetPages)
				m_flx.AddItem(makeRow(wkspg));
			
			break;
		case DATACOMBO_FOLDER:
			foreach(PageBase page in Project.ActiveFolder().Pages)
			{
				WorksheetPage wkspg = page;
				if(wkspg)
					m_flx.AddItem(makeRow(wkspg));
			}
			break;
		case DATACOMBO_CURRENT:
			WorksheetPage wkspg = Project.Pages();
			if(wkspg)
				m_flx.AddItem(makeRow(wkspg));
			break;
		case DATACOMBO_MAT_PROJECT:
			nSelPageType = EXIST_MATRIX;
			foreach(MatrixPage mpg in Project.MatrixPages)
				m_flx.AddItem(makeRow(mpg));
			break;
		case DATACOMBO_MAT_FOLDER:
			nSelPageType = EXIST_MATRIX;
			foreach(PageBase page in Project.ActiveFolder().Pages)
			{
				MatrixPage mpg = page;
				if(mpg)
					m_flx.AddItem(makeRow(mpg));
			}
			break;
		case DATACOMBO_LOOSEDATA:
			nSelPageType = EXIST_DATA;
			foreach(string strName in Project.LooseDatasetNames)
			{
				dwInfo = Project.GetDatasetInfo(strName);
				if(dwInfo & PGDN_FUNCTION)
					continue;
				m_flx.AddItem(makeRow(strName));
			}
			break;
		case DATACOMBO_FUNCTIONS:
			nSelPageType = EXIST_DATA;
			foreach(string strName in Project.LooseDatasetNames)
			{
				dwInfo = Project.GetDatasetInfo(strName);
				if(!(dwInfo & PGDN_FUNCTION))
					continue;
				m_flx.AddItem(makeRow(strName));
			}
			break;
		default:
			out_str("Error, m_AvailData returns invalid choice");
			// not supported yet
			break;
		}
		
		ResizeCols(2, 2);
		
		m_nNameCol = 0; // need update later
		
		if(bSelCurrent)
		{
			string strName = getCurrentSelPageName(nSelPageType);
			
			if(!strName.IsEmpty())
			{
				m_flx.Col = m_nNameCol;
				m_flx.Row = FindRow(strName, m_nNameCol);
			}
		}
			
	}
	//------ CPY 10/26/03 AUTO_SEL_LAST_ACTIVE_WKS_MATRIX
	string getCurrentSelPageName(int nPageTypeToSel)
	{
		string strTemp;
		Page pg = Project.Pages();
		int	nActiveWinType = EXIST_NONE;

		if(pg)
		{
			nActiveWinType = pg.GetType();
			strTemp = pg.GetName();
		}		

		if(nActiveWinType != nPageTypeToSel)
			strTemp = getLastActivePageName(nPageTypeToSel);
		
		return strTemp;
	}
	string getLastActivePageName(int nPageType)
	{
		string strTemp;
		string strVar;
		if(EXIST_MATRIX == nPageType)
			strVar = "LastMatrix$";
		else if(EXIST_WKS == nPageType)
			strVar = "LastWks$";
		
		if(strVar.IsEmpty())
			return strTemp;// empty
		
		char	szBuffer[MAXLINE];
		LT_get_str(strVar, szBuffer, MAXLINE);
		strTemp = szBuffer;
		return strTemp;
	}
	//---- end AUTO_SEL_LAST_ACTIVE_WKS_MATRIX
	string makeColHeadings()
	{
		string str;
		int	nCols = m_vsColHeadings.GetSize();
		for(int ii = 0; ii < nCols; ii++)
		{
			str += m_vsColHeadings[ii];
			if(ii < nCols -1)
				str += "|";
		}
		return str;
	}
	string makeCol(Page pg, int nColType)
	{
		string strTemp;
		switch(nColType)
		{
		case WKSPAGE_NAME:
			return pg.GetName();
		case WKSPAGE_LABEL:
			return pg.Label;
		case WKSPAGE_PATH:
		{
			Folder fld = pg.GetFolder();
			if(fld)
				strTemp = fld.GetPath();
			return strTemp;
		}
		case WKSPAGE_N_COLS:
		{
			Datasheet wks = pg.Layers();
			if(wks)
				strTemp = wks.GetNumCols();
			return strTemp;
		}
		case WKSPAGE_N_ROWS:
		{
			Datasheet wks = pg.Layers();
			if(wks)
				strTemp = wks.GetNumRows();
			return strTemp;
		}			
		case WKSPAGE_MODIFIED:
		case WKSPAGE_CREATED:
			return getPageSystemInfo(pg, nColType);
		default:
			break;
		}
		return getPageImportInfo(pg, nColType);
			
	}
	string makeRow(const string& strDatasetname)
	{
		return strDatasetname;
	}
	string makeRow(Page wkspg)
	{
		string	str;// = wkspg.GetName() + "\t" + wkspg.Label;
		int	nCols = m_vsColHeadings.GetSize();
		for(int ii = 0; ii < nCols; ii++)
		{
			str += makeCol(wkspg, ii);
			if(ii < nCols -1)
				str += "\t";
		}
		return str;
	}
	string getPageImportInfo(Page wkspg, int nType)
	{
		string str;
		storage st;
		st = wkspg.GetStorage("System");
		if(st)
		{
			Tree trTemp;
			if(st.GetSection("Import", trTemp) && trTemp.FilePath.IsValid())
			{
				switch(nType)
				{
				case WKSPAGE_FILEPATH:
					str = GetFilePath(trTemp.FilePath.strVal);
					break;
				case WKSPAGE_FILENAME:
					str = trTemp.FileName.strVal;
					break;
				case WKSPAGE_FILEDATE:
					if(trTemp.FileDate.IsValid()) // this was added later, so need to check, the other two added together
					{
						double dateVal = trTemp.FileDate.dVal;
						str = get_date_str(dateVal, LDF_SHORT);
					}
					break;
				}
			}
		}
		return str;
	}
	string 	getPageSystemInfo(Page pg, int nType)
	{
		string str;
		PageSystemInfo	PgInfo;
		pg.GetPageSystemInfo(&PgInfo);
		switch(nType)
		{
		case WKSPAGE_MODIFIED:
			str = get_date_str(PgInfo.dModified);
			break;
		case WKSPAGE_CREATED:
			str = get_date_str(PgInfo.dCreated);
			break;			
		}
		return str;
	}

protected:
	//virtual
	void ClearAll()
	{
		GridListControl::ClearAll();
	}
public:
	// return page type, EXIST_*
	int OnSelChange(ColListControl& listCols)
	{
		vector<string> vsWksNames;
		int nPageType = m_AvailData.GetSelectedPageType();
		if(GetSelItems(m_nNameCol, vsWksNames)) // assume
		{
			//int nTest = m_AvailData.GetSelectedPageType();
			listCols.UpdateList(vsWksNames, IsApplyWks(), nPageType);
			Page pg(vsWksNames[0]);
			if(pg)
				return pg.GetType();
		}
		return nPageType;
	}
	int GetCurrentPageType() // EXIST_
	{
		return m_AvailData.GetSelectedPageType();
	}
	void OnBeforeMouseDown(ColListControl& listCols, short nButton, short nShift, float X, float Y, BOOL* pCancel) // listCols arg not used for now, maybe needed later
	{
		int nRow = m_flx.MouseRow;
		int nCol = m_flx.MouseCol;
		if(MK_RBUTTON == nButton && 0 == nShift)//&& nCol >= 0 && 0== nRow)
		{
			int nx = XTwipsToPixels(X);
			int ny = YTwipsToPixels(Y);
			ClientToScreen(nx, ny);
			//printf("nx = %d, ny = %d\n", nx, ny);
			WksListControlMenu	myMenu(this, IsInGrid(nRow, nCol));
			myMenu.TrackPopupMenu(0,  nx, ny, GetDlgSafeHwnd());
			int nCmd;
			if(myMenu.GetCommand(nCmd))
			{
				switch(nCmd)
				{
				case WLCMENU_HIDE:
					HideCol(nCol);
					break;
				case WLCMENU_SHOW_ALL:
					HideCol(-1, false);
					break;
				case WLCMENU_APPLY_DESIGNATIONS:
					m_chkApplyWks.Check = m_chkApplyWks.Check? false:true;
					break;
				case WLCMENU_INCREASE_SIZE:
					PostDlgMessage(WM_USER_RESIZE_CONTROLS, 0 , LPARAM_RESIZE_CONTROLS_INCREASE);
					break;
				case WLCMENU_DECREASE_SIZE:
					PostDlgMessage(WM_USER_RESIZE_CONTROLS, 0 , LPARAM_RESIZE_CONTROLS_DECREASE);
					break;					
				}
			}
			return;
		}
	}
private:
	int				m_nNameCol;
	vector<string>	m_vsColHeadings;
	Button			m_chkApplyWks;
	//ComboBox		m_comboAvailData;
	AvailDataList	m_AvailData;
};



//------ CPY 8/21/03 QA70-5034 COL_WKS_CONTEXT_MENU_IMPROVEMENT
// moved to after WksListControl and add Auto Apply Designations
class WksListControlMenu : public Menu
{
public:
	WksListControlMenu(WksListControl* pWLcntrl, bool bIsInGrid)
	{
		UINT nFlags = bIsInGrid? MF_ENABLED : MF_DISABLED | MF_GRAYED;
		m_nChoice = -1;
		Add(_L("Hide Column"), OnMenuItem, nFlags);
		Add(_L("Show all Columns"), OnMenuItem);
		Add(NULL, OnMenuItem);
		nFlags = pWLcntrl->IsApplyWks()?MF_CHECKED : MF_UNCHECKED;
		Add(_L("Auto Apply Designations"), OnMenuItem, nFlags);
		Add(NULL, OnMenuItem);
		Add(STR_INCREASE_HEIGHT, OnMenuItem);
		Add(STR_DECREASE_HEIGHT, OnMenuItem);		
	}
	void OnMenuItem(UINT nPos)
	{
		m_nChoice = nPos;
	}
	bool GetCommand(int& nChoice)
	{
		if(m_nChoice >= WLCMENU_HIDE && m_nChoice <= WLCMENU_DECREASE_SIZE)
		{
			nChoice = m_nChoice;
			return true;
		}
		return false;
	}
private:
	int	m_nChoice;
};
//-----

#endif //_WKS_LIST_CONTORL_H



