/*------------------------------------------------------------------------------*
 * File Name: FunctionFormulaDlg.h	 											*
 * Creation: Kyle 11-10-2009													*
 * Purpose: OriginC Header H file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/

#ifndef _SIMULATE_CURVE_DLG_H__
#define _SIMULATE_CURVE_DLG_H__

#include "SetValuesCommon.h"

//////////////////////////////////////////////////////////////////////////////////////////////////

class CurvePreviewGraphControl : public GraphPageControl
{
public:
	CurvePreviewGraphControl(DWORD dwCtrl = 0) : GraphPageControl(dwCtrl)
	{
	}
	bool	Init(Control& ctrl)
	{
		if ( !ctrl )
			return false;
		
		GraphControl gCtrl;
		DWORD dwNoClicks = NOCLICK_DATA_PLOT | NOCLICK_TICKLABEL | NOCLICK_LAYER | NOCLICK_LAYERICON | NOCLICK_AXES | NOCLICK_LABEL | NOCLICK_BUTTONS;
		gCtrl.CreateControl(ctrl.GetSafeHwnd());
		if ( gCtrl )
		{
			Create(gCtrl, dwNoClicks, "NonePreview");
			return true;
		}
		return false;
	}
};

typedef	bool	(*PFN_MATH_EQU_FONTS)();
typedef	bool	(*PFN_GET_PREVIEW_IMAGE)(TreeNode &trPicts, const string& strFDFname, const string &strFuncName, bool bFormula = true);

class CurvePreviewImageControl : public ResizeControl
{
public:
	CurvePreviewImageControl() : ResizeControl()
	{
		m_bViewFirstTime = true;
	}
	
	bool	Init(Control& ctrl)
	{
		if ( !ctrl )
			return false;
		
		m_picPreview.CreateControl(ctrl.GetSafeHwnd());
		SetVisible(false);
		
		return true;
	}
	
	bool	LoadFunctionPreview(LPCSTR lpcszFuncName, bool bFormula)
	{
		PFN_MATH_EQU_FONTS pfn_init_math_equ_fonts = Project.FindFunction("nlf_init_math_equ_fonts", "Originlab\\nlsf_utils.c", TRUE); //force compile nlsf_utils.c
		PFN_GET_PREVIEW_IMAGE pfn_get_preview_image = Project.FindFunction("nlf_get_preview_image", "Originlab\\nlsf_utils.c", TRUE);
		
		if ( m_bViewFirstTime && pfn_init_math_equ_fonts != NULL )
		{
			m_bViewFirstTime = false;
			pfn_init_math_equ_fonts();
		}
		
		string strFuncName(lpcszFuncName);
		string strFileFullName;
		nlf_get_fdf_filename(lpcszFuncName, NULL, NULL, &strFileFullName);
		
		//load preview image
		Tree trPict;
		trPict.Pict.ID = 1;
		
		if ( pfn_get_preview_image && !pfn_get_preview_image(trPict.Pict, GetFileName(strFileFullName, true), strFuncName, bFormula) )
			LoadUserDefinedPreview(trPict.Pict, strFileFullName, bFormula);
		
		//set picture
		PictureHolder picHolder;
		picHolder = trPict.Pict.pict;
		if ( m_picPreview.SetPicture(picHolder) )
		{
			m_picPreview.KeepAspectRatio = true;
			return true;
		}
		return false;
		
	}
	
	bool	LoadUserDefinedPreview(TreeNode& trPict, LPCSTR lpcszFDFName, bool bFormula)
	{
		string strMeta = GetFilePath(lpcszFDFName) + GetFileName(lpcszFDFName, true);
		if ( bFormula )
			strMeta += ".wmf";
		else
			strMeta += ".cuv";
		if ( strMeta.IsFile() )
		{
			HMETAFILE hmf = NULL;
			RECT16 rect;
			hmf = load_metafile(strMeta, &rect);
			PictureHolder picHolder;
			if ( hmf && picHolder.CreateFromMetafile(hmf, (int)(rect.right - rect.left), (int)(rect.bottom - rect.top), true) )
			{
				trPict.pict = picHolder;
				return true;
			}
		}
		return false;
	}
protected:
	PictureControl	m_picPreview;
	bool			m_bViewFirstTime;
};

class InsertFormulaHelper
{
public:
	//keep current selection
	InsertFormulaHelper(const SetValContext& stContext)
	{
		int nPageType = stContext.nPageType;
		m_nObjUID = stContext.nObjUID;
		if ( nPageType == EXIST_WKS )
		{
			Column colObj;
			colObj = (Column)Project.GetObject(stContext.nObjUID);
			if ( colObj )
			{
				Worksheet wks;
				colObj.GetParent(wks);
				int nC1, nC2;
				wks.GetSelectedRange(m_nR1, nC1, m_nR2, nC2);
			}
			else
			{
				ASSERT(FALSE);
			}
		}
	}
	//restore selection
	~InsertFormulaHelper()
	{
		DataObject obj;
		obj = (DataObject)Project.GetObject(m_nObjUID);
		if ( obj )
		{
			obj.CheckShowActivate();
			Worksheet wks;
			obj.GetParent(wks);
			if ( wks ) //if open from worksheet
			{
				Column colObj(obj);
				int nColIndex = colObj.GetIndex();
				vector<int> vnC1(1), vnC2(1), vnR1(1), vnR2(1);
				vnC1[0] = nColIndex;
				vnC2[0] = nColIndex;
				vnR1[0] = m_nR1;
				vnR2[0] = m_nR2;
				wks.SetSelectedRange(vnR1, vnC1, vnR2, vnC2);
				
				//SCV dialog should ignore this message: selection changed required by restoring selection information
				okutil_dialog_event_special_bits_access(DIALOGEVENTSPECIALBITSOPTIONS_SET, DIALOGEVENTSPECIALBITS_SELECTION_CHANGE_TEMPORARY);
			}
		}
		else
		{
			ASSERT(FALSE);
		}
	}
private:
	UINT	m_nObjUID;
	int		m_nR1, m_nR2;
};

class FunctionFormulaDlg : public DynaDlg
{
public:
	FunctionFormulaDlg(const FunctionInfo& funcInfo, const SetValContext& stContext);

public:
	int		DoModalEx(HWND hParent = NULL);
	BOOL	GetResult(string& strFormula);
	
protected:

EVENTS_BEGIN
	ON_INIT(OnInitDialog) 
	ON_DESTROY(OnDestroy)
	ON_SIZE(OnDlgResize)
	ON_OK(OnClickOK)
	ON_CANCEL(OnClickCancel)
	ON_BN_CLICKED(IDC_SHOW_BOTTOM, OnShowBottomPane)
	ON_TAB_SEL_CHANGE(IDC_GRAPH_TAB, OnBottomTabChange)
	ON_GETNDLG_MSGS(IDC_GRID)
	ON_USER_MSG(WM_USER_TREEEDITOR_VALUE_CHANGE, OnAfterValueChange)
	ON_INIT_SIZE(OnInitSize)
	ON_CHANGE_SELECTION(OnSelectionChange)
	ON_CHANGE_LAYER(OnActiveLayerChange)
	ON_CHANGE_PAGE(OnActivePageChange)
	ON_IDLE(OnIdle)
	ON_DESTROY(OnDestroy)
	ON_RESTORESIZE(OnRestoreSize)
	ON_BN_CLICKED(IDC_GETN_PREVIEW_BTN, OnPreview)
	ON_BN_CLICKED(IDC_GETN_AUTO_PREVIEW_BTN, OnAutoPreview)
	ON_GETMINMAXINFO(OnMinMaxInfo)
EVENTS_END

	BOOL	OnInitDialog();
	BOOL	OnReady();
	BOOL	OnDlgResize(int nType, int cx, int cy);
	BOOL	OnDestroy();
	BOOL	OnClickOK();
	BOOL	OnClickCancel();
	BOOL	OnRestoreSize(DWORD dwSizeInfo);
	BOOL	OnShowBottomPane(Control ctrl);
	BOOL	OnBottomTabChange(Control ctrl);
	void	OnAfterValueChange(int nRow, int nCol);
	BOOL	OnPreview(Control cntrl);
	BOOL	OnAutoPreview(Control cntrl);
	BOOL	OnInitSize(int &left, int &top, int &right, int  &bottom);
	BOOL	OnSelectionChange();
	BOOL	OnIdle();
	BOOL	OnActiveLayerChange();
	BOOL	OnActivePageChange();
	int		GetTotalHeight(bool bMin = false);
	int		GetTotalWidth(bool bMin = false);

protected:
	void	SetDialogTitle(LPCSTR lpcszTitle);
	
protected:
	bool	SetInput();
	bool	InitGUI();
	void	InitPreviewTabs();
	bool	UpdatePreviewGraphs();
	bool	UpdateExpression();
	bool	UpdatePreviewCurve();
	bool	EvaluateParameter(LPCSTR lpcszParamValue, double& dVal);
	bool	EvaluateParameter(LPCSTR lpcszParamValue, vector& vVals);
	void	UpdateParameter(LPCSTR lpcszParam, string& strNewParamVal);
	void	CheckEnablePreview();

protected:
	
	TreeNode		m_trGUI;
	FunctionInfo	m_FuncInfo;
	SetValContext	m_Context;
	vector			m_vX, m_vY;
	Worksheet		m_wksPreview; //temporary worksheet to put data
	CurvePreviewImageControl	m_SampleCurvePreview;
	CurvePreviewImageControl	m_FormulaPreview;
	CurvePreviewGraphControl	m_CurCurvePreview;
	DWORD			m_dwCtrl;
	TabControl			m_tabCtrl;
	
	
private:
	void	updatePreviewButton(BOOL bEnable);
	uint	getTabGraphControlID(int nTab);

	void	initDlgControls();
	bool 	getInputRange(XYRange& dr);
	
	void 	resizeTopPaneControl();
	void	resizeBottomPaneControl();
	
};

#endif //_SIMULATE_CURVE_DLG_H__
