/*
Copyright © Reazon Systems 1999-2003 - All Rights Reserved
Description:  
 dynform.js - Dynamic Form

Java Script Classes:
  RsGenericPicker
    - RsFontPicker
    - RsColorPicker
    - RsSchoolListPicker

Pre-condition:

Post-condition:

Side-effects:

History:
  Date		  Update Description					  					                Developer
  --------- ------------------------------------------------------- ---------------------
  04/10/05  Created                                                 Reazon/TN

-----------------------------------------------------------------------------------------
*/

var _DF_pickerIfrmId = 'x7y8z9PickerFrame';

function _dynForm_onload() {
  // raise '_DF_rsWebForms.onload event handler 
  _DF_rsWebForms.onload();

}

//-----------------------------------------------------------------------------------------
// RsWebForms class
// Public methods:
//    addControl(pControl)
//-----------------------------------------------------------------------------------------

var RsWebForms = function() {
  // list of all controls (from all web forms)
  this._controls = new Array();  
}


/**
 * this event handler need to be invoked after the page 
 * finished loading
 */
RsWebForms.prototype.onload = function() {
	var i;
	var pControl;
	  
	// call event handlers of sub controls
	for (i = 0; i < this._controls.length; i++) {
		pControl = this._controls[i];
		pControl._loaded = true;
		// if onload event handler is defined, call onload
		if (pControl.onload) {
			pControl.onload();
		}
	}
}


/** 
 * add the control to the list of controls of RsWebForm
 */
RsWebForms.prototype.addControl = function(pControl) {
  this._controls[this._controls.length++] = pControl;
}

//alert(1);
// global instance of RsWebForms
var _DF_rsWebForms = new RsWebForms;
//alert(2);

//-----------------------------------------------------------------------------------------
// RsPopupWin class
//    Popup window
// Global instances:
//    _DF_pickerPopupWin 
// Constructor:
//    RsPopupWin(ifrmId)
// Public methods:
//    isVisible()
//    getTarget()
//    getIfrm()
//    getIfrmDoc()
//    getHref()
//    setHref()
//    show()
//    hide()
//    setPosition(x, y)
//-----------------------------------------------------------------------------------------

/**
 * constructor
 * Parameters
 *   ifrmId: the id of the associated IFRAME element
 */
var RsPopupWin = function(ifrmId) {
  
  // build references to important control
  this._ifrmId = ifrmId;
  this._visible = false;
  this._href = '';
  
  this._target = null;  // the control that linked to the popup
  
  _DF_rsWebForms.addControl(this);
}


/**
 * event handler for the onload event
 */
RsPopupWin.prototype.onload = function() {
  // build references important control
  // after the page finished loading
  // this._ifrm = getIFrame(this._ifrmId);
  this._ifrm = document.getElementById(this._ifrmId);
  this._ifrmDoc = getIFrameContentDocument(this._ifrm);
}


/**
 * return the reference to the _target field
 */
RsPopupWin.prototype.getTarget = function() {
  return this._target;
}


/**
 * return the reference to the iframe
 */
RsPopupWin.prototype.getIfrm = function() {
  return this._ifrm;
}

/**
 * returns the reference to the document object of the iframe
 */
RsPopupWin.prototype.getIfrmDoc = function() {
  return this._ifrmDoc;
}

/**
 * return true if the popup is visible
 */
RsPopupWin.prototype.isVisible = function() {
  return this._visible;
}

/**
 * return the the ifrm' href
 */
RsPopupWin.prototype.setHref = function(href) {
  this._href = href;
  
  // get the reference to the iframe object which has
  // the location property (cannot use this._ifrm because
  // of a bug in IE)
  // var ifrm = getIFrame(this._ifrmId);   
  // ifrm.location.href = href;
  setIfrmHref(this._ifrmId, href);
}


/**
 * return the ifrm's href
 */
RsPopupWin.prototype.getHref = function() {
  return this._href;
}


/**
 * shows the iframe
 */
RsPopupWin.prototype.show = function(target) {
  
  if (this._target && this._target != target) {
    // hide the current popup first
    this.hide();
  }
  
  this._target = target;
  this._visible = true;
  
  showElement(this._ifrm, getVisibilityString(true));
}


/**
 * hide the iframe
 */
RsPopupWin.prototype.hide = function() {

  if (this._target.onpopupclosed) {
    // raise target's onpopupclosed event handler if once exists
    this._target.onpopupclosed();
  }

  this._target = null;
  this._visible = false;
  showElement(this._ifrm, getVisibilityString(false));
}


/**
 * shows the iframe
 */
RsPopupWin.prototype.setPosition = function(left, top) {
  moveTo(this._ifrm, left, top);
}

/**
 * shows the iframe
 */
RsPopupWin.prototype.setSize = function(width, height) {
  setSize(this._ifrm, width, height);
}



/**
 * hide the iframe
 */
/* REMOVED CODE
RsPopupWin.prototype.toggle = function(target) {

  if (target != this._target) {

    // the first time the popup is open for the give target
    this._visible = true;
    this._target = target;
    
  } else {
    // toggle the visibility of the popup
    this._visible = !this._visible;
  }
  
  // show or hide the element, depending on the current visibility setting
  showElement(this._ifrm, getVisibilityString(this._visible));
}
*/


// popup window object used by pickers
var _DF_pickerPopupWin = new RsPopupWin(_DF_pickerIfrmId);


//----------------------------------------------------------------------------------------->
// RsGenericPicker asbtract class
//  Parent class of all pickers
//
// Public methods
//  getId()
//  togglePopup()
//  getPopupAnchor()
// 
// Fields:  
//  concrete child classes must provides the following fields:
//    _formName : the html form contains the control
//    _name     : the unique logical name of the control
//    _type     : type of the control (e.g. color_picker, school_picker,...)
//    _popupHref: the external page displayed in the popup iframe
//    _width    : the popup's width
//    _height   : the popup's height
//    _popupAnchor: reference to an DOM object used as an anchor to position 
//                the popup window
//
// Required Event Hanlders:
//  concrete child classes must provides the following event handlers:
//    onload()
//        this method is called after the page've finished loading
//        it should do the following (at least):
//          set reference to _popupAnchor
//
// Optional Event Handlers:
//    onpopupopened()
//        this method when the popup is shown
//    onpopupclose()
//        this method when the popup is hidden
//----------------------------------------------------------------------------------------->

/**
 * This is an abstract class for other concrete picker c
 */
var RsGenericPicker = function() {
}


/**
 * gets the unique id of the control
 * the id is prefixed with the formName for supporting multi-forms
 */
RsGenericPicker.prototype.getId = function() {
  return this._formName + '_' + this._name;
}


/**
 * gets the control's type
 */
RsGenericPicker.prototype.getPopupAnchor = function() {
  return this._popupAnchor;
}

/**
 * gets the control's type
 */
RsGenericPicker.prototype.getType = function() {
  
  if (this._type == '')
    dynformHelpers_reportBug('type is not defined!');
  else
    return this._type;
}


/**
 * toggle the popup window
 */
RsGenericPicker.prototype.togglePopup = function(ev) {

  var popup = _DF_pickerPopupWin;

  if (popup.getTarget() != this) {
    // the first time togglePopup is called
    this.adjustPopup(ev);
    this.showPopup();
  } else {
    if (popup.isVisible())
      this.closePopup();
    else
      this.showPopup();
  }
}

/**
 * adjustPopup (private method)
 *  
 */
RsGenericPicker.prototype.adjustPopup = function(ev) {
  var popup = _DF_pickerPopupWin;

  /* if (this._popupHref != popup.getHref()) {
    // change the popup's href
    popup.setHref(this._popupHref);
  } */
  popup.setHref(this._popupHref);

  popup.setSize(this._width, this._height);

  alignPopupWindow(popup.getIfrm(), this.getPopupAnchor());
}


/**
 * show the popup window
 * postcondition:
 *    'onpopupopened' event is raised
 */
RsGenericPicker.prototype.showPopup = function() {


  var popup = _DF_pickerPopupWin;

  // show the popup window
  popup.show(this);
  
  // raise 'onpopupopened' event
  if (this.onpopupopened) {
    this.onpopupopened();
  }
}


/**
 * close the popup window 
 * postcondition:
 *    'onpopupclosed' event is raised
 */
RsGenericPicker.prototype.closePopup = function(ev) {

  var popup = _DF_pickerPopupWin;
  popup.hide();

  // raise 'onpopupclosed' event
  if (this.onpopupclosed) {
    this.onpopupclosed();
  }
}


//----------------------------------------------------------------------------------------->
// RsColorPicker class : extends RsGenericPicker
// Public Methods:
//  setColor(rgbColor)
//----------------------------------------------------------------------------------------->

/**
 * constructor
 * Parameters:
 *    formName: the HTML form element containing the control
 *    name: the unique name of the control
 *    inputTextName: the html input element for user to enter the RGB color code 
 */
var RsColorPicker = function(formName, name, inputTextName) {

  // initializes RsGenericPicker's fields 
  this._formName = formName;
  this._name = name;
  this._inputTextName = inputTextName;
  this._color = '';
  
  this._type = 'color_picker';
  this._popupHref = 'pickercolor.htm';
  this._width = 370;
  this._height = 210;
  
  _DF_rsWebForms.addControl(this);
}


// inherits the RsGenericPicker class
RsColorPicker.prototype = new RsGenericPicker;


RsColorPicker.prototype.setColor = function(color) {
  this._color = color;
  
  if (this._loaded) {
    // update the input's value
    this._pColorInput.value = this._color;
  }
}


/**
 * event handler for the onload event
 */
RsColorPicker.prototype.onload = function() {

  var curForm = document.forms[this._formName];
  this._pColorInput = curForm[this._inputTextName];
  
  this._popupAnchor = this._pColorInput;
  
  // synchronize data rendered in the html input control
  // with the control's states
  this._color = this._pColorInput.value;
}


/** 
 * event handler for the onpopupopend event
 */
RsColorPicker.prototype.onpopupopened = function() {
  this._pColorInput.disabled = true;
}


/** 
 * event handler for the onpopupopend event
 */
RsColorPicker.prototype.onpopupclosed = function() {
  this._pColorInput.disabled = false;
}

//----------------------------------------------------------------------------------------->
// RsIdTextObject class
// Public Methods:

var RsIdTextObject = function (id,text) {
  this._id = id;
  this._text = text;
}

RsIdTextObject.prototype.getId = function() { 
  return this._id;
}

RsIdTextObject.prototype.getText = function() { 
  return this._text;
}

RsIdTextObject.prototype.clone = function() { 
	return new RsIdTextObject(this._id, this._text);
}

//----------------------------------------------------------------------------------------->
// RsListPicker abstract class : extends RsGenericPicker
// Public Methods:
//  
// Fields:
//   All RsGenericPickers'f field + the following:
//
//    _multiList    : true/false (true if the current list 
//                        accepts multi selectd items)  
//    _selectedIdsHiddenFieldName
//                  : the name of the hidden fieds containing selected Ids
//
//    _selectedIdsHiddenField
//
//    _selectedItems:   list of currently selected items 
//
// Required event handlers:
//  
//----------------------------------------------------------------------------------------->


var RsListPicker = function() {}

// inherits the RsGenericPicker class
RsListPicker.prototype = new RsGenericPicker;

RsListPicker.prototype.render = function() {
  var items = this._selectedItems;
  var nCount =  items.length;
  var i, curItem, id, text;
  
  // var d = document.createElement('div');
  var d = this._divList; 

  var s = '<table border="0" cellspacing="3" cellpadding="0">';
  
  if (nCount <= 0) {
    s = s + '<tr><td>(None)</td></tr>';
  } else {
    for (i = 0; i < nCount; i++) {
      curItem = items[i];
      text = curItem.getText();
      
      s = s + '<tr>' +
                '<td>' + text + '</td>' +
              '</tr>';
    }
  }
  s = s + "</table>";
//debug: alert(s);
  setInnerHTML(d, s);
  
  /*
  Renderred output:
  <table border="0" cellspacing="3" cellpadding="3">
    <tr>
      <td>${text}:</td>
    </tr>
    ...
  </table>
  */
}

/**
 * find an item with the given id
 */
RsListPicker.prototype.findItemIndexById = function(id) {
  var items = this._selectedItems;
  var i;
  
  for (i = 0; i < items.length; i++) {
    if (items[i].getId() == id)
      return i;
  }

  return -1;
}


/**
 * find an item with the given id
 * Parameters:
 *   item: (instanceof RsIdTextObject)
 */
RsListPicker.prototype.findItemIndex = function(item) {
    return this.findItemIndexById(item.getId());
}

/**
 */
RsListPicker.prototype.updateHiddenField = function() {
  var items = this._selectedItems;
  var i, s = '';
  
  for (i = 0; i < items.length; i++) {
    id = items[i].getId();
    s = (i == 0 ? id : s + ',' + id);
  }
  
  this._selectedIdsHiddenField.value = s;
  
}

/**
 * set the first item to the school that was passed in.  Used for single-select cases
 * Parameters:
 *  item: (instanceof RsIdValueObject)
 */
RsListPicker.prototype.firstItem = function(item) {

	// must clone the object, otherwise, in IE, the object
	// will be disposed once the popup frame is reloaded
	// ---> leads to the "can't execute code from a freed script
	//	NOTES : Cannot do this: var curItem = item.clone();	
	//					because the object is still constructed in the popup
	//					will figure this out later

	var curItem = new RsIdTextObject (item.getId(), item.getText());
  
  // set the first item to the given item
  var items = this._selectedItems;
  items[0] = curItem;
  
  this.updateHiddenField();

  // re-render the list of selected items
  this.render();
 
 // invoke onitemadded event handler
    this.onitemadded(curItem); 
}


/**
 * add an item to the list of selected items
 * precondition: the item's id must be unique
 * Parameters:
 *  item: (instanceof RsIdValueObject)
 */
RsListPicker.prototype.addItem = function(item) {

	// must clone the object, otherwise, in IE, the object
	// will be disposed once the popup frame is reloaded
	// ---> leads to the "can't execute code from a freed script
	//	NOTES : Cannot do this: var curItem = item.clone();	
	//					because the object is still constructed in the popup
	//					will figure this out later
	var curItem = new RsIdTextObject (item.getId(), item.getText());

  
  // check for precondition
  var itemIndex = this.findItemIndex(curItem);
  if (itemIndex >= 0) {
    dynformHelpers_reportBug('addItem() - given id already exist');
  } 
  
  // add the given item to the end of the list
  var items = this._selectedItems;
  items[items.length++] = curItem;
  
  this.updateHiddenField();

  // re-render the list of selected items
  this.render();
  
  if (this.onitemadded);
    // invoke onitemadded event handler
    this.onitemadded(curItem);
}

/**	
 * remove an item to the list of selected items
 * precondition: the item must appear in the list
 */
RsListPicker.prototype.removeItem = function(item) {
  // check for precondition
  var itemIndex = this.findItemIndex(item);
  
  if (itemIndex < 0) {
    dynformHelpers_reportBug('removeItem() - given id doesn\'s exist');
  } 
  
  // remove the item
  var items = this._selectedItems;
  
  var i;

  for (i = itemIndex; i < items.length-1; i++) {
    items[i] = items[i+1];
  }
  items.pop();

  this.updateHiddenField();
  
  // re-render the list of selected items
  this.render();
  
  
  if (this.onitemremoved);
    // invoke onitemadded event handler
    this.onitemremoved(item);
}


//----------------------------------------------------------------------------------------->
// RsSchoolListPicker class : extends RsListPicker
// Public Methods:
//----------------------------------------------------------------------------------------->

var RsAbstractSchoolListPicker = function() {
	//alert('RsAbstractSchoolListPicker');
	this._width = 330;
	this._height = 330;	
};


// inherits the RsGenericPicker class
RsAbstractSchoolListPicker.prototype = new RsListPicker;


/**
 * event handler for the onload event
 */
RsAbstractSchoolListPicker.prototype.onload = function() {
	//alert('RsAbstractSchoolListPicker.prototype.onload');

  var curForm = document.forms[this._formName];
  this._selectedIdsHiddenField = curForm[this._selectedIdsHiddenFieldName];

  this._divList = document.getElementById(this._divListName);
  this._openPopupButton = document.getElementById(this._openPopupButtonName);

  // initialize popupAnchor  (required by RsGenericPopup)
  this._popupAnchor = this._openPopupButton;

  
  // initialize selectedItems
  if (this._wddxSchools) {
    // load serialized data from wddxSchools
    this._selectedItems = dynformHelpers_loadFromWddx(
                            this._wddxSchools,       
                            'Sch_Id', 
                            'Sch_Name',
                            this.getSelectedIds());
    
    // destroy wddx schools because this is nolonger needed
    this._wddxSchools = null;
  } else {  //single item picker
    this._selectedItems[0] = new RsIdTextObject(this._selectedIdsHiddenField.value, this._divList.innerHTML); //selectedItem;
  }

  //Removed by rs on 2005-10-15:  do not render because it loads the iframe unnecessarily during page load.
  // call RsListPicker to render to selected items
  //this.render();
}


/**
 * returns the list of currently selected ids
 */
RsAbstractSchoolListPicker.prototype.getSelectedIds = function() {
  return this._selectedIdsHiddenField.value;
}


RsAbstractSchoolListPicker.prototype.onitemadded = function(item) {
 // alert('item: ' + item.getText() + ' is added');
}

RsAbstractSchoolListPicker.prototype.onitemremoved = function(item) {
 // alert('item: ' + item.getText() + ' is removed');
}


//----------------------------------------------------------------------------------------->
// RsSchoolPicker class : extends RsAbstractSchoolListPicker
// Public Methods:
//----------------------------------------------------------------------------------------->
var RsSchoolPicker = function(
    formName, 
	name, 
    divSchoolName, 
	selectedIdHiddenFieldName, 
    openPopupButtonName,
	state,
	initial
	) {

	//alert('RsSchoolPicker');
		  
	// initializes RsGenericPicker's fields 
	this._formName = formName;
		
	this._name = name;
	this._divListName = divSchoolName;
	this._openPopupButtonName = openPopupButtonName;
	this._type = 'school_picker';

	//don't pass in 'null' or 'undefined' to CF
	if (!state || state == null)
  		sParam = '';
	else
		sParam = state;

	//don't pass in 'null' or 'undefined' to CF
	if (!initial || initial == null)
  		sInitial = '';
	else
		sInitial = initial;

	this._popupHref = 'pickerschoollistc.cfm?m=no&s=' + sParam + '&i=' + sInitial;
	//this._width = 330;
	//this._height = 350;
	
	this._selectedIdsHiddenFieldName = selectedIdHiddenFieldName;
	
	// initializes RsListPicker's fields 
	this._multiList = false;
	this._selectedItems = new Array();
	
	//if (selectedId) {
	//  this._selectedItems[0] = new RsIdTextObject(selectedId, selectedText); //selectedItem;
	//}
	
	this._wddxSchools = null;
	
	_DF_rsWebForms.addControl(this);
}

// inherits the RsAbstractSchoolListPicker class
RsSchoolPicker.prototype = new RsAbstractSchoolListPicker();

//----------------------------------------------------------------------------------------->
// RsSchoolPicker class : extends RsAbstractSchoolListPicker
// Public Methods:
//----------------------------------------------------------------------------------------->
/**
 * constructor
 * Parameters:
 *    formName: the HTML form element containing the control
 *    name: the unique name of the control
 */
var RsSchoolListPicker = function(
    formName, 
	name, 
    divListName, 
	selectedIdsHiddenFieldName, 
    openPopupButtonName, 
	wddxSchools) {

  // initializes RsGenericPicker's fields 
  this._formName = formName;
  this._name = name;
  this._divListName = divListName;
  this._openPopupButtonName = openPopupButtonName;
  
  this._type = 'school_picker';
  this._popupHref = 'pickerschoollistc.cfm?m=yes';
  //this._width = 320;
  //this._height = 250;
  
  this._selectedIdsHiddenFieldName = selectedIdsHiddenFieldName;
  
  // initializes RsListPicker's fields 
  this._multiList = true;
  this._selectedItems = new Array(); 
  
  this._wddxSchools = wddxSchools;
  
  _DF_rsWebForms.addControl(this);
}

// inherits the RsAbstractSchoolListPicker class
RsSchoolListPicker.prototype = new RsAbstractSchoolListPicker();



//----------------------------------------------------------------------------------------->
// HELPERS
//----------------------------------------------------------------------------------------->
function dynformHelpers_loadFromWddx(
    wddxRecordset,  // the wddx recordset containing all selected items 
    idColumnName,   
    textColumnName,
    selectedIds     // list of currently selected ids,
                    // this list is used to determine the order of the items
                    // in the list  (notes: not implemented)
) {
  var items = new Array();
  
  if (!wddxRecordset)
    return items; // return if the recordset is undefined  
  
  var nRows = wddxRecordset.getRowCount();
  var id, text;
  
  for (row = 0; row < nRows; ++row) {
    // extract the id,text column values
    id = wddxRecordset.getField(row, idColumnName);
    text = wddxRecordset.getField(row, textColumnName);

    // add a new item to the list
    items[row] = new RsIdTextObject(id, text);
  }

  return items;
}


function dynformHelpers_reportBug(message) {
  alert('BUG-DYNFRORM: ' + message);
}
