/*------------------------------------------------------------------------------*
 * File Name:  ChkForUpdatesDlg.h												*
 * Creation:  2008-06-20														*
 * Purpose: OriginC Check For Updates dialog handler							*
 * Copyright (c) OriginLab Corp. 2008											*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 * EJP 2008-06-19 v8.0888 NEW_CHKFORUPDATES_NEED_HANDLE_PATCH					*
 * EJP 2008-07-11 v8.0901 QA80-11788 IMPROVE_CHECK_FOR_UPDATES					*
 * EJP 2008-07-21 v8.0906 QA80-11788 PREVENT_MULTIPLE_CHECK_FOR_UPDATES			*
 * EJP 2008-08-25 v8.0929 FAILED_TO_OPEN_LOG_FILE								*
 * EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO				*
 * AW 12/17/2008 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO						*
 * EJP 2009-01-08 v8.0995 QA80-12393 DISPLAY_MSG_FROM_SERVER					*
 * AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER								*
 *	Folger 01/15/09 MAKE_CHECKFORUPDATEMSG_DIALOG_RESIZABLE						*
 * AW 01/15/09 MAKE_CHECKFORUPDATEMSG_DIALOG_RESIZABLE							*
 * EJP 2009-02-12 PREVENT_UNWANTED_TIMEOUT										*
 * DSC 6/18/2010 ORG-212 IMPROVE_RUN_AS_ADMINISTRATOR_MSG						*
 * EJP 2010-07-14 ORG-525 RESIZE_COLUMNS_AFTER_UPDATING_LIST					*
 *------------------------------------------------------------------------------*/

enum {
	OUL_GET_COL = 0,
	OUL_DESCRIPTION_COL,
	OUL_SIZE_COL,
	OUL_SOURCE_COL,
	OUL_NUM_COLS
};

class UpdatesTree; /// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO

class OriginUpdatesList : public GridListControl // GridListControl derived from public GridControl
{
public:
	OriginUpdatesList()
	{
	}

	void Init(int nID, WndContainer& dlg)
	{
		GridListControl::Init(nID, dlg);
		SetAlternateRowColors();

		SetupRowsCols(1, 0, 1, 4);
		m_flx.Editable = flexEDKbdMouse;//flexEDNone;
		m_flx.ExtendLastCol = TRUE;
		m_flx.AllowUserResizing = flexResizeColumns;

		m_flx.SelectionMode = flexSelectionByRow;//flexSelectionFree;flexSelectionListBox;flexSelectionByRow
		m_flx.AllowSelection = false;
		
		m_flx.ColWidthMin = 4;
		m_flx.ColWidthMax = 0;

		SetColHeading(OUL_GET_COL, _L("Get"));
		SetColDataType(OUL_GET_COL, flexDTBoolean);
		SetColHeading(OUL_DESCRIPTION_COL, _L("Package Title"));
		SetColHeading(OUL_SIZE_COL, _L("Size (KBytes)"));
		SetColHeading(OUL_SOURCE_COL, _L("Created By"));
		
		m_flx.AutoSizeMode = flexAutoSizeColWidth; /// EJP 10-08-2003 v7.5715 QA70-5289.3 UPDATE_COL_WIDTH
		m_flx.AutoSize(0, m_flx.Cols - 1, false, 0);
	}
	
	/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
	///void UpdateGrid(Tree& trUpdates)
	void UpdateGrid(UpdatesTree& trUpdates)
	/// end CHK_FOR_UPDATES_NEED_MORE_INFO
	{
		m_flx.Rows = 1; // only column headings

		int i = 0;
		TreeNode tn;
		foreach(TreeNode tnUpdate in trUpdates.Children)
		{
			/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
			if( !trUpdates.IsFileUpdateNode(tnUpdate) )
				continue;
			/// end CHK_FOR_UPDATES_NEED_MORE_INFO

			i = m_flx.Rows;
			m_flx.Rows = i + 1;
	
			tn = tnUpdate.GetNode("title");
			SetCell(tn.strVal, flexcpText, i, OUL_DESCRIPTION_COL);
	
			tn = tnUpdate.GetNode("size");
			SetCell(tn.nVal, flexcpText, i, OUL_SIZE_COL);
	
			tn = tnUpdate.GetNode("createBy");
			SetCell(tn.strVal, flexcpText, i, OUL_SOURCE_COL);
		}
		m_flx.AutoSize(0, m_flx.Cols - 1, false, 0); /// EJP 2010-07-14 ORG-525 RESIZE_COLUMNS_AFTER_UPDATING_LIST
	}

	BOOL IsCheckBoxCol(long nCol)
	{
		int nVal;
		if( IsCheckBoxCell(1, nCol, &nVal) )
			return TRUE;
		return FALSE;
	}

	BOOL IsItemChecked(int nRow)
	{
		if( 0 < nRow && nRow < m_flx.Rows )
		{
			int nVal = GetCell(flexcpChecked, nRow, OUL_GET_COL);
			if( flexChecked == nVal )
				return TRUE;
		}
		return FALSE;
	}

	BOOL GetItemTitle(int nRow, string& strTitle)
	{
		if( 0 < nRow && nRow < m_flx.Rows )
		{
			strTitle = GetCell(flexcpText, nRow, OUL_DESCRIPTION_COL);
			return TRUE;
		}
		return FALSE;
	}

	BOOL GetSelectedTitle(string& strTitle)
	{
		int nRow = GetSelectedRow();
		return GetItemTitle(nRow, strTitle);
	}

	/// EJP 2008-07-11 v8.0901 QA80-11788 IMPROVE_CHECK_FOR_UPDATES
	///int GetCheckedItemTitle(StringArray& saTitles)
	int GetCheckedItemTitle(StringArray& saTitles, BOOL bGetChecked = TRUE)
	/// end IMPROVE_CHECK_FOR_UPDATES
	{
		string strTitle;
		for( int nRow = 1; nRow < m_flx.Rows; nRow++ )
		{
			/// EJP 2008-07-11 v8.0901 QA80-11788 IMPROVE_CHECK_FOR_UPDATES
			///int nVal = m_flx.Cell(flexcpChecked, nRow, OUL_GET_COL);
			///if( IsItemChecked(nRow) )
			if( IsItemChecked(nRow) == bGetChecked )
			/// end IMPROVE_CHECK_FOR_UPDATES
			{
				if( GetItemTitle(nRow, strTitle) )
					saTitles.Add(strTitle);
			}
		}
		return saTitles.GetSize();
	}
	
	void SetCheckForAllItems(bool bChecked = true)
	{
		int nVal = (bChecked ? flexChecked : flexUnchecked);
		for( int nRow = 1; nRow < m_flx.Rows; nRow++ )
			SetCell(nVal, flexcpChecked, nRow, OUL_GET_COL);
	}
};

/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/

/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
///#define O_WEBSITE_URL					"http://www.originlab.com/"
///#define O_REQUEST_UPDATES_URL			O_WEBSITE_URL"www/support/updates/Checkforupdate8.asmx/GetRequest"
///#define O_DOWNLOAD_UPDATE_URL			O_WEBSITE_URL"ftp/Origin_updates/v8/"
///#define O_WEBSITE_PATH					"www/support/updates/Checkforupdate8.asmx/GetRequest"
/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO

//// AW 05/08/08 QA80-11529 MORE_ON_NEW_CHECKFORUPDATE
// #define O_REQUEST_UPDATES_MSG			"strOver=8&strLang=E&strRegID="
/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
///#define O_REQUEST_UPDATES_MSG_FORMNAT 	"strOver=%f&strLang=%s&strRegID=%s"

/// AW 12/17/2008 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
//#define O_REQUEST_UPDATES_MSG_FORMNAT 	"strOver=%f&strLang=%s&strRegID=%s&strSN=%s&strUserName=%s&strCompanyName=%s&strlic=%s"
#define O_REQUEST_UPDATES_MSG_FORMNAT 	"strOver=%f&strLang=%s&strRegID=%s&strSN=%s&strUserName=%s&strCompanyName=%s&strlic=%s&strCompID=%s"
/// END CHK_FOR_UPDATES_NEED_MORE_INFO

/// end CHK_FOR_UPDATES_NEED_MORE_INFO
#define CHECKFORUPDATE_LOG_FILE_NAME	"checkforupdate_log.txt"
#define ORIGIN_INFO_BUF_SIZE 			50
//// END MORE_ON_NEW_CHECKFORUPDATE

#define SZ_UPDATE_CREATEBY		"createBy"
#define SZ_UPDATE_DESCRIPTION	"description"
#define SZ_UPDATE_FILENAME		"fileName"
#define SZ_UPDATE_LOCATION		"location"
#define SZ_UPDATE_MODIFYDATE	"modifyDate"
#define SZ_UPDATE_SIZE			"size"
#define SZ_UPDATE_TITLE			"title"
#define SZ_UPDATE_DATE_FORMAT	"yyyy'-'MM'-'dd"

class UpdatesTree : public Tree
{
public:
	int LoadFromServer()
	{
		string str;
		int nRet = postCheckForUpdates(str);
		if( 0 == nRet )
			XML = str;
		return nRet;
	}

	int GetNumberOfUpdates()
	{
		/// EJP 2009-01-08 v8.0995 QA80-12393 DISPLAY_MSG_FROM_SERVER
		///	/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
		///	///return GetNodeCount();
		///	int nCount = GetNodeCount();
		///	int nLID;
		///	if( GetLID(nLID) )
		///		nCount--;
		///	return nCount;
		///	/// end CHK_FOR_UPDATES_NEED_MORE_INFO
		int nCount = 0;
		foreach(TreeNode tn in Children)
		{
			if( IsFileUpdateNode(tn) )
				nCount++;
		}
		return nCount;
		/// end DISPLAY_MSG_FROM_SERVER
	}

	bool GetUpdateByTitle(TreeNode& tnTarget, LPCSTR lpcszTitle)
	{
		string str;
		foreach(TreeNode tnUpdate in Children)
		{
			/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
			if( !IsFileUpdateNode(tnUpdate) )
				continue;
			/// end CHK_FOR_UPDATES_NEED_MORE_INFO

			if( GetUpdateTitle(tnUpdate, str) && 0 == str.Compare(lpcszTitle) )
			{
				tnTarget = tnUpdate;
				return true;
			}
		}
		return false;
	}

	bool GetFileNameByTitle(LPCSTR lpcszTitle, string& strFileName)
	{
		TreeNode tnUpdate;
		if( GetUpdateByTitle(tnUpdate, lpcszTitle) )
			return GetUpdatePathFileName(tnUpdate, strFileName);
		return false;
	}

	bool GetDescriptionByTitle(LPCSTR lpcszTitle, string& strDescrip)
	{
		TreeNode tnUpdate;
		if( GetUpdateByTitle(tnUpdate, lpcszTitle) )
			return GetUpdateDescription(tnUpdate, strDescrip);
		return false;
	}

	bool IsUpdateNewerThanLocal(TreeNode& tnUpdate, bool bRetOnErr)
	{
		string strLocalFileName;
		if( !GetUpdateLocalFileName(tnUpdate, strLocalFileName) )
			return bRetOnErr;

		SYSTEMTIME sysTime;
		if( !GetFileModificationDate(strLocalFileName, sysTime) )
			return bRetOnErr;

		double dLocalDate;
		if( !SystemTimeToJulianDate(&dLocalDate, &sysTime) )
			return bRetOnErr;

		double dUpdateDate;
		if( !GetUpdateModifyDate(tnUpdate, dUpdateDate) )
			return bRetOnErr;

		if( dUpdateDate > dLocalDate )
			return true;
		return false;
	}

	void RemoveOlderUpdates()
	{
		foreach(TreeNode tnUpdate in Children)
		{
			/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
			if( !IsFileUpdateNode(tnUpdate) )
				continue;
			/// end CHK_FOR_UPDATES_NEED_MORE_INFO

			if( !IsUpdateNewerThanLocal(tnUpdate, true) )
				RemoveChild(tnUpdate);
		}
	}

	/// EJP 2008-07-11 v8.0901 QA80-11788 IMPROVE_CHECK_FOR_UPDATES
	void RemoveUpdatesByTitle(StringArray& saTitles)
	{
		if( 0 == saTitles.GetSize() )
			return;

		string strTitle;
		foreach(TreeNode tnUpdate in Children)
		{
			if( GetUpdateTitle(tnUpdate, strTitle) )
			{
				if( saTitles.Find(strTitle) >= 0 )
					RemoveChild(tnUpdate);
			}
		}
	}
	/// end IMPROVE_CHECK_FOR_UPDATES

	/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
	bool GetLID(int& nLID)
	{
		TreeNode tnLID = GetNode("LID", false); // false = ignore case
		if( !tnLID.IsValid() )
			return false;
		return tnLID.GetValue(nLID);
	}
	/// end CHK_FOR_UPDATES_NEED_MORE_INFO

	/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
	bool IsFileUpdateNode(TreeNode& tn)
	{
		string strName = tn.tagName;
		if( strName.CompareNoCase("document") == 0 || strName.CompareNoCase("patch") == 0 )
			return true;
		return false;
	}
	/// end CHK_FOR_UPDATES_NEED_MORE_INFO

	/// EJP 2009-01-08 v8.0995 QA80-12393 DISPLAY_MSG_FROM_SERVER
	int CheckAndShowMessage(HWND hwndParent)
	{
		/// AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER
		//int nRet = 0;
		int nRet = 1;
		/// END QA80-12393 DISPLAY_MSG_FROM_SERVER
		TreeNode tnAlert = GetNode("Alert", false); // false = ignore case
		if( tnAlert.IsValid() )
		{
			string strMsg;
			TreeNode tn = tnAlert.GetNode("Message", false);
			if( tn.IsValid() )
				tn.GetValue(strMsg);

			string strURL;
			tn = tnAlert.GetNode("URL", false);
			if( tn.IsValid() )
				tn.GetValue(strURL);
			
			int nContinue = 0;
			tn = tnAlert.GetNode("Continue", false);
			if( tn.IsValid() )
				tn.GetValue(nContinue);
			
			/// AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER
			//CheckForUpdatesMsgDlg msgDlg;
			//nRet = msgDlg.DoModalEx(hwndParent, strMsg, strURL, nContinue);
			int nShowStop = 0;
			tn = tnAlert.GetNode("Stop", false);
			if( tn.IsValid() )
				tn.GetValue(nShowStop);
			CheckForUpdatesMsgDlg msgDlg;
			nRet = msgDlg.DoModalEx(hwndParent, strMsg, strURL, nContinue, nShowStop);
			/// END DISPLAY_MSG_FROM_SERVER

		}
		return nRet;
	}
	/// end DISPLAY_MSG_FROM_SERVER

protected:
	bool GetUpdateValue(TreeNode& tnUpdate, LPCSTR lpcszChildName, string& strVal)
	{
		TreeNode tn = tnUpdate.GetNode(lpcszChildName);
		if( !tn.IsValid() )
			return false;
		strVal = tn.strVal;
		return true;
	}

	bool GetUpdateValue(TreeNode& tnUpdate, LPCSTR lpcszChildName, int& nVal)
	{
		TreeNode tn = tnUpdate.GetNode(lpcszChildName);
		if( !tn.IsValid() )
			return false;
		nVal = tn.nVal;
		return true;
	}

	bool GetUpdateCreateBy(TreeNode& tnUpdate, string& strCreateBy)
		{return GetUpdateValue(tnUpdate, SZ_UPDATE_CREATEBY, strCreateBy);}

	bool GetUpdateDescription(TreeNode& tnUpdate, string& strDesc)
		{return GetUpdateValue(tnUpdate, SZ_UPDATE_DESCRIPTION, strDesc);}
	
	bool GetUpdateFileName(TreeNode& tnUpdate, string& strFileName)
		{return GetUpdateValue(tnUpdate, SZ_UPDATE_FILENAME, strFileName);}
	
	bool GetUpdateLocation(TreeNode& tnUpdate, string& strLocation)
		{return GetUpdateValue(tnUpdate, SZ_UPDATE_LOCATION, strLocation);}
	
	bool GetUpdateSize(TreeNode& tnUpdate, int& nSize)
		{return GetUpdateValue(tnUpdate, SZ_UPDATE_TITLE, nSize);}

	bool GetUpdateTitle(TreeNode& tnUpdate, string& strTitle)
		{return GetUpdateValue(tnUpdate, SZ_UPDATE_TITLE, strTitle);}

	bool GetUpdateModifyDate(TreeNode& tnUpdate, double& dModifyDate)
	{
		string str;
		if( !GetUpdateValue(tnUpdate, SZ_UPDATE_MODIFYDATE, str) )
			return false;
		return str_to_date_custom(str, SZ_UPDATE_DATE_FORMAT, &dModifyDate);
	}

	bool GetUpdatePathFileName(TreeNode& tnUpdate, string& strPathFileName)
	{
		string str;
		if( !GetUpdateValue(tnUpdate, SZ_UPDATE_FILENAME, str) )
			return false;
		if( !GetUpdateValue(tnUpdate, SZ_UPDATE_LOCATION, strPathFileName) )
			return false;
		strPathFileName += str;
		return true;
	}

	bool GetUpdateLocalFileName(TreeNode& tnUpdate, string& strLocalFileName)
	{
		string strPathFileName;
		if( !GetUpdatePathFileName(tnUpdate, strPathFileName) )
			return false;
		strLocalFileName.Format("%s%s", GetOriginPath(), strPathFileName);
		return true;
	}

	int postCheckForUpdates(string& strResult)
	{
		/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
		///string strURL = O_REQUEST_UPDATES_URL;
		string strURL;
		http_get_updates_url(&strURL, 0x0101); 
		/// end CHK_FOR_UPDATES_NEED_MORE_INFO
		
		//// AW 05/08/08 QA80-11529 MORE_ON_NEW_CHECKFORUPDATE
		//string strMsg = O_REQUEST_UPDATES_MSG;
		string strMsg;

		char 			chRS[ORIGIN_INFO_BUF_SIZE], chRL[ORIGIN_INFO_BUF_SIZE];
		stWCBUSERINFO	orgUserInfo;
		
		memset(&orgUserInfo, 0, sizeof(stWCBUSERINFO));	
		
		/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
		char szSerialNumber[ORIGIN_INFO_BUF_SIZE];
		orgUserInfo.lpstrSerialNumber = szSerialNumber;
		/// end CHK_FOR_UPDATES_NEED_MORE_INFO

		orgUserInfo.lpstrRegistrationID = chRS;
		orgUserInfo.lpstrLanguageCharater = chRL;
		GetUserInfo(&orgUserInfo, true);   // AW 12/17/2008 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO

		/// EJP 2008-10-28 v8.0963 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
		///strMsg.Format(O_REQUEST_UPDATES_MSG_FORMNAT, orgUserInfo.fVersionNumber, chRL, chRS);
		strMsg.Format(O_REQUEST_UPDATES_MSG_FORMNAT, orgUserInfo.fVersionNumber, chRL, chRS,
			orgUserInfo.lpstrSerialNumber,
			orgUserInfo.szUserName, orgUserInfo.szCompanyName,
			orgUserInfo.szLic
			,orgUserInfo.szComputerID/// AW 12/17/2008 QA80-12393 CHK_FOR_UPDATES_NEED_MORE_INFO
			);
		/// end CHK_FOR_UPDATES_NEED_MORE_INFO
		/// END MORE_ON_NEW_CHECKFORUPDATE

		strResult.Empty(); /// EJP 2008-07-11 v8.0901 QA80-11788 IMPROVE_CHECK_FOR_UPDATES
		int nRet = http_post(strURL, strMsg, &strResult, TRUE); // TRUE for get results
		if( 0 == nRet )
		{
			strResult.Replace("&lt;", "<");
			strResult.Replace("&gt;", ">");
		}

		//// AW 05/08/08 QA80-11529 MORE_ON_NEW_CHECKFORUPDATE
		string strLog, strlogFileName;
		/// EJP 2008-06-17 v8.0887 QA80-11529 WRITE_LOG_TO_USER_PATH
		///strlogFileName.Format("%s%s", GetOriginPath(), CHECKFORUPDATE_LOG_FILE_NAME);
		strlogFileName.Format("%s%s", GetOriginPath(ORIGIN_PATH_USER), CHECKFORUPDATE_LOG_FILE_NAME);
		/// end WRITE_LOG_TO_USER_PATH
		stdioFile fCheckForUpdatelog;
		/// EJP 2008-08-25 v8.0929 FAILED_TO_OPEN_LOG_FILE
		///if ( !fCheckForUpdatelog.Open(strlogFileName, file::modeWrite|file::shareDenyWrite ) )
		if ( !fCheckForUpdatelog.Open(strlogFileName, file::modeCreate|file::modeWrite|file::shareDenyWrite) )
		/// end FAILED_TO_OPEN_LOG_FILE
		{
			out_str("Failed to open " + strlogFileName);			
		}
		else
		{
			fCheckForUpdatelog.WriteString(strURL);
			fCheckForUpdatelog.WriteString(strMsg);
			fCheckForUpdatelog.WriteString(strResult);
		}
		/// END MORE_ON_NEW_CHECKFORUPDATE

		return nRet;
	}
	
	/* Not needed now but may be useful later.	
	int postCheckForUpdates(TreeNode& tnUpdates)
	{
		string strResult;
		int nRet = postCheckForUpdates(strResult);
		if( 0 == nRet )
		{
			tnUpdates.XML = strResult;
		}
		return nRet;
	}
	*/
};

/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/

/// EJP 2009-01-08 v8.0995 QA80-12393 DISPLAY_MSG_FROM_SERVER
/// AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER
//class CheckForUpdatesMsgDlg : public Dialog 
class CheckForUpdatesMsgDlg : public ResizeDialog 
/// END DISPLAY_MSG_FROM_SERVER  
{
public:
	CheckForUpdatesMsgDlg() : ResizeDialog(IDD_CHKFORUPDATES_MSG, "ODlg8") 
	{
	}
	
	/// AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER
	//DWORD DoModalEx(HWND hParent, LPCSTR strMsg, LPCSTR strURL, BOOL bContinue)
	DWORD DoModalEx(HWND hParent, LPCSTR strMsg, LPCSTR strURL, BOOL bContinue, BOOL bShowClose)
	/// END DISPLAY_MSG_FROM_SERVER
	{
		InitMsgMap();

		m_strMsg = strMsg;
		m_strURL = strURL;
		m_bContinue = bContinue;
		m_bShowClose = bShowClose; /// AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER
		
		if( IDOK == DoModal(hParent) )
			return 1;
		return 0;
	}

protected:
	
	EVENTS_BEGIN
		ON_INIT(OnInitDialog)
		ON_DESTROY(OnDestroy)
		ON_OK(OnOK)
		ON_CANCEL(OnCancel)
		ON_BN_CLICKED(IDC_GOTOPAGE, OnGotoPage)
		ON_SIZE(OnDlgResize)			/// AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER
		ON_READY(OnReady)				///------ Folger 01/15/09 MAKE_CHECKFORUPDATEMSG_DIALOG_RESIZABLE
	EVENTS_END

	BOOL OnInitDialog()
	{
		ResizeDialog::OnInitDialog();	///------ Folger 01/15/09 MAKE_CHECKFORUPDATEMSG_DIALOG_RESIZABLE
		
		Control ctrl = GetItem(IDC_MESSAGE);
		ctrl.Text = m_strMsg;

		ctrl = GetItem(IDC_GOTOPAGE);
		ctrl.Visible = m_strURL.GetLength();

		ctrl = GetItem(IDOK); // The continue with check for updates button
		ctrl.Visible = m_bContinue;
		
		/// AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER
		ctrl = GetItem(IDCANCEL); // close button
		ctrl.Visible = m_bShowClose;
		/// END DISPLAY_MSG_FROM_SERVER

		ShowWindow(SW_NORMAL);
		return TRUE;
	}

	BOOL OnDestroy(void)
	{
		return TRUE;
	}
	///------ Folger 01/15/09 MAKE_CHECKFORUPDATEMSG_DIALOG_RESIZABLE
	BOOL	OnReady()
	{
		SetInitReady();
		return TRUE;
	}
	///------ End MAKE_CHECKFORUPDATEMSG_DIALOG_RESIZABLE
public:

	BOOL OnOK()
	{
		return TRUE;
	}

	BOOL OnCancel()
	{	
		return TRUE;
	}

	BOOL OnGotoPage(Control cntrl)
	{
		LT_execute("win -aw " + m_strURL);
		return TRUE;
	}
	/// AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER
	BOOL OnDlgResize(int nType, int cx, int cy)
	{
		if(!IsInitReady())
			return TRUE;
		
		///------ Folger 01/15/09 MAKE_CHECKFORUPDATEMSG_DIALOG_RESIZABLE
		//uint nBottomIDs[]  = {IDCANCEL, IDOK, IDC_GOTOPAGE, 0};
		//ArrangeMainItemAndControls(nBottomIDs, IDC_MESSAGE, NULL, false);
		MoveControlsHelper	_temp(this);

		vector<uint>	vnBottomIDs  = {IDCANCEL, IDOK, IDC_GOTOPAGE, 0};
		for ( int ii=vnBottomIDs.GetSize()-1; ii>=0; --ii )
		{
			if ( vnBottomIDs[ii] != 0 && !GetItem(vnBottomIDs[ii]).Visible )
				vnBottomIDs.RemoveAt(ii);
		}
		if ( vnBottomIDs.GetSize() > 1 )   /// AW 01/15/09 MAKE_CHECKFORUPDATEMSG_DIALOG_RESIZABLE	
			ArrangeMainItemAndControls(vnBottomIDs, IDC_MESSAGE, NULL, false);
		///------ End MAKE_CHECKFORUPDATEMSG_DIALOG_RESIZABLE
		
		return TRUE;
	}
	/// END DISPLAY_MSG_FROM_SERVER


private:
	
	string m_strMsg;
	string m_strURL;
	bool m_bContinue;
	bool m_bShowClose; /// AW 01/13/09 QA80-12393 DISPLAY_MSG_FROM_SERVER

};
/// end DISPLAY_MSG_FROM_SERVER

/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/

#define SZ_CHKFORUPDATES_TITLE		_L("Check for Updates")
#define SZ_CHKFORUPDATES_NONE		_L("There are no updates for this version of Origin.")
#define SZ_CHKFORUPDATES_REGREQ		_L("Check for Updates requires Origin to be registered.")
#define SZ_CHKFORUPDATES_WRITEABLEREQ	_L("Check for Updates requires the Origin folder to have write access.")
///DSC 6/18/2010 ORG-212 IMPROVE_RUN_AS_ADMINISTRATOR_MSG
// #define SZ_CHKFORUPDATES_ADMINREQ	_L("Check for Updates requires that you run Origin as an administrator.")
#define SZ_CHKFORUPDATES_ADMINREQ_1	_L("Check for Updates requires that you run Origin as an administrator.") 
#define SZ_CHKFORUPDATES_ADMINREQ_2 _L("Please make sure you are logged into Windows with an account with administrator permissions.")
#define SZ_CHKFORUPDATES_ADMINREQ_3 _L("Additionally, on Windows Vista and 7, you must right-click on the Origin program icon and select 'Run as Administrator'.")
///end IMPROVE_RUN_AS_ADMINISTRATOR_MSG
#define SZ_CHKFORUPDATES_ERROR		_L("An error occurred when getting updates.\nError %d") /// EJP 2008-07-17 v8.0904 QA80-11788 IMPROVE_CHECK_FOR_UPDATES
#define SZ_CHKFORUPDATES_IS_RUNNING	_L("Check for Updates is already getting updates.") /// EJP 2008-07-21 v8.0906 QA80-11788 PREVENT_MULTIPLE_CHECK_FOR_UPDATES

class CheckForUpdatesDlg : public ResizeDialog   
{
public:
	CheckForUpdatesDlg() : ResizeDialog(IDD_CHKFORUPDATES, "ODlg8") 
	{
	}

	DWORD DoModalEx(HWND hParent, UpdatesTree& trUpdates)
	{
		m_hwndParent = hParent; /// EJP 2008-07-21 v8.0906 QA80-11788 PREVENT_MULTIPLE_CHECK_FOR_UPDATES

		// Is there a better way to do this?  Pointer?
		m_trUpdates.XML = trUpdates.XML;

		InitMsgMap();// will be called from internal later
		int nRet = DoModal(hParent);
		if(IDOK == nRet)
		{
			return 1;
		}
		return 0;
	}

protected:
	
	EVENTS_BEGIN
		ON_INIT( OnInitDialog )
		ON_DESTROY(OnDestroy)
		ON_SIZE(OnDlgResize)
		ON_OK(OnOK)
		ON_CANCEL(OnCancel)
		ON_GRID_BEFORE_EDIT(IDC_UPDATES_LIST, OnBeforeEdit)
		ON_GRID_SEL_CHANGE(IDC_UPDATES_LIST, OnSelChange)
		ON_BN_CLICKED(IDC_CHECK_ALL, OnCheckAll)
		ON_BN_CLICKED(IDC_UNCHECK_ALL, OnUncheckAll)
	EVENTS_END
	
	BOOL OnInitDialog()
	{
		// Get the initial client rect height.
		// This will be used when resizing the dialog.
		RECT rc;
		GetClientRect(&rc);
		m_nClientHeight = rc.bottom;
		m_nClientWidth = rc.right;

		Control ctrl = GetItem(IDC_UPDATES_LIST);
		ctrl.GetWindowRect(&rc);
		ScreenToClient(&rc);
		m_nCtrlGap = rc.left;
		
		m_updatesList.Init(IDC_UPDATES_LIST, *this);
		m_updatesList.UpdateGrid(m_trUpdates);
		m_updatesList.SetCheckForAllItems();
		
		ShowWindow(SW_NORMAL);
		return TRUE;
	}

	BOOL OnDestroy(void)
	{
		ResizeDialog::OnDestroy();
		return true;
	}

public:
	BOOL OnOK()
	{
		/// EJP 2008-07-11 v8.0901 QA80-11788 IMPROVE_CHECK_FOR_UPDATES
		///StringArray saFileNames;
		///if( GetCheckedItemFileName(saFileNames) )
		///	getUpdatedFiles(saFileNames);
		StringArray saTitles;
		m_updatesList.GetCheckedItemTitle(saTitles, FALSE); // FALSE = get unchecked items
		m_trUpdates.RemoveUpdatesByTitle(saTitles);
		int nRet = http_get_updates(&m_trUpdates, NULL, HTTP_SHOW_PROGRESS_BAR | HTTP_DO_IN_THREAD);
		if( nRet )
		{
			/// EJP 2008-07-21 v8.0906 QA80-11788 PREVENT_MULTIPLE_CHECK_FOR_UPDATES
			///	HWND hwnd = GetSafeHwnd();
			///	string strMsg;
			///	strMsg.Format(SZ_CHKFORUPDATES_ERROR, nRet);
			///	MessageBox(hwnd, strMsg, SZ_CHKFORUPDATES_TITLE, MB_OK);
			string strMsg;
			strMsg.Format(SZ_CHKFORUPDATES_ERROR, nRet);
			MessageBox(m_hwndParent, strMsg, SZ_CHKFORUPDATES_TITLE, MB_OK);
			/// end PREVENT_MULTIPLE_CHECK_FOR_UPDATES
		}
		/// end IMPROVE_CHECK_FOR_UPDATES

		return TRUE;
	}

	BOOL OnCancel()
	{	
		return TRUE;
	}

	BOOL OnCheckAll(Control cntrl)
	{
		m_updatesList.SetCheckForAllItems();
		return TRUE;
	}

	BOOL OnUncheckAll(Control cntrl)
	{
		m_updatesList.SetCheckForAllItems(false);
		return TRUE;
	}

	BOOL OnDlgResize(int nType, int cx, int cy)
	{
		// An array of IDs for the controls below the grid control
		static int s_nIDs[] = {
			IDC_CHECK_ALL, IDC_UNCHECK_ALL,
			IDC_DESCRIP_LABEL, IDC_ITEM_DESCRIPTION,
			IDOK, IDCANCEL,
			0};

		RECT rcClient;
		GetClientRect(&rcClient);

		RECT rcCtrl;
		Control ctrl;

		// Shift up or down all the controls below the grid control
		
		int nWidthDiff = rcClient.right - m_nClientWidth;
		int nHeightDiff = rcClient.bottom - m_nClientHeight;

		int i = 0;
		while( s_nIDs[i] )
		{
			ctrl = GetItem(s_nIDs[i]);
			ctrl.GetWindowRect(&rcCtrl);
			ScreenToClient(&rcCtrl);
			rcCtrl.top += nHeightDiff;
			rcCtrl.bottom += nHeightDiff;
			MoveControl(ctrl, rcCtrl);
			i++;
		}
		
		m_nClientWidth = rcClient.right;
		m_nClientHeight = rcClient.bottom;

		// Adjust width and height of grid control

		ctrl = GetItem(IDC_UPDATES_LIST);
		ctrl.GetWindowRect(&rcCtrl);
		ScreenToClient(&rcCtrl);
		rcCtrl.right += nWidthDiff;
		rcCtrl.bottom += nHeightDiff;
		MoveControl(ctrl, rcCtrl);

		// Adjust width of description control

		ctrl = GetItem(IDC_ITEM_DESCRIPTION);
		ctrl.GetWindowRect(&rcCtrl);
		ScreenToClient(&rcCtrl);
		rcCtrl.right += nWidthDiff;
		MoveControl(ctrl, rcCtrl);

		// Adjust Check All and Uncheck All buttons to right side of dialog

		int x = posCtrlByRightSide(IDC_UNCHECK_ALL, rcClient.right - m_nCtrlGap);
		posCtrlByRightSide(IDC_CHECK_ALL, x - m_nCtrlGap);

		// Adjust OK and Cancel buttons to right side of dialog

		x = posCtrlByRightSide(IDCANCEL, rcClient.right - m_nCtrlGap);
		posCtrlByRightSide(IDOK, x - m_nCtrlGap);

		return TRUE;
	}

	void OnSelChange(Control cntrl)
	{
		string strTitle;
		if( !m_updatesList.GetSelectedTitle(strTitle) )
			return;
		string strDescrip;
		if( !m_trUpdates.GetDescriptionByTitle(strTitle, strDescrip) )
			return;
		Control ctrl = GetItem(IDC_ITEM_DESCRIPTION);
		ctrl.Text = strDescrip;
	}

	void OnBeforeEdit(Control flxControl, long nRow, long nCol, BOOL* pCancel)
	{
		// We only allow editing the checkbox column.
		*pCancel = !m_updatesList.IsCheckBoxCol(nCol);
	}

	int GetCheckedItemFileName(StringArray& saFileNames)
	{
		StringArray saTitles;
		m_updatesList.GetCheckedItemTitle(saTitles);

		string strFileName;
		for( int i = 0; i < saTitles.GetSize(); i++ )
		{
			if( m_trUpdates.GetFileNameByTitle(saTitles[i], strFileName) )
				saFileNames.Add(strFileName);
		}
		return saFileNames.GetSize();
	}

private:
	HWND m_hwndParent; /// EJP 2008-07-21 v8.0906 QA80-11788 PREVENT_MULTIPLE_CHECK_FOR_UPDATES

	int m_nCtrlGap;
	int m_nClientHeight;
	int m_nClientWidth;

	UpdatesTree m_trUpdates;
	OriginUpdatesList m_updatesList;

	int posCtrlByRightSide(uint nID, int nRight)
	{
		Control ctrl = GetItem(nID);
		RECT rcCtrl;
		ctrl.GetWindowRect(&rcCtrl);
		ScreenToClient(&rcCtrl);
		int nWidth = rcCtrl.right - rcCtrl.left;
		rcCtrl.right = nRight;
		rcCtrl.left = nRight - nWidth;
		MoveControl(ctrl, rcCtrl);
		return rcCtrl.left;
	}
	bool isEXEfile(LPCSTR lpcszFilename)
	{
		char szTemp[MAXLINE];
		char szTempFilename[MAX_PATH];
		lstrcpyn(szTempFilename, lpcszFilename, MAX_PATH);
		if(!check_add_file_ext(szTempFilename, NULL, szTemp)) // has Ext
		{
			if(lstrcmpi(szTemp, "EXE")==0)
				return true;
		}
		return false;
	}
#ifdef JUNK /// EJP 2008-07-11 v8.0901 QA80-11788 IMPROVE_CHECK_FOR_UPDATES
	int getUpdatedFiles(StringArray& saSubFileNames)
	{
		StringArray saURLs, saFileNames;

		string strTargetPath = GetOriginPath();
		
		/// EJP 2008-06-19 v8.0888 NEW_CHKFORUPDATES_NEED_HANDLE_PATCH
		WORD wCtrl = HTTP_SHOW_PROGRESS_BAR | HTTP_DO_IN_THREAD;
		int nPatchFileIndex = -1; // -1 = not set


		string str;
		for( int i = 0; i < saSubFileNames.GetSize(); i++ )
		{
			str.Format(O_DOWNLOAD_UPDATE_URL"%s", saSubFileNames[i]);
			saURLs.Add(str);

			str.Format("%s%s", strTargetPath, saSubFileNames[i]);
			str.Replace('/', '\\');

			/// EJP 2008-06-19 v8.0888 NEW_CHKFORUPDATES_NEED_HANDLE_PATCH
			if( nPatchFileIndex < 0 && isEXEfile(str) )
			{
				wCtrl |= HTTP_GETTING_PATCH;
				nPatchFileIndex = i; // need pass patch file index in lParam
			}
			/// end NEW_CHKFORUPDATES_NEED_HANDLE_PATCH
			
			saFileNames.Add(str);
		}

		/// EJP 2009-02-12 PREVENT_UNWANTED_TIMEOUT
		///	/// EJP 2008-06-19 v8.0888 NEW_CHKFORUPDATES_NEED_HANDLE_PATCH
		///	///return http_get_files(&saURLs, &saFileNames, NULL, wCtrl);
		///	return http_get_files(&saURLs, &saFileNames, NULL, wCtrl, nPatchFileIndex);
		///	/// end NEW_CHKFORUPDATES_NEED_HANDLE_PATCH
		return http_get_files(&saURLs, &saFileNames, NULL, wCtrl, 0, nPatchFileIndex);
		/// end PREVENT_UNWANTED_TIMEOUT
	}
#endif // JUNK /// end IMPROVE_CHECK_FOR_UPDATES
};

int DoCheckForUpdatesDlg()
{
	HWND hwndParent = GetWindow();
	
	/// EJP 2008-07-21 v8.0906 QA80-11788 PREVENT_MULTIPLE_CHECK_FOR_UPDATES
	if( http_is_getting_updates() )
	{
		MessageBox(hwndParent, SZ_CHKFORUPDATES_IS_RUNNING, SZ_CHKFORUPDATES_TITLE, MB_OK);
		return 0;
	}
	/// end PREVENT_MULTIPLE_CHECK_FOR_UPDATES

	///DSC 3/12/08 QA70-10997 v8.0823 MORE_TEST_FOR_ADMININ_WHEN_WRITE_TO_EXE_PATH
	if(!is_running_as_administrator(TRUE)) // require admin on Vista only, else require write access.
	{
		///DSC 6/18/2010 ORG-212 IMPROVE_RUN_AS_ADMINISTRATOR_MSG
		//MessageBox(hwndParent, SZ_CHKFORUPDATES_ADMINREQ, SZ_CHKFORUPDATES_TITLE, MB_OK);
		string strAdminReq;
		strAdminReq.Format("%s\n%s\n%s", SZ_CHKFORUPDATES_ADMINREQ_1, SZ_CHKFORUPDATES_ADMINREQ_2, SZ_CHKFORUPDATES_ADMINREQ_3);
 		MessageBox(hwndParent, strAdminReq, SZ_CHKFORUPDATES_TITLE, MB_OK);
		///end IMPROVE_RUN_AS_ADMINISTRATOR_MSG

		return 0;
	}
	///end MORE_TEST_FOR_ADMININ_WHEN_WRITE_TO_EXE_PATH

	///DSC 2/4/08 QA70-10997 v8.0801 TEST_FOR_ADMININ_WHEN_WRITE_TO_EXE_PATH
	if( !is_path_normal_writable(okutil_get_origin_path(ORIGIN_PATH_SYSTEM)) )
	{
		MessageBox(hwndParent, SZ_CHKFORUPDATES_WRITEABLEREQ, SZ_CHKFORUPDATES_TITLE, MB_OK);
		return 0;
	}
	///end TEST_FOR_ADMININ_WHEN_WRITE_TO_EXE_PATH
	
	char szSN[128], szCID[128];
	if( 0 == okutil_get_serial_number(szSN, szCID, TRUE) || 0 == szCID[0] )
	{
		MessageBox(hwndParent, SZ_CHKFORUPDATES_REGREQ, SZ_CHKFORUPDATES_TITLE, MB_OK);
		return 0;
	}

	UpdatesTree trUpdates;
	if( 0 == trUpdates.LoadFromServer() )
	{
		trUpdates.RemoveOlderUpdates();

		/// EJP 2009-01-08 v8.0995 QA80-12393 DISPLAY_MSG_FROM_SERVER
		int nMsg = trUpdates.CheckAndShowMessage(hwndParent);
		if( 0 == nMsg )
			return 0;
		/// end DISPLAY_MSG_FROM_SERVER

		if( 0 == trUpdates.GetNumberOfUpdates() )
		{
			MessageBox(hwndParent, SZ_CHKFORUPDATES_NONE, SZ_CHKFORUPDATES_TITLE, MB_OK);
			return 0;
		}
	}

	CheckForUpdatesDlg dlg;
	dlg.DoModalEx(hwndParent, trUpdates);

	return 0;
}
