#include <origin.h>
#include <GetNBox.h>
#include <xfutils.h>

//put additional include files here

/* Modification Log:															*
* Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE								*
*/

//put your own support static functions here
#define CDSET_INI_SECTION "cdset"

///Joseph 06/26/07 FIX_BUG_DOT_DOT_NOT_WORK
static bool _is_path_unassigned(LPCSTR lpcszPath)
{
	string strPath(lpcszPath);
	if(strPath.IsEmpty() || okutil_cvt_str_to_predefined_type(strPath) == PDS_UNASSIGNED)
		return true;
	
	return false;
}



void cd(const string& newpath, string& result)
{
	string workingfolder;
	
	///Cheney 2007-7-2 UPDATE_XF_ERR_THROW
	string strMsg, strCWD;
	ocu_load_msg_str(XF_SYSTEM_CURRENT_WORKING_FOLDER, &strCWD);
	///end UPDATE_XF_ERR_THROW
	
	if(_is_path_unassigned(newpath))
	{
		workingfolder = okutil_get_custom_path(true);// true means update map 
		if(result) // str variable is specified, default is <optional> which will result into invalid str
		{
			result = workingfolder;
		}
		else
		{
			if(workingfolder.IsEmpty())
			{
				///Cheney 2007-7-2 UPDATE_XF_ERR_THROW
				//printf("%s is not defined\n", STR_C_W_D);
				/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
				//warning_msg_box(XF_CD_UNDIFINE, strCWD, false, 'E');
				XF_THROW_EX(XF_CD_UNDIFINE, strCWD);
				///end UPDATE_XF_ERR_THROW
			}
			else
			{
				/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
				//printf("%s:\n%s\n", strCWD, workingfolder);	
				string str;
				str.Format("%s:\n%s", strCWD, workingfolder);
				warning_msg_box(str, false, 'R');
				///End CLEANUP_XFS_ERROR_CODE
			}
		}
		return;
	}	
	// only handle 0 - 9 supported
	if( newpath.GetLength()==1 && '0'<=newpath[0] && newpath[0]<='9')
	{
		int nIndex = atoi(newpath);
		if(0==nIndex)//clear working dir
		{
			okutil_set_custom_path("");
			///Cheney 2007-7-2 UPDATE_XF_ERR_THROW
			//printf("%s is undefined\n", STR_C_W_D);
			/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
			//warning_msg_box(XF_CD_UNDIFINE, strCWD, false, 'E');
			XF_THROW_EX(XF_CD_UNDIFINE, strCWD);
			///End CLEANUP_XFS_ERROR_CODE
			///end UPDATE_XF_ERR_THROW
		}
		else
		{
			INIFile ini;
			string str = ini.ReadString(CDSET_INI_SECTION, newpath);
			if( str.IsEmpty() )
			{
				///Cheney 2007-7-2 UPDATE_XF_ERR_THROW
				//printf("Index %s is not assigned a path\n", newpath);
				/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
				//warning_msg_box(XF_CD_NOT_ASSIGN_PATH, newpath, false, 'E');
				XF_THROW_EX(XF_CD_NOT_ASSIGN_PATH, newpath);
				///End CLEANUP_XFS_ERROR_CODE
				///end UPDATE_XF_ERR_THROW
			}
			else
			{
				string strResolved;
				okutil_resolve_str_expression(str , &strResolved);
				
				if( strResolved.IsPath() )
				{
					okutil_set_custom_path(strResolved);
					if(result)
						result = strResolved;						
					/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
					//printf("%s:\n%s\n", strCWD, strResolved);
					string str;
					str.Format("%s:\n%s", strCWD, strResolved);
					warning_msg_box(str, false, 'R');
					///End CLEANUP_XFS_ERROR_CODE
				}
				else
					///Cheney 2007-7-2 UPDATE_XF_ERR_THROW
					//printf("Index %s is assigned invalid path %s\n", newpath, strResolved);
				{
					ocu_load_msg_str(XF_CD_ASSIGN_INVALID_PATH, &strMsg, newpath, NULL, strResolved);
					/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
					//warning_msg_box(strMsg, false, 'E');
					XF_THROW(strMsg);
					///End CLEANUP_XFS_ERROR_CODE
				}
					///end UPDATE_XF_ERR_THROW
			}					
		}
		return;
	}
	//-- go back one directory
	if(0==newpath.Compare("..")|| 0==newpath.Compare("..\\"))
	{
		workingfolder = okutil_get_custom_path();
		if( workingfolder.ReverseFind('\\') == workingfolder.GetLength()-1)
			workingfolder.Delete(workingfolder.GetLength()-1, 1);
		int nBackslash = workingfolder.ReverseFind('\\');
		string newworkdir = workingfolder.Left(nBackslash+1);
		if(newworkdir.IsPath())
		{
			okutil_set_custom_path(newworkdir);
			if(result)
				result = newworkdir;
			/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
			//printf("%s:\n%s\n", strCWD, newworkdir);
			string str;
			str.Format("%s:\n%s", strCWD, newworkdir);
			warning_msg_box(str, false, 'R');
			///End CLEANUP_XFS_ERROR_CODE
		}
		else
		{
			///Cheney 2007-7-2 UPDATE_XF_ERR_THROW
			//printf("%s: parent path invalid\n",newworkdir); 
			/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
			//warning_msg_box(XF_CD_PARENT_PATH_INVALID, newworkdir, false, 'E');
			XF_THROW_EX(XF_CD_PARENT_PATH_INVALID, newworkdir);
			///End CLEANUP_XFS_ERROR_CODE
			///end UPDATE_XF_ERR_THROW
		}
		return;
	}
	else if(0==newpath.Compare("\\")) // \ means go to root "c:\" or "\\name\"
	{
		workingfolder = okutil_get_custom_path();
		string newworkdir;
		if( 1 == workingfolder.Find(":") && 2 == workingfolder.Find("\\")) // have "c:\"
			newworkdir = workingfolder.Left(2+1);
		else if( 0 == workingfolder.Find("\\\\") ) // have "\\name\"
		{
			int nPos = workingfolder.Find("\\", 2);
			if (nPos<0)
				nPos=workingfolder.GetLength(); 
			newworkdir = workingfolder.Left(nPos+1);	
		}
		if(newworkdir.IsPath())
		{
			okutil_set_custom_path(newworkdir);
			if(result)
				result = newworkdir;
			
			/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
			//printf("%s:\n%s\n", strCWD, newworkdir);
			string str;
			str.Format("%s:\n%s", strCWD, newworkdir);
			warning_msg_box(str, false, 'R');
			///End CLEANUP_XFS_ERROR_CODE
		}
		else
		{
			///Cheney 2007-7-2 UPDATE_XF_ERR_THROW
			//printf("%s could not be applied to %s\n", newpath, STR_C_W_D);
			ocu_load_msg_str(XF_CD_ASSIGN_INVALID_PATH, &strMsg, newpath, NULL, strCWD);
			/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
			//warning_msg_box(strMsg, false, 'E');
			XF_THROW(strMsg);
			///end UPDATE_XF_ERR_THROW
		}
		return;
	}
	// eliminate strings like /, \\, ..., are invalid but still accepted IsPath(), 
	// ex c:\Origin\... is accepted by IsPath
	else if(	0==newpath.Compare("/")
			|| 0==newpath.Compare(".")
			|| 0==newpath.Compare(".\\")
			//|| 0==newpath.Find("..")
			|| 0<=newpath.Find("...")
			|| 0==newpath.Compare("\\\\") // but "\\\\unc\\share" allowed
			|| 0<newpath.Find("\\\\")
			|| 0<=newpath.Find("\\\\\\")
			) 
	{
		///Cheney 2007-7-2 UPDATE_XF_ERR_THROW		
		//printf("%s is not a valid path or subdirectory\n", newpath);
		/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
		//warning_msg_box(XF_CD_INVALID_PATH_OR_SUBDIR, newpath, false, 'E');
		XF_THROW_EX(XF_CD_INVALID_PATH_OR_SUBDIR, newpath);
		///End CLEANUP_XFS_ERROR_CODE
		///end UPDATE_XF_ERR_THROW
		return;
	}
	//-- user entered path
	string strNewpathResolved;
	okutil_resolve_str_expression(newpath , &strNewpathResolved);
	// If user enters relative path, create full path relative to custom path.
	// otherwise IsPath() will examine it relative to another choice of cwd 
	if(!strNewpathResolved.IsEmpty() &&  1!=strNewpathResolved.Find(":\\") && 0!=strNewpathResolved.Find("\\\\") )
	{
		workingfolder = okutil_get_custom_path();
		workingfolder=workingfolder+strNewpathResolved;
		strNewpathResolved = workingfolder;
		
	}
	if(strNewpathResolved.IsPath())
	{
		okutil_set_custom_path(strNewpathResolved);
		if(result)
			result = strNewpathResolved;
		
		/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
		//printf("%s:\n%s\n", strCWD, strNewpathResolved);
		string str;
		str.Format("%s:\n%s", strCWD, strNewpathResolved);
		warning_msg_box(str, false, 'R');
		///End CLEANUP_XFS_ERROR_CODE
	}
	else
	{
		if(!strNewpathResolved.IsEmpty())
		{
			///Cheney 2007-7-2 UPDATE_XF_ERR_THROW
			//printf("%s is not a valid path.\n", strNewpathResolved);
			/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
			//warning_msg_box(XF_CD_NOT_VALID_PATH, strNewpathResolved, false, 'E');
			XF_THROW_EX(XF_CD_NOT_VALID_PATH, strNewpathResolved);
			///End CLEANUP_XFS_ERROR_CODE
			///end UPDATE_XF_ERR_THROW
		}
		else 
		{
			// the user entered empty string ""
			// This means set custom path to empty
			okutil_set_custom_path("");
			///Cheney 2007-7-2 UPDATE_XF_ERR_THROW
			//printf("%s is undefined\n", STR_C_W_D);
			/// Iris 10/21/2010 ORG-1303 CLEANUP_XFS_ERROR_CODE
			//warning_msg_box(XF_CD_UNDIFINE, strCWD, false, 'E');
			XF_THROW_EX(XF_CD_UNDIFINE, strCWD);			
			///End CLEANUP_XFS_ERROR_CODE
			///end UPDATE_XF_ERR_THROW
		}
	}
	
}

//nGetNDialog = 0,1,2, corresponding to the XF GetN dropdown, 0 = dialog is not used
//you can change nRet to be one of XFEVT_PROCEED (defualt), XFEVT_ABORT, XFEVT_PROCEED_NO_DLG or XFEVT_PROCEED_WITH_DLG(when nGetNDialog = 0)
//nGetNDialog = -1 when Ok on GetN dialog to allow handler to preocess <auto> etc variables
//dwCntrl is combination of bits
//LTXF_FROM_GUI_MENU, LTXF_FROM_GUI_PROMPT, LTXF_FROM_AUTO_UPDATE, LTXF_FROM_FUNCTION, LTXF_THEME_USED, LTXF_CHANGE_PARAM
void cd_before_execute(TreeNode& trGetN, int nGetNDialog, int& nRet, int dwCntrl)
{

}
