/*------------------------------------------------------------------------------*
 * 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"


#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


#define XF_TITLE_NAME 			"XFunction"
#define XF_FILE_EXT				"OXF"
#define OPX_TITLE_NAME 			"OPX"
#define OPX_FILE_EXT			"OPX"
#define FDF_TITLE_NAME 			"FDF"
#define FDF_FILE_EXT			"FDF"
#define OPATCH_TITLE_NAME 		"Origin Pacth"
#define OPATCH_FILE_EXT			"EXE"


/// AW 10/13/05 ADD_SUPPORT_FOR_DIFF_WEBSITE_ADDRESS
#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 UploadFileDlg;
static UploadFileDlg *s_pCheckForUpdatedlg = NULL;


enum
{
	CHK_RESET_UPLOAD = 1,
	CHKS_SET_UPLOAD,
	CHK_UPLOADING,
};

static bool _get_help_text(vector<char>& vc, const TreeNode& tr, string& str)
{
	vc.SetSize(0);
	if(!tr || tr.IsEmpty())
		return false;
	if(tr.TypeID != TNVAL_TYPE_CHAR_VECTOR)
	{
		str = tr.strVal;
		if(str.GetLength() < 10000)// it seems that Word doc has a min size of about 20k, and typical text is very small
		{
			printf("failed to get vector<char> from %s node(typeid = %d), using string instead\n", tr.tagName, tr.TypeID);
			return false;
		}
	}
	try {
		vc = tr.bVals;	
	}
	catch(int nErr)
	{
		out_int("_get_help_text err = ", nErr);
		return false;
	}
	return true;	
}

class UploadFileDlg : public TreeEditDlg   
{
public:
	UploadFileDlg(string strUserName, string strPWD, BOOL bDeleteOnDestroy = FALSE) : TreeEditDlg(IDD_CHK_FOR_UPDATES, "ODlg8" )
	{
		m_bDeleteOnDestroy = bDeleteOnDestroy;
		m_strUserName = strUserName;
		m_strPWD = strPWD;
		try
		{
			m_TestCheckUpdates = CreateObject("OSoap.OCheckForUpdates");
		
			if( NULL == m_TestCheckUpdates )
				MessageBox(NULL, "Can't initialize OSoap COM!!!", "Error");				
	
			m_bError = false;
		}
		catch(int nError)
		{
			MessageBox(NULL, "Can't init Soap");
			m_bError = true;
		}
		
	}
protected:
	BOOL	m_bDeleteOnDestroy, m_bError;
	int 	m_nStage;
	string	m_strMsg;
	string	m_strResult;
	string  m_strSavedFilePath;
	string 	m_strUserName, m_strPWD;
	Tree	m_trResult;
	Object 	m_txText;
	Object  m_TestCheckUpdates;
	StringArray m_arrStrFiles;
	vector<int> m_arrIndex;

	
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;
	}
	BOOL IsValid() { return !m_bError; }

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 = CHK_RESET_UPLOAD;
		UpdateDlg();
		UpdateDlgSize();
		SetInitReady();
		m_treeEditCntrl.SetReady();
		ShowWindow(SW_NORMAL);
		return TRUE;
	}
	BOOL OnHttpAct(Control cntrl)
	{
		switch ( m_nStage )
		{
		case CHK_RESET_UPLOAD:        //
			int nFileCount = GetFileNames(m_trResult);
			if ( 0 == nFileCount )
			{
				m_nStage = CHK_RESET_UPLOAD;		// let user reselect from files
			}
			else
			{	
				m_nStage = CHKS_SET_UPLOAD;
				SetSelectedFiles();
			}
			break;
		case CHKS_SET_UPLOAD:
			
			UploadFiles();
			m_nStage = CHKS_SET_UPLOAD;
			SetSelectedFiles();
			break			
		case CHK_UPLOADING:
			
			m_nStage = CHKS_SET_UPLOAD;
			break;
		default:
			ASSERT(FALSE);
			return false;
		}
		UpdateDlg();
		return true;
	}
	void OnSelChange(Control cntrl)
	{
		if(m_treeEditCntrl.IsReady())
		{
			int  nIndex = m_treeEditCntrl.GetSelectedRow();
			updateDescription(nIndex);
		}
	}
	BOOL OnDestroy(void)
	{
		TreeEditDlg::OnDestroy();
		if(m_bDeleteOnDestroy)
		{
			delete this;
			s_pCheckForUpdatedlg = NULL;
		}
		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 SetSelectedFiles()
	{
		m_treeEditCntrl.SetReady(false);
		m_trResult.Save(GetAppPath(TRUE)+"result.xml");
		m_treeEditCntrl.SetVisible(TRUE);	
		SetupParamTree(m_trResult);
		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);
		m_treeEditCntrl.SetReady(true);
	}
	
	int GetFileType(string& strPath)
	{
		string strExt = strPath.Right(3);
		if ( strExt.Compare(XF_FILE_EXT) == 0 )
			return FILE_CATEGORY_XF;
		if ( strExt.Compare(FDF_FILE_EXT) == 0 )
			return FILE_CATEGORY_FDF;
		if ( strExt.Compare(OPX_FILE_EXT) == 0 )
			return FILE_CATEGORY_MODULE;
		if ( strExt.Compare(OPATCH_FILE_EXT) == 0 )
			return FILE_CATEGORY_PATCH;
		return FILE_CATEGORY_OTHER;
	}
	
	int GetFileNames(TreeNode& TrResult )
	{


		int iNumSelFiles;
		string strPath, strTemp;
		StringArray saFiletypes, saFilePaths;
		saFiletypes.SetSize( 4 );
		strTemp.Format("[%s (.%s)] *.%s", XF_TITLE_NAME, XF_FILE_EXT, XF_FILE_EXT);
		saFiletypes[0] = strTemp;
		strTemp.Format("[%s (.%s)] *.%s", OPX_TITLE_NAME, OPX_FILE_EXT, OPX_FILE_EXT);
		saFiletypes[1] = strTemp;
		strTemp.Format("[%s (.%s)] *.%s", FDF_TITLE_NAME, FDF_FILE_EXT, FDF_FILE_EXT);
		saFiletypes[2] = strTemp;
		strTemp.Format("[%s (.%s)] *.%s", OPATCH_TITLE_NAME, OPATCH_FILE_EXT, OPATCH_FILE_EXT);
		saFiletypes[3] = strTemp;
		
		iNumSelFiles = GetMultiOpenBox( saFilePaths, saFiletypes ); // or
		int nFileType;
		int nErrFileNum = 0;
		Tree trInfo;
		bool bOK;
		TrResult.Reset();
		m_arrStrFiles.SetSize(0);
		if ( !okutil_create_file_info_tree(&trInfo) )
		{
			MessageBox(NULL, "Can't Init XF tree", "Message");
			return 0;
		}
		for ( int ii = 0; ii < iNumSelFiles; ii++ )
		{
			bOK = false;
			strPath = saFilePaths[ii];
			nFileType = GetFileType(strPath);
			switch ( nFileType )
			{
			case FILE_CATEGORY_XF:
				strTemp = XF_TITLE_NAME;
				bOK = okutil_get_XF_file_info(strPath, &trInfo);
				if ( bOK )
					bOK = HandleSummary(trInfo);
				break;
			case FILE_CATEGORY_FDF:
				strTemp = OPX_TITLE_NAME;
				MessageBox(NULL, "will be ready soon", "Message");
				break;
			case FILE_CATEGORY_MODULE:
				strTemp = OPX_TITLE_NAME;
				MessageBox(NULL, "will be ready soon", "Message");
				break;
			case FILE_CATEGORY_PATCH:
				strTemp = OPATCH_TITLE_NAME;
				MessageBox(NULL, "will be ready soon", "Message");
				break;
			default:
				strTemp.Format( "%s is invalid file type!");
				nErrFileNum++;
				MessageBox(NULL, strTemp, "Error");
			}
			if ( bOK )
			{
				TrResult.AddNode(trInfo);
				m_arrStrFiles.Add(strPath);
				
			}
		}
		return TrResult.GetNodeCount();
	}
	
	bool HandleSummary(TreeNode& trInfo)
	{
		_VARIANT  var;
		vector<char> vcVals;
		bool bOK = true;;
		string strVal;
		vcVals.SetSize(0);
		
		try
		{
			TreeNode trSummary = trInfo.GetNode("Summary");
			if ( _get_help_text(vcVals, trSummary, strVal) )
			{
				var = vcVals.GetDataAsOneDimensionalArray();
				bOK =  m_txText.LoadFromMemory(var, 9);
				if ( !bOK)
					error_report("TX control fail to read doc format inform");
				else
				{
					strVal = m_txText.SaveToMemory(6);
					trInfo.RemoveChild("Summary");
					trInfo.AddTextNode(strVal, "Summary");
				}
			}
		}
		catch (int nErr )
		{
			error_report("Fail to get summary");
			return false;
		}
		return bOK;

		
	}
	
	void UpdateDlg()
	{
		Button cCancelBtn = GetItem(IDCANCEL);
		Button cActionBtn = GetItem(IDC_HTTP_ACTION);
		switch ( m_nStage )
		{
		case CHK_RESET_UPLOAD:        //
			cActionBtn.Text = "Select Files";
			//m_trResult = GetFileNames();
			break;
		case CHKS_SET_UPLOAD:
			//GetSelectedFiles();
			cActionBtn.Text = "Upload Files";
			break;
		case CHK_UPLOADING:
			cActionBtn.Text = "Abort";
			cCancelBtn.Visible = FALSE;
			break;
		default:
			ASSERT(FALSE);
		}
		OnDlgResize(0, GetDlgExtent(false), GetDlgExtent(true));
	}
	
	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 SetupParamTree(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;
	}
	
	
	int GetSelectFiles()
	{
		TreeNode tr = m_paramTree;
		int nIndex = 0;
		foreach(TreeNode trSection in tr.Children)
		{
			if(0 != trSection.chk.nVal)
			{
				m_arrIndex.Add(nIndex);
			}
			nIndex++;
		}
		return m_arrIndex.GetSize();
	}
		
	void UploadFiles()
	{
		int nRet;
		TreeNode tr = m_paramTree;
		int nIndex = 0;
		string strMsg, strInfo;
		TreeNode trTemp;
		
		int nUserID = -1;
		
		nUserID = m_TestCheckUpdates.GetAuthorID(m_strUserName, m_strPWD);
		if ( 0 == nUserID ) 
		{
			error_report("Fail to link server");
			return;
		}
		else if ( 0 > nUserID )
		{
			error_report("Invalid UserName/Password");
			return;
		}
		else
		{
			// set userID info
			foreach(TreeNode trSection in tr.Children)
			{
				if(0 != trSection.chk.nVal)
				{
					strMsg.Format("Upload %s ?", m_arrStrFiles[nIndex]); 
					if(IDCANCEL == MessageBox(NULL, strMsg, "Messgae", MB_OKCANCEL)) // For Safe, stop programming upload
						return;
					trTemp = m_trResult.Children.Item(nIndex);
					
					TreeNode TrAuthorID = trTemp.GetNode("AuthorID");
					TrAuthorID.nVal = nUserID;
					strInfo = trTemp.XML;
					try
					{
						nRet = m_TestCheckUpdates.UploadFile(strInfo, m_arrStrFiles[nIndex]);
					}
					catch ( int nErr)
					{
						nRet = -1;					
					}
					if ( nRet != 0 )
					{
						strMsg.Format("Fail to upload %s", m_arrStrFiles[nIndex] );
						error_report(strInfo);	
					}
					m_trResult.RemoveChild(nIndex);
				}
				nIndex++;
			}
		}
	}

	

	LPCSTR GetResult()
	{
		return m_strResult;		
	}

		

};

void UploadXF()
{
	static UploadFileDlg* s_pDlg;
	
	if(s_pDlg)
	{
		Window winDlg = s_pDlg->GetWindow();
		if(winDlg)
			winDlg.SendMessage(WM_CLOSE);
		
		delete s_pDlg;
		s_pDlg = NULL;
	}
	s_pDlg = new UploadFileDlg();
	if ( !s_pDlg->IsValid() )
	{
		error_report("Upload files failed!");
		return;
	}
	
	s_pDlg->Create(GetWindow());
	out_str("-------------- Done!!! ----------------");
}


