/*------------------------------------------------------------------------------*
 * File Name:				 													*
 * Creation: 																	*
 * Purpose: OriginC Source C file												*
 * Copyright (c) ABCD Corp.	2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010		*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *	AW 10/08/05 MOVE_PROGRESSBAR_TO_VC_LEVEL									*
 *	DSC 10/11/2005 QA70-8167 FIND_FILES_FROM_SPECIFIED_LOCATION					*
 *------------------------------------------------------------------------------*/
 
////////////////////////////////////////////////////////////////////////////////////
// Including the system header file Origin.h should be sufficient for most Origin
// applications and is recommended. Origin.h includes many of the most common system
// header files and is automatically pre-compiled when Origin runs the first time.
// Programs including Origin.h subsequently compile much more quickly as long as
// the size and number of other included header files is minimized. All NAG header
// files are now included in Origin.h and no longer need be separately included.
//
// Right-click on the line below and select 'Open "Origin.h"' to open the Origin.h
// system header file.
#include <Origin.h>
#define BASE_WINDOW MultiPaneDlg
#include "DialogEx.h"
#include "TreeEditEvents.h"
#include "XFunctionEx.h"
#include "OCHttpUtils.h"
#include "TXdefines.h"


#define  STR_FILE_LIST_NAME 		"FileName"
#define STR_DOWNLOAD_ADDRESS_TEMP	"/fileexchange/details.aspx?fname="

#define FILE_CATEGORY_XF 		0x01
#define FILE_CATEGORY_FDF 		0x02
#define FILE_CATEGORY_HELP		0x04
#define FILE_CATEGORY_MODULE	0x08
#define FILE_CATEGORY_PATCH		0x10
#define FILE_CATEGORY_OTHER		0x20

/// AW 10/13/05 ADD_SUPPORT_FOR_DIFF_WEBSITE_ADDRESS
#define WEBSITE_URL				"http://207.180.39.140"      // new testing website 
//#define WEBSITE_URL				"http://10.10.10.21"      // inside office 
//#define WEBSITE_URL			"http://207.180.39.180"   // for out of Office
//#define WEBSITE_URL			"http://www.originlab.com" // for release
/// END ADD_SUPPORT_FOR_DIFF_WEBSITE_ADDRESS

int SelectUpdating(TreeNode& trOptions, vector<string>& m_vsServerFileName, vector<string>& m_vsLocalFileName, DWORD& nTotalSize);

class CheckForUpdateWindow;
static CheckForUpdateWindow *s_pCheckForUpdatedlg = NULL;
static int s_nCounter=0;

enum
{
	CHKS_HTTP_CHECK = 1,
	CHKS_SET_DOWNLOAD,
	CHKS_HTTP_DOWNLOAD,
	CHK_RESET_DOWNLOAD
};

class CheckForUpdateWindow : public TreeEditDlg   
{
public:
	CheckForUpdateWindow(BOOL bDeleteOnDestroy = FALSE, DWORD dwOption = 0, LPCSTR lpszExt = NULL) : TreeEditDlg(IDD_CHK_FOR_UPDATES, "ODlg8" )
	{
		m_bDeleteOnDestroy = bDeleteOnDestroy;
		s_nCounter = 0;
		m_dwOption = dwOption;
		m_nStage = CHKS_HTTP_CHECK;//CHKS_SET_DOWNLOAD;//;
		m_strMsg = "Check website to get downlaodable list";
		m_bCheck = FALSE;
		try
		{
			m_TestCheckUpdates = CreateObject("OSoap.OCheckForUpdates");
		}
		catch(int nError)
		{
		}
		if( NULL == m_TestCheckUpdates )
			MessageBox(NULL, "Can't initialize OSoap COM!!!", "Error");				

		m_strSavedFilePath = okutil_get_origin_path(ORIGIN_PATH_USER);
		m_strMsg = "Connect server, please wait...";
		m_strExt = lpszExt;
		//m_vsBadFileName.SetSize(0);
		
	}
protected:
	BOOL	m_bDeleteOnDestroy, m_bCheck;
	DWORD	m_dwOption;
	int		m_nStage;
//	int 	m_nTimerID;	/// AW 10/08/05 MOVE_PROGRESSBAR_TO_VC_LEVEL
	int 	m_nHttpJobIndex;
	int 	m_dwCntrl;
	int 	m_nMin, m_nMax;
	string	m_strMsg, m_strExt;
	string	m_strResult;
	string 	m_strLanguageType;
	string  m_strSavedFilePath;
	vector<string> m_vsServerFileName, m_vsLocalFileName, m_vsBadFileName;
	Tree	m_trResult;
//	Control m_ctrlProgress;	/// AW 10/08/05 MOVE_PROGRESSBAR_TO_VC_LEVEL
	Object 	m_txText;
	Object  m_TestCheckUpdates;
	
	/// AW 11/01/05 MOVE_KEYBOARD_HANDLE_TO_CLASS
	TXKeyboardHandle	m_myKeyboard;
	/// END MOVE_KEYBOARD_HANDLE_TO_CLASS

	
public:
	DWORD	DoModalEx(HWND hParent)
	{
		InitMsgMap();// will be called from internal later
		int nRet = DoModal(hParent);
		if(IDOK == nRet)
		{
			return 1;
		}
		return 0;
	}
	virtual int  Create(HWND hParent = NULL)
	{
		InitMsgMap();
		//Launch the modeless dialog
		int nRet = TreeEditDlg::Create(hParent);
		
		return nRet;
	}

protected:
	
	EVENTS_BEGIN
		ON_INIT( OnInitDialog )
		ON_DESTROY(OnDestroy)
		ON_SIZE(OnDlgResize)
		ON_BN_CLICKED(IDC_HTTP_SHOW_BOTTOM, OnShowBottomPane)

		ON_GETNDLG_MSGS(IDC_HTTP_GRID)
		ON_BN_CLICKED(IDC_HTTP_ACTION, OnHttpAct)
		ON_GRID_SEL_CHANGE(IDC_HTTP_GRID, OnSelChange)
		
		ON_SYSCOMMAND(OnSystemCommand)
	EVENTS_END
	
protected:
	BOOL OnInitDialog()
	{
		ResizeDialog::OnInitDialog(IDC_HTTP_GRID, "CheckForUpdateDlg");
		
		m_treeEditCntrl.Init(IDC_HTTP_GRID, false, true, NULL, *this);
		vector<string>  vstrTipsUpDown = {"Show More", "Show Less"};
		TreeEditDlg::OnInitDialog(IDC_HTTP_GRID, IDC_HTTP_SHOW_BOTTOM, IDC_TX_ITEM_DESCRITION, vstrTipsUpDown, "CheckForUpdateDlg", 0, NULL, false);
		
		
		try 
		{
			Control TXTextControl = GetItem(IDC_TX_ITEM_DESCRITION);
			m_treeEditCntrl.SetVisible(FALSE);
			
			if(TXTextControl)
			{
				m_txText = TXTextControl.GetActiveXControl();
			}
		}
		catch (int nError)
		{
		}
		if ( NULL == m_txText )
		{
			MessageBox(NULL, "Can't initialize TX control !", "error");
			return false;
		}
		
		
		
		m_nStage = CHKS_SET_DOWNLOAD;
		/// AW 11/01/05 MOVE_KEYBOARD_HANDLE_TO_CLASS
		m_myKeyboard.RestoreKeyboard();
		/// END MOVE_KEYBOARD_HANDLE_TO_CLASS

		
		updateDlg();
		UpdateDlgSize();
		SetInitReady();
		m_treeEditCntrl.SetReady();
		ShowWindow(SW_NORMAL);
		return TRUE;
	}

	
	BOOL OnHttpAct(Control cntrl)
	{
		m_bCheck = FALSE;
		
		BOOL bSelected;
		DWORD nTotalSize;
		m_vsServerFileName.SetSize(0);
		m_vsLocalFileName.SetSize(0);

		TreeNode tr = m_paramTree;
		foreach(TreeNode trSection in tr.Children)
		{
//			foreach(TreeNode trNode in trSection.Children)
			{
				if(0 != trSection.chk.nVal)
				{
					bSelected = 1==trSection.Use;
					m_vsServerFileName.Add(STR_DOWNLOAD_ADDRESS_TEMP + trSection.FileName.strVal);
					m_vsLocalFileName.Add(m_strSavedFilePath + trSection.FileName.strVal);
					nTotalSize +=atoi(trSection.FileSize.strVal);
				}
			}
		}
		if ( 0 == m_vsServerFileName.GetSize() )
			return TRUE;  

		m_nStage = CHKS_HTTP_DOWNLOAD;
//		m_strMsg = "Download files ";
		updateDlg();
		return DownloadFiles(nTotalSize)
		
	}
	void OnSelChange(Control cntrl)
	{
		if(m_treeEditCntrl.IsReady())
		{
			int  nIndex = m_treeEditCntrl.GetSelectedRow();
			updateDescription(nIndex);
		}
	}
	BOOL OnDestroy(void)
	{
		TreeEditDlg::OnDestroy();
		/// AW 11/01/05 MOVE_KEYBOARD_HANDLE_TO_CLASS
		m_myKeyboard.RestoreKeyboard();
		/// END MOVE_KEYBOARD_HANDLE_TO_CLASS

		if(m_bDeleteOnDestroy)
		{
			delete this;
			s_pCheckForUpdatedlg = NULL;
		}
		s_nCounter = 0;
		return true;
	}
	void OnRowColChange(Control cntrl)
	{
		if(!IsInitReady())
			return;
		TreeEditDlg::OnRowColChange(cntrl);
	}
	void OnBeforeEdit(Control cntrl, long nRow, long nCol, BOOL* pCancel)
	{	
		if(!IsInitReady())
			return;
		if(nCol > 1)
		{
			*pCancel = true;
			return;
		}
			
		TreeEditDlg::OnBeforeEdit(cntrl, nRow, nCol, pCancel);
	}

public:
	BOOL OnDlgResize(int nType, int cx, int cy)
	{
		if(!IsInitReady())
			return TRUE;
		
		out_str("Resize");
		uint nRightIDs[] = {0};
		uint nButtonIDs[]  = {IDCANCEL, IDC_HTTP_ACTION, IDC_HTTP_PROGRESS, 0};
//		ArrangeMainItemAndControls(nBottomIDs, IDC_HTTP_GRID, NULL, false);
//		ResizeMoveControlsRightBottom(IDC_HTTP_GRID, NULL, nBottomIDs, cx, cy);
//		TreeEditDlg::OnDlgResize(nBottomIDs, cx, cy, false);
		MultiPaneDlg::OnDlgResize(nButtonIDs, cx, cy, false);
//		ResizeDialog::OnResize(nType, cx, cy);
		

		//MultiPaneDlg::OnDlgResize(nBottomIDs, cx, cy, false);
		return TRUE;
	}
private:
	void updateDlg()
	{
		m_bCheck = FALSE;
		Button cCancelBtn = GetItem(IDCANCEL);
		Button cActionBtn = GetItem(IDC_HTTP_ACTION);
		m_treeEditCntrl.SetReady(false);
		//Tree trResult; 
		switch ( m_nStage )
		{
			
		case CHKS_HTTP_CHECK:
			//emptyParamTree();
			m_treeEditCntrl.SetVisible(FALSE);
			return;
			
		case CHKS_SET_DOWNLOAD:
			
			m_txText.Text = m_strMsg;
			String str;
			try 
			{
				m_strResult = m_TestCheckUpdates.GetFileList(m_strExt);
			}
			catch (int nError)
			{ 
			}
			if ( m_strResult.IsEmpty() )
			{
				MessageBox(NULL, "Can't link to Server!", "Error");
				return;
			}
			m_trResult.XML = m_strResult;
			//trResult.Load(GetAppPath(TRUE)+"result.xml");   // testing testing no network
			m_strMsg  += "done!\n";
			m_txText.Text = m_strMsg;
			m_trResult.Save(GetAppPath(TRUE)+"result.xml");
			m_treeEditCntrl.SetVisible(TRUE);
		case CHK_RESET_DOWNLOAD:
			//setupParamTree(trResult);
			
//			if ( 0 == m_nTimerID )
//				m_nTimerID = SetTimer(MY_TIMER_ID,TIMER_VALUE);	/// AW 10/08/05 MOVE_PROGRESSBAR_TO_VC_LEVEL
			cActionBtn.Enable = TRUE;
			cCancelBtn.Visible = TRUE;
			m_bCheck = FALSE;
//			m_ctrlProgress.Visible = FALSE;   /// AW 10/08/05 MOVE_PROGRESSBAR_TO_VC_LEVEL
			m_strMsg += "Check local files...";
			//GetLocalFileList();
			GetDownloadList();
			NewsetupParamTree(m_trResult);
			m_strMsg += "done!\n";
			m_txText.Text = m_strMsg;
			break;
		case CHKS_HTTP_DOWNLOAD:
			cActionBtn.Enable = FALSE;
			cCancelBtn.Visible = FALSE;
//			m_ctrlProgress.Visible = TRUE;  /// AW 10/08/05 MOVE_PROGRESSBAR_TO_VC_LEVEL
			break;
		default:
			ASSERT(FALSE);
		}
		OnDlgResize(0, GetDlgExtent(false), GetDlgExtent(true));
		// CPY 8/31/05 SHOW_TREE_AS_GRID
//		m_treeEditCntrl.Update(m_paramTree, true, true);
		if(m_paramTree)
			setGridViewOptions(m_paramTree);
		m_treeEditCntrl.UpdateGrid(m_paramTree);
		
		
		//---- CPY ADD_SORTING
		m_treeEditCntrl.SetExplorerBar(flexExSortShow);
		m_treeEditCntrl.SetAllowSelection(true);
		//m_treeEditCntrl.SetSelection( flexSelectionByRow );
		m_treeEditCntrl.SetSelection( flexSelectionListBox );
		//----END ADD_SORTING
		//vector<byte> vbHideCols = {0, 0, 1, 0, 0, 0};
		//m_treeEditCntrl.SetHiddenCols(vbHideCols);*/
		m_treeEditCntrl.ResizeCols(0.1, 1.0, 0);
//		string str;
//		str = " ";
//		m_txText.LoadFromMemory(str, 1, 1);
		m_txText.SelStart = -1;
		m_txText.SelText = " ";

		m_treeEditCntrl.SetReady();

	}
	
	////////
	// move this function into GetDownloadList
	/*
	void GetLocalFileList()
	{
		vector<string> vsFiles;
		NOTIFY_XF_FILE_CHANGE
		
		//okutil_find_files(NULL, NULL, SUPPORTFILE_XF, FF_UPDATE_MAP);
		//okutil_find_files(StringArray* psaNames, StringArray* psaFiles, int nFileType, DWORD dwCntrl = 0x0, DWORD *pdwUsgCtxts = NULL, 
		//int numOfTpes = 0, IntArray *parrIds = NULL,  DoubleArray* parrDoubles = NULL, int nLocation = ORIGIN_PATH_PREFER_USER);

		
		///DSC 10/11/2005 QA70-8167 FIND_FILES_FROM_SPECIFIED_LOCATION
		// int nNumXFs = okutil_find_files(&m_vsXFnames, &vsFiles, SUPPORTFILE_XF, FF_REMOVE_DUPLICATE|FF_REMOVE_CATEGORY|FF_REMOVE_PATH);
		//int nNumXFs = okutil_find_files(&m_vsXFnames, &vsFiles, SUPPORTFILE_XF, FF_REMOVE_CATEGORY|FF_REMOVE_PATH);
		int nNumXFs = okutil_find_files(&m_vsXFnames, &vsFiles, SUPPORTFILE_XF, FF_REMOVE_CATEGORY|FF_REMOVE_PATH, NULL, 0, NULL, &m_vdLoacalVersions);
		///end FIND_FILES_FROM_SPECIFIED_LOCATION
		
	}
	*/
	
	void GetDownloadList()
	{
		int ii, nRet;
		BOOL bOK, bInList;
		
		
		vector<string> vsFiles, vsFileNames;
		vector<double> vdLoacalVersions, vdBadFileVersion;
		NOTIFY_XF_FILE_CHANGE
		
		//int nNumXFs = okutil_find_files(&vsFileNames, &vsFiles, SUPPORTFILE_XF, FF_REMOVE_CATEGORY|FF_REMOVE_PATH|FF_GET_VERSION_INSTEAD_OF_DATE, NULL, 0, NULL, &vdLoacalVersions, ORIGIN_PATH_USER);
		int nNumXFs = okutil_find_files_from_map(&vsFileNames, &vsFiles, SUPPORTFILE_XF, FF_GET_VERSION_INSTEAD_OF_DATE, NULL, 0, NULL, &vdLoacalVersions, ORIGIN_PATH_USER);
		nNumXFs = okutil_find_files_from_map(&vsFileNames, &vsFiles, SUPPORTFILE_XF, FF_REMOVE_CATEGORY|FF_REMOVE_PATH, NULL, 0, NULL, NULL, ORIGIN_PATH_USER);
		
		/// this step should be removed later
		for(ii = 0; ii < nNumXFs; ii++)
			vsFileNames[ii] += ".oxf";
			
		// compare with installed XF list
		vector<string> vsExcludeFileNameList;
		vector<uint> vnIndeces;
		
		vsExcludeFileNameList = vsFileNames;
		vsExcludeFileNameList.Append(m_vsBadFileName);
		vdBadFileVersion.SetSize(m_vsBadFileName.GetSize());  // generate array for reorder
		vdLoacalVersions.Append(vdBadFileVersion);
		
		nNumXFs = vsExcludeFileNameList.GetSize();
		if ( nNumXFs > 1 ) 
		{
			bOK = vsExcludeFileNameList.Sort(SORT_ASCENDING);
			vdLoacalVersions.Reorder(vnIndeces);
		}
		foreach( TreeNode trFileNode in m_trResult.Children )
		{
			string	strFilename;
			bOK = trFileNode.GetValue(strFilename, STR_FILE_LIST_NAME);
			ASSERT(bOK);
			
			/// check if filename is in the list of the client
			bInList = false;
			if ( nNumXFs > 0 )
			{
				for(ii = 0; ii < vsExcludeFileNameList.GetSize(); ii++)
				{
					nRet = strFilename.CompareNoCase(vsExcludeFileNameList[ii]);
					if ( 0 == nRet )
					{	
						if ( trFileNode.Version.dVal <= vdLoacalVersions[ii] ) 
						{				
							bInList = TRUE;
							break;
						}
					}
					else if ( 0 > nRet)
					{
						break;    // no need got to end
					}
				}
			}
			if ( bInList )
			{
				m_trResult.RemoveChild(trFileNode);
			}
		}
	}
	///////////
	
	void updateDescription(int nIndex)
	{
		if ( nIndex < 0 )
			return;
		TreeNode tdNode = m_paramTree.Children.Item(nIndex - 1);
		string str;
		TreeNode tdDesc =tdNode.GetNode("Description");
		str = tdDesc.Text;
		m_txText.Text = str;
				
		
	}
	
	void getn_tree_set_view_options(TreeNode& tr, bool bRowColors = true, bool bEmptyIndicatorColor = true, bool bSet = true)
	{
		if(!bSet) // to remove
		{
			if(bRowColors)
				tr.RemoveAttribute(STR_ATTRIB_TREE_ROW_COLOR);
			if(bEmptyIndicatorColor)
				tr.RemoveAttribute(STR_ATTRIB_TREE_INDICATOR_COLOR);
			
			return;
		}
		string strColors, strSpecialIndicatorColors;
		get_analysis_gui_color(strColors, strSpecialIndicatorColors);
		if(bRowColors)
			tr.SetAttribute(STR_ATTRIB_TREE_ROW_COLOR, strColors);
		if(bEmptyIndicatorColor)
			tr.SetAttribute(STR_ATTRIB_TREE_INDICATOR_COLOR, strSpecialIndicatorColors);
	}
	void setGridViewOptions(TreeNode& tr)
	{
		GETN_USE(tr)
		GETN_OPTION_EDIT_ALIGN("1|1|1") // CheckBox = Left, Numbers = Center, String = Center
		getn_tree_set_view_options(tr, true, true, false);
	}
	
	void NewsetupParamTree(TreeNode& trOptions)  // Set GUI for selecting download
	{
		int nn = 1;
		foreach(TreeNode trN in trOptions.Children)
		{
			string strLabel = nn++;
			trN.SetAttribute(STR_LABEL_ATTRIB, strLabel);
			trN.InsertNode(trN.FirstNode, "chk", TRGP_CHECK);
		}
		m_paramTree = trOptions;
	}
	
	
	BOOL MoveFiles()
	{
		int nSize = m_vsLocalFileName.GetSize();
		string strFullName, strShortName, strCat, strNewFullName, strError;
		
		Tree tr;
		BOOL bOK;
		// XFunctionOrganizer Xfo;

		string strFolder = GetAppPath(true) + STR_XF_FILE_FOLDER;
		for ( int ii = 0; ii < nSize; ii++ )
		{
			strFullName = m_vsLocalFileName[ii];
			strShortName = strFullName.Mid(strFullName.ReverseFind('\\') + 1);
			strCat = "";
			
			
			
			if(tr.Load(strFullName))
			{
			/*	if(tr.category)
					strCat = tr.category.strVal;
				else
				{
					strError.Format(" No Category info in %s", strFullName);
					strError.WriteLine(WRITE_COMPILER_OUTPUT);
					ASSERT(FALSE);
				}
				
				if ( strCat.IsEmpty() )
				{
					m_vsBadFileName.Add(strShortName);
				}
				else
				{
					strNewFullName = strFolder + "\\" + strCat + "\\" + strShortName;
					bOK = MoveFile(strFullName, strNewFullName);
					ASSERT(bOK);
				}
			*/
				// if ( Xfo.SaveToDefaultLocation(tr) )
				if (xf_save_to_default_location(tr) )
				{
					strNewFullName = strFolder + "\\" + strCat + "\\" + strShortName;
					bOK = DeleteFile(strFullName);
					ASSERT(bOK);
				}
				else
				{
					m_vsBadFileName.Add(strShortName);	
				}
			}
			else
			{
				strError.Format("%s is not valid XF!", strFullName);
				strError.WriteLine(WRITE_COMPILER_OUTPUT);
				ASSERT(FALSE);
			}
			
			
		}
		return TRUE;
	}

	
	BOOL DownloadFiles(DWORD nTotalSize)
	{
		int nErr;
		
		
		m_dwCntrl = HTTP_JOB_DOWNLOAD_FILE;
		m_nHttpJobIndex = http_start(m_dwCntrl, NULL, &m_vsServerFileName, &m_vsLocalFileName, &nErr, WEBSITE_URL); /// AW 10/13/05 ADD_SUPPORT_FOR_DIFF_WEBSITE_ADDRESS
		if ( 0 > m_nHttpJobIndex )
		{
			ASSERT(FALSE);
			return FALSE;
		}
		MoveFiles();
		m_nStage = CHK_RESET_DOWNLOAD;
		updateDlg();

		m_bCheck = TRUE;
		
		return TRUE;
		
	}
	

	LPCSTR GetResult()
	{
		return m_strResult;		
	}

		

};

//-- CPY 10/11/05

void TestDownloadXF(BOOL bClose = false)
{
	static CheckForUpdateWindow* s_pDlg;
	
	if(bClose)
	{
		if(s_pDlg)
		{
			Window winDlg = s_pDlg->GetWindow();
		}
		return;
	}
	if(s_pDlg)
		TestDownloadXF(true);
	
	s_pDlg = new CheckForUpdateWindow(FALSE, 0, "oxf");
	
	s_pDlg->Create(GetWindow());
	out_str("-------------- Done!!! ----------------");
}

int CheckForUpdateDlg(int nMsg=0, DWORD dwCntrl=0, LPVOID lpData = NULL)
{
	static CheckForUpdateWindow* s_pDlg = NULL;
	bool bClose = OMSG_CLOSE==nMsg? true:false;
	bool bUpdate = OMSG_UPDATE==nMsg? true:false;
	
	if(bClose)  
	{
		if(s_pDlg)
		{
			Window winDlg = s_pDlg->GetWindow();
			if(winDlg)
				winDlg.SendMessage(WM_CLOSE);
			
			delete s_pDlg;
			s_pDlg = NULL;
		}
		return 0;
	}
	if(s_pDlg) // reentrance, better close it first
	{
		CheckForUpdateDlg(OMSG_CLOSE);
	}
		
	// open or update
	if(!s_pDlg)
	{
		if(bUpdate)
			return 1;// not possible to update, since dialog not opened

		s_pDlg = new CheckForUpdateWindow(FALSE, 0, "oxf");
		s_pDlg->Create(GetWindow());
	}
		
		
	if(bUpdate)
	{
		//s_pDlg->Update();//"from global message");
	}
	return 0;
}
//---
