////The following declaration and initiations is on behalf of the sorting functions.
var Stack = new Array();
var Top;

Top=-1;


/*******************************************************************
Returns a String containing a copy of a specified string without leading spaces. 

Parameters:
String - The required string argument is any valid 
         string expression. If string contains null, 
         false is returned.
Returns: String.
*******************************************************************/
function LTrim(String)
{
	var i = 0;
	var j = String.length - 1;

	if (String == null)
		return (false);

	for (i = 0; i < String.length; i++)
	{
		if (String.substr(i, 1) != ' ' && String.substr(i, 1) != '\t')
			break;
	}

	if (i <= j)
		return (String.substr(i, (j+1)-i));
	else
		return ('');
}

/*******************************************************************
Returns a String containing a copy of a specified string without trailing spaces. 

Parameters:
String - The required string argument is any valid 
         string expression. If string contains null, 
         false is returned.
Returns: String.
*******************************************************************/
function RTrim(String)
{
	var i = 0;
	var j = String.length - 1;

	if (String == null)
		return (false);

	for(j = String.length - 1; j >= 0; j--)
	{
		if (String.substr(j, 1) != ' ' && String.substr(j, 1) != '\t')
			break;
	}

	if (i <= j)
		return (String.substr(i, (j+1)-i));
	else
		return ('');
}

/*******************************************************************
Returns a String containing a copy of a specified string without 
both leading and trailing spaces .

Parameters:
String - The required string argument is any valid 
         string expression. If string contains null, 
        false is returned.
Returns: String.
*******************************************************************/
function Trim(String)
{
	if (String == null)
		return (false);
	return RTrim(LTrim(String));
}


//////////////////////////////////////
//==============Sort================//
//////////////////////////////////////
function Sort_Old(lst,start,end,flgDirection,flgSortType,flgDataType){
	/*
	* lst is the name of the list object to be sorted. i.e: document.frmProduct.lstAllProducts.
	
	* start and the end are the boundaries on the list that we need to sort with; they represent the colomn width.
	
	* The 'flgSortType' varaible may take one of the follwing three values:
	1===>QuickSort (Use it when you want to sort a header that currently is not sorted niether Asc nor Desc).
	2===>InsertionSort (Use it when you want to sort after the process of (Add/Remove) between two lists).
	3===>ConvertList (Use it when you want to sort a column that is currently sorted).

	* The 'flgDirection' varaible may take two values:
	1===>Asc
	2===>Desc
	*/
	/*
	The following lines were written to make sure that 
	no rows in the list still selected after getting the list sorted.
	Remember that this should not be applied when the sorting type is insertion flgSortType=2
	*/
	if (flgSortType!=2)
	{
	var size,intLoop;
	size=lst.length-1;
	
	for (intLoop=0;intLoop<=size;intLoop++)
		lst[intLoop].selected=false;
	}	
	if (flgSortType==1)
		{
		if (flgDirection==1)
			if (flgDataType==1)
				QuickSort_Asc_String(lst,lst.length-1,start,end);
			else
				if (flgDataType==2)
					QuickSort_Asc_Integer(lst,lst.length-1,start,end);
				else
					QuickSort_Asc_DateTime(lst,lst.length-1,start,end);
		}
	else
		if (flgSortType==2)
			if (flgDirection==1)
				InsertionSort_Asc(lst,lst.length-1,start,end);
			else
				InsertionSort_Desc(lst,lst.length-1,start,end);		
		else
			ConvertList(lst,lst.length-1);
}

//////////////////////////////////////
//==============Sort================//
//////////////////////////////////////
function Sort(lst,start,end,flgDirection,flgSortType,flgDataType){
	/*
	* lst is the name of the list object to be sorted. i.e: document.frmProduct.lstAllProducts.
	
	* start and the end are the boundaries on the list that we need to sort with; they represent the colomn width.
	
	* The 'flgSortType' varaible may take one of the follwing three values:
	1===>QuickSort (Use it when you want to sort a header that currently is not sorted niether Asc nor Desc).
	2===>InsertionSort (Use it when you want to sort after the process of (Add/Remove) between two lists).
	3===>ConvertList (Use it when you want to sort a column that is currently sorted).

	* The 'flgDirection' varaible may take two values:
	1===>Asc
	2===>Desc
	*/
	/*
	The following lines were written to make sure that 
	no rows in the list still selected after getting the list sorted.
	Remember that this should not be applied when the sorting type is insertion flgSortType=2
	*/
	if (flgSortType!=2)
	{
	var size,intLoop;
	size=lst.length-1;
	
	for (intLoop=0;intLoop<=size;intLoop++)
		lst[intLoop].selected=false;
	}	
	if (flgSortType==1)
		{
		if (flgDirection==1)
			if (flgDataType==1)
				QuickSort_Asc_String(lst,lst.length-1,start,end);
			else
				if (flgDataType==2)
					InsertionSort_Integer_Asc(lst,lst.length-1,start,end);
				else
					InsertionSort_Asc(lst,lst.length-1,start,end);
		}
	else
		if (flgSortType==2)
			if (flgDirection==1)
				InsertionSort_Asc(lst,lst.length-1,start,end);
			else
				InsertionSort_Desc(lst,lst.length-1,start,end);		
		else
			ConvertList(lst,lst.length-1);
}

//////////////////////////////////////
//==========ConvertList=============//
//////////////////////////////////////   
function ConvertList(lst,size){ 
	var I,J,Stext,Svalue;
   
		J=size;
		I=0;
		while (I<J)
		{
			Stext=lst.options[I].text;
			Svalue=lst.options[I].value;
			lst.options[I].text=lst.options[J].text;
			lst.options[I].value=lst.options[J].value;
			lst.options[J].text=Stext;
			lst.options[J].value=Svalue;
			J--;
			I++;
		}
}

//////////////////////////////////////
//=======InsertionSort_Asc==========//
//////////////////////////////////////
function InsertionSort_Asc(lst,size,start,end)
{
var I,J;
var Stext,Svalue;
var Flag;
   
		   
 if(size>=1)
	{
	for(I=1;I<=size;I++)
	 {
	  Flag=true;
	  J=I;
	  while ((J>=1) && (Flag))
	    if (TrimString(TrimString(escape(((lst.options[J].text).slice(start,end)).toUpperCase()),'%20'),'%A0') < TrimString(TrimString(escape(((lst.options[J-1].text).slice(start,end)).toUpperCase()),'%20'),'%A0'))
	    {
	      Stext=lst.options[J].text;
	      Svalue=lst.options[J].value;
	      lst.options[J].text=lst.options[J-1].text;
	      lst.options[J].value=lst.options[J-1].value;
	      lst.options[J-1].text=Stext;
	      lst.options[J-1].value=Svalue;
	      J--;
	    }
	   else
			{
	    Flag=false; 
	    }
 		}
	}
}

//////////////////////////////////////
//=======InsertionSort_Desc==========//
//////////////////////////////////////   
function InsertionSort_Desc(lst,size,start,end)
{
var I,J;
var Stext,Svalue;
var Flag;
   
   	
if(size>=1)
	{
	for(I=1;I<=size;I++)
	 {
	  Flag=true;
	  J=I;
	  while ((J>=1) && (Flag))
	    if (TrimString(TrimString(escape(((lst.options[J].text).slice(start,end)).toUpperCase()),'%20'),'%A0') > TrimString(TrimString(escape(((lst.options[J-1].text).slice(start,end)).toUpperCase()),'%20'),'%A0'))
	    {
	      Stext=lst.options[J].text;
	      Svalue=lst.options[J].value;
	      lst.options[J].text=lst.options[J-1].text;
	      lst.options[J].value=lst.options[J-1].value;
	      lst.options[J-1].text=Stext;
	      lst.options[J-1].value=Svalue;
	      J--;
	    }
	   else
			{
	    Flag=false; 
	    }
 		}
	}
}


//////////////////////////////////////
//======QuickSort_Asc_String=========//
//////////////////////////////////////
function QuickSort_Asc_String(lst,size,start,end){
var L,R,I,J,K,REFText,REFValue;
       	
	Top++;
	Stack[Top]=0;
	Top++;
	Stack[Top]=0;
	L=0;
	R=size;
		    
	do 
		{
		I=L;
		J=R;
		REFText=lst.options[L].text;
		REFValue=lst.options[L].value;            
		while (I<J)
			{
			while ((((REFText).toUpperCase()).slice(start,end)<((lst.options[J].text).toUpperCase()).slice(start,end))&&(I<J))
				{
				J--;
				}
			if (J!=I)
				{
				lst.options[I].text=lst.options[J].text;
				lst.options[I].value=lst.options[J].value;
				I++;
				}
			while((((REFText).toUpperCase()).slice(start,end)>((lst.options[I].text).toUpperCase()).slice(start,end))&&(I<J))
				{
				I++;
				}  
			if (J!=I)
				{
				lst.options[J].text=lst.options[I].text;
				lst.options[J].value=lst.options[I].value;
				J--;
				} 
			}
		lst.options[J].text=REFText;
		lst.options[J].value=REFValue;
		if (J==R)
			{
			R--;
			}  
		else
			if(I==L)
				{
				L++;
				} 
			else
				if ((I-L)<=(R-J))
					{
					K=J+1;		                      
					Top++;
					Stack[Top]=K;
					Top++;
					Stack[Top]=R;
					R=I-1;
					} 
				else
					{
					K=I-1;           
					Top++;
					Stack[Top]=L;
					Top++;
					Stack[Top]=K;		                      
					L=J+1;
					}
		if (R<=L)
			{
			R=Stack[Top];
			Top--;
			L=Stack[Top];
			Top--;
			}
		}
	while ((R!=0)||(L!=0)) ;   
}


//////////////////////////////////////
//====QuickSort_Asc_StringOld=======//
//////////////////////////////////////
function QuickSort_Asc_StringOld(lst,size,start,end){
var L,R,I,J,K,REFValue,REFText;
var Temp1 = new String();
var Temp2 = new String();
var Temp3 = new String();
       	
       	
	Top++;
	Stack[Top]=0;
	Top++;
	Stack[Top]=0;
	L=0;
	R=size;
		          
	do 
		{
		I=L;
		J=R;
		REFText=lst.options[L].text;
		REFValue=lst.options[L].value;            
		while (I<J)
			{
			Temp1=TrimString(escape((REFText).slice(start,end)),'%20');
			Temp1=TrimString(Temp1,'%A0');
			Temp1=(Temp1).toUpperCase();
			
			Temp2=TrimString(escape((lst.options[J].text).slice(start,end)),'%20');
			Temp2=TrimString(Temp2,'%A0');
			Temp2=(Temp2).toUpperCase();
			
			if (((Temp1) < (Temp2)) && (I<J))
				{
				do
				 {
				 	J--;
				  Temp2=TrimString(escape((lst.options[J].text).slice(start,end)),'%20');
				  Temp2=TrimString(Temp2,'%A0');
					Temp2=(Temp2).toUpperCase();
				 }while (((Temp1) < (Temp2)) && (I<J));
				}
				
			if (J!=I)
				{
				lst.options[I].text=lst.options[J].text;
				lst.options[I].value=lst.options[J].value;
				I++;
				}
			Temp3=TrimString(escape((lst.options[I].text).slice(start,end)),'%20');
			Temp3=TrimString(Temp3,'%A0');
			Temp3=(Temp3).toUpperCase();
			if (((Temp1)>(Temp3)) && (I<J))
				{
				do
				 {
				 I++;
				 Temp3=TrimString(escape((lst.options[I].text).slice(start,end)),'%20');
				 Temp3=TrimString(Temp3,'%A0');
				 Temp3=(Temp2).toUpperCase();
				 }while (((Temp1)>(Temp3)) && (I<J));
				}
				
			if (J!=I)
				{
				lst.options[J].text=lst.options[I].text;
				lst.options[J].value=lst.options[I].value;
				J--;
				} 
			}
		lst.options[J].text=REFText;
		lst.options[J].value=REFValue;
		if (J==R)
			{
			R--;
			}  
		else
			if(I==L)
				{
				L++;
				} 
			else
				if ((I-L)<(R-J))
					{
					K=J+1;		                      
					Top++;
					Stack[Top]=K;
					Top++;
					Stack[Top]=R;
					R=I-1;
					} 
				else
					{
					K=I-1;           
					Top++;
					Stack[Top]=L;
					Top++;
					Stack[Top]=K;		                      
					L=J+1;
					}
		if (R<=L)
			{
			R=Stack[Top];
			Top--;
			L=Stack[Top];
			Top--;
			}
		}
	while ((R!=0)||(L!=0)) ;   }


//////////////////////////////////////
//=========QuickSort_Asc_Integer============//
//////////////////////////////////////
function QuickSort_Asc_Integer(lst,size,start,end){
var L,R,I,J,K,REFValue,REFText;
var Temp1 = new String();
var Temp2 = new String();
var Temp3 = new String();
       	
	Top++;
	Stack[Top]=0;
	Top++;
	Stack[Top]=0;
	L=0;
	R=size;
		          
	do 
		{
		I=L;
		J=R;
		REFText=lst.options[L].text;
		REFValue=lst.options[L].value;            
		while (I<J)
			{
			Temp1=TrimString(escape((REFText).slice(start,end)),'%20');
			Temp2=TrimString(escape((lst.options[J].text).slice(start,end)),'%20');
			if ((parseInt(Temp1) < parseInt(Temp2)) && (I<J))
				{
				do
				 {
				 	J--;
				  Temp2=TrimString(escape((lst.options[J].text).slice(start,end)),'%20');
				 }while ((parseInt(Temp1) < parseInt(Temp2)) && (I<J));
				}
				
			if (J!=I)
				{
				lst.options[I].text=lst.options[J].text;
				lst.options[I].value=lst.options[J].value;
				I++;
				}
			Temp3=TrimString(escape((lst.options[I].text).slice(start,end)),'%20');
			if ((parseInt(Temp1)>parseInt(Temp3)) && (I<J))
				{
				do
				 {
				 I++;
				 Temp3=TrimString(escape((lst.options[I].text).slice(start,end)),'%20');
				 }while ((parseInt(Temp1)>parseInt(Temp3)) && (I<J));
				}
				
			if (J!=I)
				{
				lst.options[J].text=lst.options[I].text;
				lst.options[J].value=lst.options[I].value;
				J--;
				} 
			}
		lst.options[J].text=REFText;
		lst.options[J].value=REFValue;
		if (J==R)
			{
			R--;
			}  
		else
			if(I==L)
				{
				L++;
				} 
			else
				if ((I-L)<=(R-J))
					{
					K=J+1;		                      
					Top++;
					Stack[Top]=K;
					Top++;
					Stack[Top]=R;
					R=I-1;
					} 
				else
					{
					K=I-1;           
					Top++;
					Stack[Top]=L;
					Top++;
					Stack[Top]=K;		                      
					L=J+1;
					}
		if (R<=L)
			{
			R=Stack[Top];
			Top--;
			L=Stack[Top];
			Top--;
			}
		}
	while ((R!=0)||(L!=0)) ;   
}


//////////////////////////////////////
//=========QuickSort_Asc_DateTime============//
//////////////////////////////////////
function QuickSort_Asc_DateTime(lst,size,start,end){
var L,R,I,J,K,REFValue,REFText;
var Temp1 = new String();
var Temp2 = new String();
var Temp3 = new String();
var Date1 = new Date();       	
var Date2 = new Date();
var Date3 = new Date();

	Top++;
	Stack[Top]=0;
	Top++;
	Stack[Top]=0;
	L=0;
	R=size;
		          
	do 
		{
		I=L;
		J=R;
		REFText=lst.options[L].text;
		REFValue=lst.options[L].value;            
		while (I<J)
			{
			Temp1=TrimString(escape((REFText).slice(start,end)),'%20');
			Temp1=TrimString(Temp1,'%A0');
			Temp1=Replace('%3A',':');
			Temp2=TrimString(escape((lst.options[J].text).slice(start,end)),'%20');
			Temp2=TrimString(Temp2,'%A0');
			Temp2=Replace('%3A',':');
			
			Date2=Temp2;
			Date1=Temp1;
			if ((Date1 < Date2) && (I<J))
				{
				do
				 {
				 	J--;
				  Temp2=TrimString(escape((lst.options[J].text).slice(start,end)),'%20');
				  Temp2=TrimString(Temp2,'%A0');
				  Temp2=Replace('%3A',':');
				  Date2=Temp2;
				  alert(Date2);
				 }while ((Date1 < Date2) && (I<J));
				}
				
			if (J!=I)
				{
				lst.options[I].text=lst.options[J].text;
				lst.options[I].value=lst.options[J].value;
				I++;
				}
			Temp3=TrimString(escape((lst.options[I].text).slice(start,end)),'%20');
			Temp3=TrimString(Temp3,'%A0');
			Temp3=Replace('%3A',':');
			Date3=Temp3;
			if ((Date1 > Date3) && (I<J))
				{
				do
				 {
				 I++;
				 Temp3=TrimString(escape((lst.options[I].text).slice(start,end)),'%20');
				 Temp3=TrimString(Temp3,'%A0');
				 Temp3=Replace('%3A',':');
				 Date3=Temp3;
				 alert(Date3);
				 }while ((Date1 > Date3) && (I<J));
				}
				
			if (J!=I)
				{
				lst.options[J].text=lst.options[I].text;
				lst.options[J].value=lst.options[I].value;
				J--;
				} 
			}
		lst.options[J].text=REFText;
		lst.options[J].value=REFValue;
		if (J==R)
			{
			R--;
			}  
		else
			if(I==L)
				{
				L++;
				} 
			else
				if ((I-L)<=(R-J))
					{
					K=J+1;		                      
					Top++;
					Stack[Top]=K;
					Top++;
					Stack[Top]=R;
					R=I-1;
					} 
				else
					{
					K=I-1;           
					Top++;
					Stack[Top]=L;
					Top++;
					Stack[Top]=K;		                      
					L=J+1;
					}
		if (R<=L)
			{
			R=Stack[Top];
			Top--;
			L=Stack[Top];
			Top--;
			}
		}
	while ((R!=0)||(L!=0)) ;   

}


//////////////////////////////////////
//=========BinarySearch_Desc============//
//////////////////////////////////////   
function BinarySearch_Desc(lst,value,start,end){
var low;
var high;
var mid;
var tem;
var mystr=new String();

value=TrimString(value.toUpperCase(),'%20');
tem=false;
low=0;
high=lst.length-1;

while (!(tem || (high < low)))
{
	mid = (Math.round((((low + high) / 2) - 0.5)));
	mystr=escape(((lst.options[mid].text).slice(start,end+1)).toUpperCase());
	mystr=TrimString(mystr,'%A0');
	mystr=TrimString(mystr,'%20');

	if (value > mystr)
	   high = mid - 1;
	else
	    if (value < mystr)
	        low = mid + 1;
	    else
	        tem = true;

}
if (value < mystr)
   return mid;
else
    if ((value > mystr) && (mid!=(lst.length -1)))
        return mid-1;
    else
        return mid;
}

//////////////////////////////////////
//=========BinarySearch_E============//
//////////////////////////////////////   
function BinarySearch_E(lst,value,start,end){
var low;
var high;
var mid;
var tem;
var mystr=new String();

value=TrimString(value.toUpperCase(),'%20');
tem=false;
low=0;
high=lst.length-1;

while (!(tem || (high < low)))
{
	mid = (Math.round(((low + high) / 2)));

	mystr=escape(((lst.options[mid].text).slice(start,end+1)).toUpperCase());

	mystr=escape(((lst.options[mid].text)).toUpperCase());
	mystr=TrimString(mystr,'%A0');
	mystr=TrimString(mystr,'%20');
	
	if (value < mystr)
	   high = mid - 1;
	else
	    if (value > mystr)
	        low = mid + 1;
	    else
	        tem = true;
}

if (value < mystr)
   return mid;
else
    if ((value > mystr) && (mid!=(lst.length -1)))
        return mid +1;
    else
        return mid;
}

////////////////BinarySearch_Asc arabic////////////////
//////////////////////////////////////////////////////
function BinarySearch_Asc(lst,value){
var low;
var high;
var mid;
var tem;
var mystr=new String();

value=Trim(value);
tem=false;
low=0;
high=lst.length-1;

while (!(tem || (high < low)))
{
	mid = (Math.round(((low + high) / 2)));

	mystr=Trim(lst.options[mid].text);
	
	if (value < mystr)
	   high = mid - 1;
	else
	    if (value > mystr)
	        low = mid + 1;
	    else
	        tem = true;
}

if (value < mystr)
   return mid;
else
    if ((value > mystr) && (mid!=(lst.length -1)))
        return mid +1;
    else
        return mid;
}

//////////////////////////////////////
//===========TrimString=============//
//////////////////////////////////////
//The Trimtring do a triming with any special characters like ('%A0') or (%20)
function TrimString(strString,del1)
{
var St=new String(strString);
var arrS;
var i;

arrS=St.split(del1);

var sTrim= new String();
var sp=new String();
sp="";
for (i=0;i<=arrS.length-1;i++)
{
	if (arrS[i]!="")
	{ 
		sTrim=sTrim + sp +arrS[i];
		sp=" ";
	} 
}
return(sTrim);
}

//////////////////////////////////////
//===========Replace=============//
//////////////////////////////////////

function Replace(strString,del1,del2)
{
var St=new String(strString);
var arrS;
var i;

arrS=St.split(del1);

var sTrim= new String();
var sp=new String();

sp=del2;
for (i=0;i<=arrS.length-1;i++)
{
	if (sTrim!="")
		sTrim = arrS[i];
	else
		sTrim = sTrim + sp +arrS[i];
}
return(sTrim);
}


//////////////////////////////////////
//=======InsertionSort_Asc==========//
//////////////////////////////////////
function InsertionSort_Integer_Asc(lst,size,start,end)
{
var I,J;
var Stext,Svalue;
var Flag;
var value1 = new String();
var value2 = new String();
   
		   
 if(size>=1)
	{
	for(I=1;I<=size;I++)
	 {
	  Flag=true;
	  J=I;
	  while ((J>=1) && (Flag))
	    {
			value1 = TrimString(escape(((lst.options[J].text).slice(start,end)).toUpperCase()),'%A0');
			value2 = TrimString(escape(((lst.options[J-1].text).slice(start,end)).toUpperCase()),'%A0');
	    if (parseFloat(value1) < parseFloat(value2))
				{
	      Stext=lst.options[J].text;
	      Svalue=lst.options[J].value;
	      lst.options[J].text=lst.options[J-1].text;
	      lst.options[J].value=lst.options[J-1].value;
	      lst.options[J-1].text=Stext;
	      lst.options[J-1].value=Svalue;
	      J--;
				}
			else
				{
				Flag=false; 
				}
			}
 		}
	}
}

//////////////////////////////////////
//======QuickSort_Asc_String_Original=========//
//////////////////////////////////////
function QuickSort_Asc_String_Original(lst,size,start,end){
var L,R,I,J,K,REFText,REFValue;
       	
	Top++;
	Stack[Top]=0;
	Top++;
	Stack[Top]=0;
	L=0;
	R=size;
		    
	do 
		{
		I=L;
		J=R;
		REFText=lst.options[L].text;
		REFValue=lst.options[L].value;            
		while (I<J)
			{
			while ((((REFText).toUpperCase()).slice(start,end)<((lst.options[J].text).toUpperCase()).slice(start,end))&&(I<J))
				{
				J--;
				}
			if (J!=I)
				{
				lst.options[I].text=lst.options[J].text;
				lst.options[I].value=lst.options[J].value;
				I++;
				}
			while((((REFText).toUpperCase()).slice(start,end)>((lst.options[I].text).toUpperCase()).slice(start,end))&&(I<J))
				{
				I++;
				}  
			if (J!=I)
				{
				lst.options[J].text=lst.options[I].text;
				lst.options[J].value=lst.options[I].value;
				J--;
				} 
			}
		lst.options[J].text=REFText;
		lst.options[J].value=REFValue;
		if (J==R)
			{
			R--;
			}  
		else
			if(I==L)
				{
				L++;
				} 
			else
				if ((I-L)<=(R-J))
					{
					K=J+1;		                      
					Top++;
					Stack[Top]=K;
					Top++;
					Stack[Top]=R;
					R=I-1;
					} 
				else
					{
					K=I-1;           
					Top++;
					Stack[Top]=L;
					Top++;
					Stack[Top]=K;		                      
					L=J+1;
					}
		if (R<=L)
			{
			R=Stack[Top];
			Top--;
			L=Stack[Top];
			Top--;
			}
		}
	while ((R!=0)||(L!=0)) ;   
}
