// DlgBase.js support for the dialogs and their communications with
// the server

// A quick set of utility functions to make life just a tad easier

function FormObj(fField){ 
	if( fField==null ) return(null);
return( document.getElementById(fField) ); 
}

function isArray(x){
	return( (typeof x=='object') && (x.constructor==Array) );
}

function IsValidMailAddress(str) {

		var at="@"
		var dot="."
		var lat=str.indexOf(at)
		var lstr=str.length
		var ldot=str.indexOf(dot)
		if (lat==-1) return( false); // No at in the message
		if ( lat==0 || lat==lstr) return( false); // @ at wrong position

		if ( ldot<=0 || ldot>=(lstr-1)){ // is the dot more or less positoned correctly
		    return false
		}
// various arcane other tests follow.
		 if (str.indexOf(at,(lat+1))!=-1) return false
		 if (str.substring(lat-1,lat)==dot || str.substring(lat+1,lat+2)==dot){
		    return false
		 }
		 if (str.indexOf(dot,(lat+2))==-1) return false
		 if (str.indexOf(" ")!=-1) return false
 		 return true					
	}


// First though we define the dlgField class

// Class dlgField - Support for storing the fields on the form
//
// Methods
//	 dlgField(FieldName,OnScreen=true,bFormElement=true)
//		Create the initial field object.  OnScreen if set to true
//		indicates taht there is an id on the form that corresponds to
//		the FieldName
//		If bFormElement is set to true it means the element isn't a form element
//		and should be filled with innerHTML instead of set value
//	 CreateDumpLine(Index)
//		Create a line of data showing the field contents for debug purposes.
//		If index is defined at Index) will be tacked at the from of the line
//	 LoadFromForm()
//		If the field is an OnScreen Field - Load its data from the screen
//	 LoadFromXml(pXMLRoot)
//		Load data from an xml file that was probably returend from the server
//	 Clear()
//		Clear the data in the field
//	 Display()
//		Display the field data on the form
//	XmlDump
//		Dump the name and the data as an xml entry
//	SetData(myData,bAutoDisplay=false)
//		Sets the data member of dlgField to myData.  If myData==null then the
//		field is cleared. if(bAutoDisplay) is true, the data will be propigated
//		to the screen.
// Properties
//	 Name 
//		Name of the Field.  This is the same as the id on the form
//		and the database record name.
//	 Data
//		Data taht is currently in the field.
//	  OnScreen
//		If true indicates that this field in on the form with id==Field
//

function dlgField_CreateDumpLine(Index)
{

	var Text="";
	if( arguments.length>0 ){
		Text= Index+") ";
	}
	Text = Text+this.Name+" ";
	if( this.Data.length >0) Text=Text+this.Data+" ";
	else Text=Text+"[Empty] ";
	Text += (this.OnScreen) ? "Has Field":"No Form Field";
	return(Text);
}

function dlgField_LoadFromForm()
{
	if( !this.OnScreen ) return(this.Data);
	var Field=document.getElementById(this.Name);
	if( Field!=null){
		if( this.bIsCheckBox ) this.Data=Field.checked;
		else{
			if( this.bIsCombo ) this.Data=this.GetCombo();
			else this.Data=Field.value;
			 }
		}
	return( this.Data);		
}

function dlgField_GetCombo()
{
	var Field=document.getElementById(this.Name);
	if( Field == null ) return("");
	if( Field.selectedIndex===null) return("");
	if( Field.selectedIndex <0) return("");
	var List=Field.options;
	if( List==null ) return("");
	var Count=List.length;
	if( Count<=0) return("");
	return( List[Field.selectedIndex].value);	
}

function dlgField_Display()
{
	if( !this.OnScreen ) return;
	var Field=document.getElementById(this.Name);
	if( Field==null ) return;
	if( this.bIsCheckBox ){ // Set or unset a check
		Field.checked=this.Data;
		return;
	}
	if( this.bIsCombo ){
		this.SetCombo(this.Data);
		return;
	}
	if( this.bFormElement )	Field.value=this.Data;
	else{
		Field.innerHTML=this.Data;
	}

}

function dlgField_SetCombo(value)
{
	var Field=document.getElementById(this.Name);
	if( Field == null ) return;
	var List=Field.options;
	if( List==null ) return;
	var Count=List.length;
	if( Count<=0) return;
	for( var Index=0; Index<Count; Index++){
		if( List[Index].value==value){
			Field.selectedIndex=Index;
			return;
		} // fi value found
	} // next index
	Field.selectedIndex=-1;
}


function dlgField_LoadFromXml(pXMLRoot)
{
	this.Data="";			// Clear the old data field
	var pSection=pXMLRoot.getElementsByTagName(this.Name);
	if( pSection.length==0 ) return;		// The section we want isn't here
	this.Data=GetNodeText(pSection[0],1);
}

function dlgField_Clear(){ this.Data=""; }
function dlgField_XmlDump(){ return(pAjaxXmlFormat.CreateTag(this.Name,this.Data)); }
function dlgField_SetData(myData,bAutoDisplay)
{
	var bDisplay= (arguments.length <2) ? false: bAutoDisplay;
	this.Clear();
	if( myData!=null ) this.Data=myData;
	if( bDisplay ) this.Display();
}
function dlgField_GetData(){ return(this.Data); }


function dlgField(FieldName,OnScreen,bFormElement)
{
	this.Name=FieldName;
	this.bFormElement=true;
	this.Data="";
	this.OnScreen=true;
	this.bIsCheckBox=false;
	this.bIsCombo=false;
	if(arguments.length>1) this.OnScreen=OnScreen;
	if(arguments.length>2) this.bFormElement=bFormElement;
}



// Now create a dummy dlgField so we can override it's prototype
new dlgField(null);

dlgField.prototype.CreateDumpLine=dlgField_CreateDumpLine;
dlgField.prototype.LoadFromForm=dlgField_LoadFromForm;
dlgField.prototype.LoadFromXml=dlgField_LoadFromXml;	
dlgField.prototype.Display=dlgField_Display;
dlgField.prototype.Clear=dlgField_Clear;
dlgField.prototype.XmlDump=dlgField_XmlDump;
dlgField.prototype.SetData=dlgField_SetData;
dlgField.prototype.GetData=dlgField_GetData;
dlgField.prototype.SetCombo=dlgField_SetCombo;
dlgField.prototype.GetCombo=dlgField_GetCombo;

// Now begin the dlgBase class.  Normally this would be the base class and
// the instance would be derivied from it.  But javascript doesn't really support
// this idea, so the foucs is making this a member of the derivied class
// Attempt to use the prototyping facilites of Javascript and see if we can't subclass
// 1-30-08

// Class dlgBase - Support for communication between the form and the server
//
// Externs that are used by dlgBase
//	pAjaxCtrl	
//		The AjaxCtrl class.  This should have been created when AjaxUtil.js
//		was included in the source.
//  pServerLoc
//		dlgBase that keeps a copy of what the current record is on the server.
//
// Methods:
//	 dlgBase()
//		Construct and Initializes the dlgBase Class
//	 ShowDebugText(sText,bClear=0)
//		Append the text specified by sText to the text in the debug window.  
//		If bClear is true clear any exisiting  text from the window and 
//		only display sText.
//	 SetDebugFields(dbBlock,dbCell)
//		dbBlock - The div block or whatever the container that has the text is called
//		dbCell - The id of the text area that is being used.
//	ShowDebugWindow(bShow=true)
//		Raise or lower the debug window.
//	 DumpFields()
//		 Utility function that will dump the contents of the field
//		 array into the debug window
//	 GetFieldIndex(FieldName)
//		 Returns the index in the field array of the field whose Name is FieldName
//		 -1 is returned on error
//	GetField(FieldName)
//		Returns the field object from the array.  REMEMBER this return
//		is not a pointer!
//	FieldIsEmpty(FieldName)
//		Returns true if the field doesn't exist or the Data member is null
//		or the Data member ==''
//	 LoadFromForm()
//		 Loads all fields from the form.
//	LoadInitialFields(pArray)
//		Loads and display the fields in pArray
//		pArray[n][0]=fieldname
//		pArray[n][1]=field data
//	 MatchesServer(bool ForceLoad=1,dlgBase pServerLoc)
//		  Return true if the fields on the from match the fields on the server.
//	LoadFieldsFromXml(pXMLRoot)
//		  Transfer data from an xml response into the field array.  Please note
//		  that if a field doesn't exit, it will be filled with blanks.
//  ConvertToXmlBlock()
//		  Dump all the fields out in a format that resembles xml
//	ClearScreenFields()
//		Clear the fields and change the Locale Combo to Add New Record
//	DisplayFields
//		  Display all of the fields on the form
//	DisplayField(FieldName)
//		  Displays a single field on the form
//	AddField(FieldName,OnScreen=true,bFormElement=true)
//		  Add a field used for transfer to the internal fields array.  See
//		  the constructior of loc field for more details
//	AddFormInputs(pArray)
//	AddStaticText(pArray)
//	AddFormControls(pArray)
//		Add a group of control from the form into the dialog.
//		Inputs - Text Input fields i.e. value is used to set their value
//		AddStaticText - things that are set with innerHTML
//		AddFormControls - Things aren't in the above list. 
//	SetFieldData(FieldName,myData,bAutoDisplay=false)
//		  Set the dlgField named FieldName with the value in myData
//
// Properties
//	 Fields
//		Array of LocField objects.  Refer to LocField for contents
//

function dlgBase_GetFieldIndex(FieldName)
{
	if( !arguments.length ) return(-1);
	for( var i=0; i<this.Fields.length; i++){ //>
		if( this.Fields[i].Name==FieldName) return(i);	
	}// next i
	return(-1);
}

function dlgBase_GetField(fField){
	if( !arguments.length ) return(null);
	for( var i=0; i<this.Fields.length; i++){ //>
		if( this.Fields[i].Name==fField) return(this.Fields[i]);	
	}// next i
	return(null);
}

function dlgBase_FieldIsEmpty(fFieldName){
	if( !arguments.length ) return(true);
	var fField=this.GetField(fFieldName);
	if( fField==null ) return(true);
	if( fField.Data==null ) return(true);
	if( fField.Data=="") return(true);
	return(false);
}


function dlgBase_DumpFields()
{
	if( !this.DebugActive ) return;
	if( this.Fields.length ==0 ){
		this.ShowDebugText("Field array is empty");
		return;
	}
	for( var i=0; i<this.Fields.length; i++){ //>
		this.ShowDebugText(this.Fields[i].CreateDumpLine(i));		
	} // next i
}

function dlgBase_SetFieldData(FieldName,myData,bAutoDisplay)
{
	var bDisplay= ( arguments.length < 3 ) ? false : bAutoDisplay;
	var p=this.GetField(FieldName);
	if( p != null ) p.SetData(myData,bDisplay);
}

function dlgBase_GetFieldData(FieldName)
{
	var p=this.GetField(FieldName);
	if( p != null ) return(p.GetData());
	return( null );
}

function dlgBase_DisplayField(FieldName)
{
	var p=this.GetField(FieldName);
	if( p != null ) p.Display();
}

function dlgBase_LoadFromForm()
{
// First handle the easy fields
	for( var i=0; i<this.Fields.length; i++){ //>
		if( !this.Fields[i].OnScreen ) continue;
		this.Fields[i].LoadFromForm();	
	}// next i
// Now handle the Combo box from the top

}

function dlgBase_FieldFormLoad(fName)
{
	var p=this.GetField(fName);
	if( p != null ) return( p.LoadFromForm());
	return(null);
}

function dlgBase_LoadFieldsFromXml(pXMLRoot)
{
	for( var i=0; i<this.Fields.length; i++){ //>
		this.Fields[i].LoadFromXml(pXMLRoot);	
	}// next i
}

function dlgBase_LoadInitialFields(pArray)
{
	if( arguments.length != 1) return;
	var pField;
	for( var i=0; i< pArray.length; i++){
		if( (pField=this.GetField(pArray[i][0]))==null) continue;
		pField.SetData(pArray[i][1],true);
	}// next i
}

function dlgBase_DisplayFields()
{
	for( var i=0; i<this.Fields.length; i++){ //>
		this.Fields[i].Display();	
	}// next i
}

function dlgBase_MatchesServer(ForceLoad,pServerLoc)
{
	var ShouldLoad=1;
	if( (arguments.length>0) && (ForceLoad == false) ) ShouldLoad=0;
	if( ShouldLoad) this.LoadFromForm();		// Load the new fields from the form
	for( var i=0; i<this.Fields.length; i++){ //>
		if( !this.Fields[i].OnScreen ) continue;
		if( this.Fields[i].Data.length != pServerLoc.Fields[i].Data.length ) return( false);
		if( this.Fields[i].Data != pServerLoc.Fields[i].Data ){
//			this.ShowDebugText("Server doesnt match index "+i);
			 return( false);	
			 }
	}// next i
//this.ShowDebugText("Server Matches");
	return( true );		
}

function dlgBase_ClearScreenFields()
{
	for( var i=0; i<this.Fields.length; i++){ //>
		if( !this.Fields[i].OnScreen ) continue;
		this.Fields[i].Data="";
	}// next i
}

function dlgBase_ShowElement(Name,Show)
{
	var ShouldShow=true;
	if( arguments.length == 2) ShouldShow=Show;
	var Field=document.getElementById(Name);
	if( Field ==null) return;
	if( ShouldShow ) Field.style.visibility="visible";
	else Field.style.visibility="hidden";

}

function dlgBase_EnableButton(Name,Status)
{
	if( arguments.length != 2) return;
	var Field=document.getElementById(Name);
	if( Field == null ) return;
	Field.disabled=(Status) ? false:true;
}

function dlgBase_SetButtonText(nID,Lable)
{
	if( arguments.length != 2) return;
	var Field=document.getElementById(nID);
	if( Field == null ) return;
	Field.value=Lable;
	Field.innerHTML=Lable;
}

function dlgBase_ComboSetSelected(nID,value)
{
//this.ShowDebugText("Combo box:"+nID+" Value="+value+"\n");
	var Field=document.getElementById(nID);
	if( Field == null ) return;
	var List=Field.options;
	if( List==null ) return;
	var Count=List.length;
	if( Count<=0) return;
	var Index;
	for( Index=0; Index<Count; Index++){
		if( List[Index].value==value){
			Field.selectedIndex=Index;
			return;
		} // fi value found
	} // next index
	Field.selectedIndex=-1;
}

function dlgBase_GetComboValue(nID)
{
	var Field=document.getElementById(nID);
	if( Field == null ) return("");
	if( Field.selectedIndex===null) return("");
	if( Field.selectedIndex <0) return("");
	var List=Field.options;
	if( List==null ) return("");
	var Count=List.length;
	if( Count<=0) return("");
	return( List[Field.selectedIndex].value);	
}

function dlgBase_SetCheck(nID,value)
{
	var Field=document.getElementById(nID);
	if( Field == null ) return;
	Field.checked=value;	
}

function dlgBase_GetCheck(nID)
{
	var Field=document.getElementById(nID);
	if( Field == null ) return(0);
	if( Field.checked ) return(1);
	return(0);	
}

function dlgBase_SetFocus(nID)
{
	if( arguments.length != 1) return;
	var Field=document.getElementById(nID);
	if( Field == null ) return;
	Field.focus();
}

function dlgBase_ConvertToXmlBlock()
{
	var Str="";
	for( var i=0; i<this.Fields.length; i++){ //>
		Str=Str+this.Fields[i].XmlDump();	
	}// next i
	return( Str);
}

function dlgBase_AddField(FieldName,OnScreen,bFormElement)
{
	var k=this.Fields.length;
	if( arguments.length<3) bFormElement=true;
	if( arguments.length<2) OnScreen=true;
	this.Fields[k]=new dlgField(FieldName,OnScreen,bFormElement);
	return( this.Fields[k]);
}

function dlgBase_AddFormControls(pArray)
{
	if( pArray==null ) return;
	var Len=pArray.length,i;
	for( i=0; i<Len; i++) this.AddField(pArray[i],false,false);
}

function dlgBase_AddFormInputs(pArray)
{
	if( pArray==null ) return;
	var Len=pArray.length,i;
	for( i=0; i<Len; i++) this.AddField(pArray[i],true,true);
}

function dlgBase_AddStaticText(pArray)
{
	if( pArray==null ) return;
	var Len=pArray.length,i;
	for( i=0; i<Len; i++) this.AddField(pArray[i],true,false);
}

function dlgBase_AddCheckBoxes(pArray)
{
	if( pArray==null ) return;
	var Len=pArray.length,i;
	for( i=0; i<Len; i++){
		 var p=this.AddField(pArray[i],true,true);
		 p.bIsCheckBox=true;
		 }
}

function dlgBase_AddComboBoxes(pArray)
{
	if( pArray==null ) return;
	var Len=pArray.length,i;
	for( i=0; i<Len; i++){
		 var p=this.AddField(pArray[i],true,true);
		 p.bIsCombo=true;
		 }
}


function dlgBase_AddRequiredField(FieldName)
{
	var k=this.requiredFields.length;
	this.requiredFields[k]=FieldName;
}

function dlgBase_SetRequiredFields(pArray)
{
	if( pArray==null ) return;
	var i,Len=pArray.length;
	for( i=0; i< Len; i++) this.AddRequiredField(pArray[i]);
}

function dlgBase_SetTextColor(pArray,cColor)
{
	if( pArray==null ) return;
	if( !isArray(pArray) ) pArray=Array(pArray);
	var tField;
	for( var i=0; i< pArray.length; i++){
		tField=document.getElementById(pArray[i]);
		if( tField==null ) continue;
		tField.style.color=cColor;
	}// next i

}

function dlgBase_AllRequiredSet()
{
	var Len=this.requiredFields.length;
	var fLen=this.Fields.length;
	var i,j;
	var pData;
	for( i=0; i<Len; i++){
		pData=null;
		for(j=0; j<fLen; j++){	
			if( this.requiredFields[i]==this.Fields[j].Name){
				pData=this.Fields[j].Data;
				break;
			} // fi field found
		} // next j
		if( (pData==null) ||  (pData=="") ){
//this.ShowDebugText("failed on "+this.requiredFields[i]+" i="+i);
			 return(false);
			 }
	}// next i
	return(true);
}

function dlgBase_AnyRequiredSet()
{
	var Len=this.requiredFields.length;
	var fLen=this.Fields.length;
	var i,j;
	var pData;
	for( i=0; i<Len; i++){
		pData=null;
		for(j=0; j<fLen; j++){	
			if( this.requiredFields[i]==this.Fields[j].Name){
				pData=this.Fields[j].Data;
				break;
			} // fi field found
		} // next j
		if( pData==null) continue;
		if( pData=="" ) continue;
		return( true);
	}// next i
	return(false);
}

// Begin a quick experimental section the idea here is add the blur and focus and timer
// functions to the base dialog class for those fields that don't need to check for any
// thing other than requiredness

function dlgBase_OnRequiredBlur(Obj)
{
	if( this.EditAmtTimeID!=-1 ) clearInterval(this.EditAmtTimeID);

	pDlg.SetFieldData(Obj.id,Obj.value);
}

function dlgBase_OnRequiredFocus(Obj)
{
	this.pTimerID=Obj.id;
	this.pTimerText=Obj.value;
	this.pTimerObj=Obj;
	this.EditAmtTimeID=setInterval("OnRequiredTimer()",200);
}

function dlgBase_OnRequiredTimer()
{
	if( this.pTimerObj.value==this.pTimerText ) return(false);
	this.pTimerText=this.pTimerObj.value;
	this.SetFieldData(this.pTimerID,this.pTimerText);
	return(true);
}

// Begin a block of debug functions

function dlgBase_SetDebugFields(dbBlock,dbCell)
{
	this.DebugBlock=dbBlock;
	this.DebugCell=dbCell;
}

function dlgBase_ShowDebugWindow(bShow)
{
	var Field=FormObj(this.DebugBlock);
	if( Field==null ) return;
	this.DebugActive =( !arguments.length ) ? true:bShow;
	if( this.DebugActive  ){
		Field.style.visibility="visible";
		Field.style.display="block";
		
	} else{
		Field.style.visibility="hidden";
		Field.style.display="none";
	}
}

function dlgBase_ShowDebugText(sText,bClear)
{ 
	if( !this.DebugActive ) return;
	if( arguments.length>1 ){
		if( arguments[1]==1 ) this.DebugText="";	// Clear out the debug Text
	}
	var Field=FormObj(this.DebugCell);
	if( Field == null ) return;
	if( this.DebugText.length>1) this.DebugText=this.DebugText+"\n";
	this.DebugText=this.DebugText+sText;
	Field.value=this.DebugText;
 }


function dlgBase()
{
	this.Fields=Array();
	this.requiredFields=Array();
	this.DebugBlock=null;				// The block used for debugging
	this.DebugCell=null;				// The cell that will debugging stuff
	this.DebugActive=false;
	this.DebugText="";
} // End of function LocDlg

new dlgBase();

dlgBase.prototype.ShowDebugText=dlgBase_ShowDebugText;
dlgBase.prototype.SetDebugFields=dlgBase_SetDebugFields;
dlgBase.prototype.ShowDebugWindow=dlgBase_ShowDebugWindow;
dlgBase.prototype.DumpFields=dlgBase_DumpFields;
dlgBase.prototype.GetFieldIndex=dlgBase_GetFieldIndex;
dlgBase.prototype.GetField=dlgBase_GetField;
dlgBase.prototype.LoadFromForm=dlgBase_LoadFromForm;
dlgBase.prototype.LoadInitialFields=dlgBase_LoadInitialFields;
dlgBase.prototype.FieldFormLoad=dlgBase_FieldFormLoad;
dlgBase.prototype.MatchesServer=dlgBase_MatchesServer;
dlgBase.prototype.EnableButton=dlgBase_EnableButton;
dlgBase.prototype.ShowElement=dlgBase_ShowElement;
dlgBase.prototype.SetButtonText=dlgBase_SetButtonText;	
dlgBase.prototype.LoadFieldsFromXml=dlgBase_LoadFieldsFromXml;
dlgBase.prototype.DisplayFields=dlgBase_DisplayFields;
dlgBase.prototype.DisplayField=dlgBase_DisplayField;
dlgBase.prototype.ConvertToXmlBlock=dlgBase_ConvertToXmlBlock;
dlgBase.prototype.AddField=dlgBase_AddField;
dlgBase.prototype.SetFieldData=dlgBase_SetFieldData;
dlgBase.prototype.GetFieldData=dlgBase_GetFieldData;
dlgBase.prototype.FieldIsEmpty=dlgBase_FieldIsEmpty;
dlgBase.prototype.ClearScreenFields=dlgBase_ClearScreenFields;
dlgBase.prototype.AddRequiredField=dlgBase_AddRequiredField;
dlgBase.prototype.SetRequiredFields=dlgBase_SetRequiredFields;
dlgBase.prototype.AllRequiredSet=dlgBase_AllRequiredSet;
dlgBase.prototype.AnyRequiredSet=dlgBase_AnyRequiredSet;
dlgBase.prototype.SetFocus=dlgBase_SetFocus;
dlgBase.prototype.ComboSetSelected=dlgBase_ComboSetSelected;
dlgBase.prototype.SetCheck=dlgBase_SetCheck;
dlgBase.prototype.GetCheck=dlgBase_GetCheck;
dlgBase.prototype.GetComboValue=dlgBase_GetComboValue;
dlgBase.prototype.AddFormControls=dlgBase_AddFormControls;
dlgBase.prototype.AddFormInputs=dlgBase_AddFormInputs;
dlgBase.prototype.AddStaticText=dlgBase_AddStaticText;
dlgBase.prototype.AddCheckBoxes=dlgBase_AddCheckBoxes;
dlgBase.prototype.AddComboBoxes=dlgBase_AddComboBoxes;
dlgBase.prototype.OnRequiredBlur =dlgBase_OnRequiredBlur;
dlgBase.prototype.OnRequiredFocus =dlgBase_OnRequiredFocus;
dlgBase.prototype.OnRequiredTimer =dlgBase_OnRequiredTimer;
dlgBase.prototype.SetTextColor =dlgBase_SetTextColor;