/**
 *----------------------------------------------------------*-----------------*
 *     Web Project Manager                                  |   frontSystem   |
 *----------------------------------------------------------*-----------------*
 *     @category frontSystem
 *     @package javascript
 *     @version 0.1 [2008/11/29]
 *
 *     @author Tomáš Režňák <tomas.reznak@web-project-manager.com>
 *     @copyright Copyright © 2008, Tomáš Režňák
 *     @link http://www.web-project-manager.com/
 *----------------------------------------------------------------------------*
 *     definition of javascript functions for HTML forms
 */

/*
 * general functions / START
 */ 
 
/**
 * submit form
 *    
 * @param mixed obj    [optional] form object or id of form to be submitted. If omitted, try to submit all forms on current page
 * @return void
 */
function formSubmit(obj) {
  var status;

  if (obj == null) {    // no form specified - submit each form on the page
    var forms = document.forms;

    for (var i=0;i<forms.length;i++) {
      status = true;
      if (forms[i].onsubmit) {
        status = forms[i].onsubmit();
      }
      
      if (status != false) {
        forms[i].submit();
      }      
    }
    
  } else {    // submit form specified by obj
    if (document.getElementById(obj)) {    // form identified by its id
      obj = document.getElementById(obj);
    }
  
    if (obj) {
      status = true;
    
      if (obj.onsubmit) {
        status = obj.onsubmit();
      }
      
      if (status != false) {
        obj.submit();
      }
    }
  }
}

/**
 * submit search form
 *    
 * @param mixed obj    form object or id of form to be submitted
 * @return void
 */
function formSubmitSearch(obj) {
  if (document.getElementById(obj)) {    // form identified by its id
    obj = document.getElementById(obj);
  }

  obj.submit();
  
  var img = document.getElementById("form_search_preloader");
  if (img) {    // display preloader image
    var div = document.createElement("DIV");
    div.id = "form_search_preloader_bg";
    obj.appendChild(div);
    
    var scroll = windowGetScrollXY();
    if (scroll.y > 80) {
      scroll.y -= 80;
    }
    
    img.style.left = ((scroll.x + obj.offsetParent.offsetWidth - 80) / 2) + "px";
    img.style.top = ((scroll.y + obj.offsetParent.offsetHeight - 50) / 2) + "px";
    
    elementShow(img);
  }
}
  

/**
 * put focus on the first field in the form
 *    
 * @param string form_id     form id
 * @return void
 */
function formFocusFirstField(form_id) {
  var form = document.getElementById(form_id);

  if (form && form[0]) {
    try {
      form[0].focus();
    } catch (e) {}
  }
}

/**
 * change active tab to tab_name
 *    
 * @param string tab_name    name of tab which should be set as active
 * @return void
 */
function formTabChange(tab_name) {
	elementHide("tab_" + active_tab);
	document.getElementById("tabname_" + active_tab).className = "";
	
	elementShow("tab_" + tab_name);
	document.getElementById("tabname_" + tab_name).className = "active";
	active_tab = tab_name;
	
	// try to put focus on the first field in active tab
	var parent = document.getElementById("tab_" + active_tab).parentNode;
  var type;
  var field;

	while (parent) {
	  if (parent.tagName == "FORM") {
	    for (i=0;i<parent.elements.length;i++) {
	      field = parent.elements[i];
	      
	      try {
          type = field.type;
        } catch (e) {}	      
	    
	      if (type && formGetFieldParentTabName(field) == active_tab) {
	        if (type == "text" || type == "textarea") {
  	        try {
              field.focus();
            } catch (e) {}
	        }
	            
	        return;
	      }
	    }
	  }
	  
	  try {
      parent = parent.parentNode;
    } catch (e) {}
	}
}

/**
 * transform text to fancy URL format (e.g. "My Name Of Item" to "my-name-of-item")
 * 
 * @param string txt       text to be formatted
 * @param string obj_id    HTML object to which the output will be returned (function will set object's 'value' attribute)
 */
function toFancy(txt, obj_id) {
  if (txt) {
	  var ajax = new traxi();
	  ajax.action_script = server_check_action_script;
	  ajax.execute_response = true;
	  ajax.set("action", "text_to_fancy");
	  ajax.set("text", txt);
	  ajax.set("obj_id", obj_id);
    ajax.run();	  
  }
}

/**
 * start displaying field long help text as a card
 *    
 * @param array id            label name which contains help text
 * @param object obj          reference object used for card positioning
 * @param boolean editable    [optional] if true, allow text editing (used when in admin mode)
 * @return void
 */
function formFieldHelp(id, obj, editable) {
  if (editable) {    // if editable, wait before showing a card
	  var delay = 1000;    // time to wait before showing a card, in miliseconds
	
	  // store values in global variables
	  card_id = id;
	  card_obj = obj;
	  card_timer = setTimeout("formFieldHelpStart()", delay);  
  } else {    // if not editable, show card immediately
	  var query = "action=card&type=form_help&editable=0&id=" + id;
	  
	  showCard(query, obj, 360);  
  }
}

/**
 * display field long help text as a card
 *    
 * @return void
 */
function formFieldHelpStart() {
  var query = "action=card&type=form_help&editable=1&id=" + card_id;
  
  showCard(query, card_obj, 420);
}

/**
 * cancel displaying field long help text as a card
 *
 * @return void
 */
function formFieldHelpCancel() {
  if (card_timer) {
    clearTimeout(card_timer);
  }
}

/*
 * general functions / END
 */


/*
 * field: choose functions / START
 */
 
/**
 * add selected option(s) in left select field to list of chosen options in right select field
 *    
 * @param string id    id of choose field
 * @return void
 */
function formChooseAddToList(id) {
  var obj = document.getElementById("choose_" + id);
  var selected = false;

  if (obj.options) {
    var option;
    
    for (var i=0; i<obj.options.length; i++) {    // process all selected options in left select field
      if (obj.options[i].selected) {
        option = formSelectAddOption(id, obj.options[i].value, obj.options[i].text);
        if (option) {    // mark new option as selected
          option.selected = true;
        }
        
        selected = true;
      }
    }
  }

  if (!selected) {    // inform user that he didn't select option to be added
    alert(label("FORM_CHOOSE_NO_OPTION_SELECTED"));
  }
}

/**
 * remove selected option(s) in right select field to list of source options in left select field
 *    
 * @param string id    id of choose field
 * @return void
 */
function formChooseRemoveFromList(id) {
  var obj = document.getElementById(id);
  var selected_options = new Array();
  var counter = 0;

  if (obj.options) {
	  for (var i=0; i<obj.options.length; i++) {    // make list of all selected options in right select field
	    if (obj.options[i].selected) {
	      selected_options[counter] = obj.options[i].value;
	      counter++;
	    }
	  }
	}

	if (selected_options.length) {
	  for (i=0; i<selected_options.length; i++) {    // remove all selected options
	    formSelectRemoveOption(obj, selected_options[i]);
	  }
	} else {    // inform user that he didn't select option to be removed
	  alert(label("FORM_CHOOSE_NO_OPTION_SELECTED"));
	}
}

/*
 * field: choose functions / END
 */


/*
 * field: datetime functions / START
 */
 
/**
 * show calendar to choose date
 *    
 * @param mixed obj              date text field or its id
 * @param object obj_calendar    calendar image object (used for calendar positioning)
 * @param string format          date format to be displayed and returned
 * @return void
 */
function formDatetimeCalendarShow(obj, obj_calendar, format) {
  if (document.getElementById(obj)) {    // form identified by its id
    obj = document.getElementById(obj);
  }
  
  displayCalendar(obj, format, obj_calendar, false);
}

/**
 * calculate datetime value from datetime field
 * note: this function is typically called before submitting a form
 *
 * @param string id    datetime field id
 * @return string      datetime in local format
 */
function formDatetimeBuild(id) {
  var date = document.getElementById(id + "_date").value
  
  if (!date) {    // empty value
    return "";
  }

  var hours_select = document.getElementById(id + "_hh");
  var minutes_select = document.getElementById(id + "_mm");
  var seconds_select = document.getElementById(id + "_ss");
  
  var hours = (hours_select ? hours_select.options[hours_select.options.selectedIndex].value : "00");
  var minutes = (minutes_select ? minutes_select.options[minutes_select.options.selectedIndex].value : "00");
  var seconds = (seconds_select ? seconds_select.options[seconds_select.options.selectedIndex].value : "00");

  var t = date + " " + hours + ":" + minutes + ":" + seconds;

  return t;  
}  
 
/*
 * field: datetime functions / END
 */ 

 
/*
 * field: grid functions / START
 */

var grids = new Object();    // object stores data for all grid fields in the form

/**
 * set required variables for grid field
 *    
 * @param string id    id of grid field
 * @return void
 */
function formGridInitialize(id) {
  grids[id] = new Object();
  grids[id].grid_bg = document.getElementById("grid_bg_" + id);    // grid's background when editing row
  grids[id].grid_table = document.getElementById("grid_table_" + id);    // grid's table
  grids[id].grid_form = document.getElementById("grid_form_" + id);      // grid's editing form
  grids[id].active_row = null;

  grids[id].fields = new Array();    // store field definitions (field type and/or field default value)
  grids[id].values = new Array();    // store row values
}

/**
 * fill grid table with data (according to grid values)
 *    
 * @param string id    id of grid field
 * @return void
 */
function formGridFillTable(id) {
  for (row_number in grids[id].values) {
    var row = document.getElementById("grid_row_" + id + "_" + row_number);
    cells = row.childNodes;

    var counter = 0;
    for (field_id in grids[id].fields) {
      cells[counter].innerHTML = formGridGetShowValue(field_id, grids[id].values[row_number][field_id], grids[id].fields[field_id].type);
      counter++;
    }
  }
    
  var php = new PHP_Serializer(true);
  grids[id].grid_field.value = php.serialize(grids[id].values);
}

/**
 * calculate displayable value for grid table (according to field type, for most fields not necessary)
 *    
 * @param string id            id of grid field
 * @param mixed value          raw value stored in grid
 * @param string field_type    type of field for which the value is aimed
 * @return string              value text to be displayed in grid table
 */
function formGridGetShowValue(id, value, field_type) {
  var t = value;    // for most fields, no changes are necessary

  if (field_type == "choose") {    // processing choose field
    var select_left = document.getElementById("choose_" + id);
    var text_values = new Array();
    
    for (var i=0;i<value.length;i++) {
      text_values[i] = formSelectGetOptionText(select_left, value[i]);
    }
    
    t = text_values.join(', ');    // get text representation of value
  }

  if (field_type == "select") {    // processing select field
    var select = document.getElementById(id);
    
    if (select.options) {
      for (var i=0; i<select.options.length; i++) {
        if (select.options[i].value == value) {
          t = select.options[i].text;    // get text representation of value
          
          return t;
        }
      }
    }
  }    

  return t;
}

/**
 * fill grid editing form's fields with values (according to current row when editing row or default values if inserting new row)
 *    
 * @param string id         id of grid field
 * @param boolean is_new    [optional] set to true when inserting new row, leave blank or set to false when editing existing row
 * @return void
 */
function formGridFillForm(id, is_new) {
  var row_number = grids[id].active_row;
  
  for (field_id in grids[id].fields) {
    var field = document.getElementById(field_id);
    var field_type = grids[id].fields[field_id].type;
    
    if (is_new) {    // for new rows try to set default values
      var default_value = (grids[id].fields[field_id].def_value != null ? grids[id].fields[field_id].def_value : null);
    }
    
    if (field_type == "checkbox") {    // processing checkbox field
      if (is_new) {
        if (default_value) {
          field.checked = true;
        }
      } else {
        if (grids[id].values[row_number][field_id]) {
          field.checked = true;
        }
      }
    }

    if (field_type == "choose") {    // processing choose field
      if (field.options) {    // clear previous state
        for (var i=0; i<field.options.length; i++) {
          field.options[i] = null;
        }
        field.options.length = 0;
      }    

      if (!is_new) {    // select option(s) according to cell value
        for (var i=0; i<grids[id].values[row_number][field_id].length; i++) {
          var select_left = document.getElementById("choose_" + field_id);
          var option_value = grids[id].values[row_number][field_id][i];
          var option_text = formSelectGetOptionText(select_left, option_value);
          
          formSelectAddOption(field, option_value, option_text)
        }
      }    
    }

    if (field_type == "select") {    // processing select field
      if (is_new) {
        if (default_value != null) {    // select default option in select field
          for (var i=0; i<field.options.length; i++) {
            if (field.options[i].value == default_value) {
              field.options[i].selected = true;
            }         
          }             
        } else {    // no default value - select first option
          field.selectedIndex = 0;
        }
      } else {    // select option according to cell value
         for (var i=0; i<field.options.length; i++) {
           if (field.options[i].value == grids[id].values[row_number][field_id]) {
             field.options[i].selected = true;
           }         
         }      
      }
    }
    
    if (field_type == "text") {    // processing input text field
      if (is_new) {    // if default value defined, use it, otherwise blank field
        field.value = (default_value != null ? default_value : "");
      } else {    // set value according to cell value
        field.value = grids[id].values[row_number][field_id];
      }
    }
  }
}

/**
 * submit grid editing form
 *    
 * @param string id    id of grid field
 * @return void
 */
function formGridSubmitForm(id) {
  if (grids[id].form_type == "insert") {    // inserting a new row - create row
    formGridTableInsertRow(id);
    grids[id].active_row = grids[id].values.length;
    grids[id].values[grids[id].values.length] = new Array();
  } 

  var row_number = grids[id].active_row;
  
  for (field_id in grids[id].fields) {    // pass through all fields and set values from form fields to grid
    var field = document.getElementById(field_id);
    var field_type = grids[id].fields[field_id].type;
    
    if (field_type == "checkbox") {    // processing checkbox field
      grids[id].values[row_number][field_id] = (field.checked ? 1 : 0);
    }
    
    if (field_type == "choose") {    // processing choose field
      var choose_values = new Array();
      
      for (var i=0;i<field.options.length;i++) {
        choose_values[i] = field.options[i].value;
      }

      grids[id].values[row_number][field_id] = choose_values;
    }    
    
    if (field_type == "select") {    // processing select field
       grids[id].values[row_number][field_id] = field.options[field.options.selectedIndex].value;
    }
    
    if (field_type == "text") {    // processing input text field
      grids[id].values[row_number][field_id] = field.value;
    }
  }

  // update table and select current row
  formGridFillTable(id);
  formGridSelectRow(id, row_number);
  
  // hide editing form
  grids[id].grid_bg.style.width = "0px";
  grids[id].grid_bg.style.height = "0px";
  elementHide(grids[id].grid_form);  
  
  document.onkeypress = function() {};    // disable keypress detection
}

/**
 * cancel grid editing form (user clicked on 'cancel' button)
 *    
 * @param string id    id of grid field
 * @return void
 */
function formGridCancelForm(id) {
  // hide editing form
  grids[id].grid_bg.style.width = "0px";
  grids[id].grid_bg.style.height = "0px";
  elementHide(grids[id].grid_form);
  
  document.onkeypress = function() {};    // disable keypress detection
}

/**
 * mark row of grid table as selected
 * 
 * @param string id             id of grid field
 * @param integer row_number    ordinal number of row in grid table (counted from 0)
 * @return void
 */
function formGridSelectRow(id, row_number) {
  for (var i=0; i<grids[id].values.length; i++) {
    var tr = document.getElementById("grid_row_" + id + "_" + i);
    if (i == row_number) {
      tr.className = "grid_row_active";
      grids[id].active_row = row_number;
      formGridEnableTools(id);    // make controls visible
    } else {
      tr.className = "";
    }
  }
}

/**
 * edit currently selected grid row or create new row, display editing form
 * 
 * @param string id         id of grid field
 * @param boolean is_new    [optional] set to true when inserting new row, leave blank or set to false when editing existing row
 * @return void
 */
function formGridEditRowForm(id, is_new) {
  formGridFillForm(id, is_new);    // set form fields to appropriate values

  // enable keypress detection to handle some keys (e.g. escape for cancelling a form)
  document.onkeypress = function(e) {
    if (!e) {
      e = window.event;
    }
    
    if (e.keyCode == 27) {    // escape has been pressed - cancel editing form
      formGridCancelForm(id);
    }
  };

  // calculate form's background dimensions
  grids[id].grid_bg.style.width = (grids[id].grid_bg.offsetParent.offsetWidth + 5) + "px";
  grids[id].grid_bg.style.height = (grids[id].grid_bg.offsetParent.offsetHeight + 50) + "px";

  elementShow(grids[id].grid_bg);
  elementShow(grids[id].grid_form);
  
  // focus on first field on the form
  var counter = 0;
  for (field_id in grids[id].fields) {
    if (counter == 0) {
      document.getElementById(field_id).focus();
      counter = 1;
    }
  }
  
  grids[id].form_type = (is_new ? "insert" : "edit");    // set form type for submit processing
}

/**
 * delete currently selected grid row
 * 
 * @param string id    id of grid field
 * @return void
 */
function formGridDeleteRow(id) {
  if (grids[id].active_row != null) {    // process only when row is selected
		var status = confirm(label("FORM_GRID_DO_YOU_WANT_TO_DELETE_ROW"));    // confirm delete operation
		
		if (status) {
      formGridTableDeleteRow(id);
			grids[id].values.splice(grids[id].active_row, 1);
			grids[id].active_row = null;
			formGridFillTable(id);
			formGridSelectRow(id, null);    // deselect deleted row
			formGridDisableTools(id);
		}
	}
}

/**
 * move currently selected grid row up
 * 
 * @param string id    id of grid field
 * @return void
 */
function formGridMoveRowUp(id) {
  var row_number = grids[id].active_row;
  
  if (row_number) {    // process only when not on the first row and row is selected
    formGridSwitchRows(id, row_number, row_number - 1);
    formGridSelectRow(id, row_number - 1);
  }
}

/**
 * move currently selected grid row down
 * 
 * @param string id    id of grid field
 * @return void
 */
function formGridMoveRowDown(id) {
  var row_number = grids[id].active_row;
  
  if ((row_number < grids[id].values.length - 1) && (row_number != null)) {    // process only when not on the last row and row is selected
    formGridSwitchRows(id, row_number, row_number + 1);
    formGridSelectRow(id, row_number + 1);
  }
}

/**
 * switch grid row values (used for rows movement)
 * 
 * @param string id       id of grid field
 * @param integer row1    ordinal number of first row
 * @param integer row2    ordinal number of second row;
 * @return void
 */
function formGridSwitchRows(id, row1, row2) {
  // switch values
  var tmp = grids[id].values[row1];
  grids[id].values[row1] = grids[id].values[row2];
  grids[id].values[row2] = tmp;

  formGridFillTable(id);    // update view
}

/**
 * delete row from grid table (from the last position)
 * 
 * @param string id    id of grid field
 * @return void
 */
function formGridTableDeleteRow(id) {
  if (grids[id].values.length > 0) {    // process only when some rows exist
	  var table = document.getElementById("grid_table_" + id);
	  var tr = document.getElementById("grid_row_" + id + "_" + (grids[id].values.length - 1));
	
	  // remove row from the table
	  var table_section = table.childNodes[0];
	  table_section.removeChild(tr);
	}
}

/**
 * insert row to grid table (to the last position)
 * 
 * @param string id    id of grid field
 * @return void
 */
function formGridTableInsertRow(id) {
  var table = document.getElementById("grid_table_" + id);

  // create new table row
  var tr = document.createElement("TR");
  
  row_number = grids[id].values.length;

  tr.id = "grid_row_" + id + "_" + row_number;
  tr.row_number = row_number;
  tr.grid_id = id;
  tr.onclick = function() { formGridSelectRow(this.grid_id, this.row_number); };
  tr.ondblclick = function() { formGridSelectRow(this.grid_id, this.row_number);formGridEditRowForm(this.grid_id); }

  // create table cells
  for (field_id in grids[id].fields) {
    var td = document.createElement("TD");
    td.innerHTML = "&nbsp;";
    tr.appendChild(td);
  }
  
  // append row to the table
  var table_section = table.childNodes[0];
  table_section.appendChild(tr);  
}

/**
 * enable row manipulation tools (image controls)
 * 
 * @param string id    id of grid field
 * @return void
 */
function formGridEnableTools(id) {
  var edit = document.getElementById("grid_tool_edit_" + id);
  var del = document.getElementById("grid_tool_delete_" + id);
  var up = document.getElementById("grid_tool_up_" + id);
  var down = document.getElementById("grid_tool_down_" + id);  

  if (edit) {
    edit.className = "grid_tool_edit_enabled";
  }
  if (del) {
    del.className = "grid_tool_delete_enabled";
  }
  if (up) {
    up.className = "grid_tool_up_enabled";
  }
  if (down) {
    down.className = "grid_tool_down_enabled";
  }
}

/**
 * disable row manipulation tools (image controls)
 * 
 * @param string id    id of grid field
 * @return void
 */
function formGridDisableTools(id) {
  var edit = document.getElementById("grid_tool_edit_" + id);
  var del = document.getElementById("grid_tool_delete_" + id);
  var up = document.getElementById("grid_tool_up_" + id);
  var down = document.getElementById("grid_tool_down_" + id);  

  if (edit) {
    edit.className = "grid_tool_edit_disabled";
  }
  if (del) {
    del.className = "grid_tool_delete_disabled";
  }
  if (up) {
    up.className = "grid_tool_up_disabled";
  }
  if (down) {
    down.className = "grid_tool_down_disabled";
  }
}

/*
 * field: grid functions / END
 */


/*
 * field: input functions / START
 */

/**
 * highlight form input element when actually typing text in it
 *    
 * @param mixed obj    input element object or object's id
 * @return void
 */
function formInputHighlightTyping(obj) {
  if (document.getElementById(obj)) {    // object identified by its id
    obj = document.getElementById(obj);
  }

  switchClass(obj, "typing", "");
}

/**
 * copy text from form input field src_obj to form field dest_obj
 *    
 * @param mixed src_obj              source input text field or input's id
 * @param mixed dest_obj             destination input text field or input's id
 * @param string fancy_url_format    [optional] if true, tranform output to fancy URL format (@see toFancy() function)
 * @return void
 */
function formInputCopyText(src_obj, dest_obj, fancy_url_format) {
  if (element(src_obj)) {    // object identified by its id
    src_obj = element(src_obj);
  }
  if (element(dest_obj)) {    // object identified by its id
    dest_obj = element(dest_obj);
  }
  
  var value = src_obj.value;

  if (fancy_url_format) {    // set value by toFancy() function
    toFancy(value, dest_obj.id);
    return;
  }
  
  dest_obj.value = value;
}

/**
 * create keywords from text in input field src_obj and store to form field dest_obj

 * @param mixed src_obj     source input text field or input's id
 * @param mixed dest_obj    destination input text field or input's id
 * @return void
*/  
function formInputCreateKeywords(src_obj, dest_obj) {
  if (element(src_obj)) {    // object identified by its id
    src_obj = element(src_obj);
  }
  if (element(dest_obj)) {    // object identified by its id
    dest_obj = element(dest_obj);
  }
  
  var data = new Array();
  var text = src_obj.value;
  var counter = 0;
  
  var text_array = text.split(" ");

  for (word in text_array) {
    if (text_array[word].length > 2) {
      data[counter] = text_array[word].toLowerCase();
      counter++;
    }
  }
  
  dest_obj.value = data.join(", ");
}

/*
 * field: input functions / END
 */

 
/*
 * field: select functions / START
 */

/**
 * mark all options in select field as selected
 *    
 * @param mixed obj    select field object or select field id
 * @return boolean     allways returns true (this function is used in onsubmit() functions of HTML forms)
 */
function formSelectSelectAllOptions(obj) {
  if (document.getElementById(obj)) {    // object identified by its id
    obj = document.getElementById(obj);
  }
  
  if (obj.options) {
    for (var i=0; i<obj.options.length; i++) {
      obj.options[i].selected = true;
    }
  }

  return true;
}

/**
 * add option to select field
 *    
 * @param mixed obj    select field object or select field id
 * @param value        option value attribute
 * @param text         option text
 * @return mixed       created option object or false if option already exists
 */
function formSelectAddOption(obj, value, text) {
  if (document.getElementById(obj)) {    // object identified by its id
    obj = document.getElementById(obj);
  }
  
  if (!formSelectOptionExists(obj, value)) {    // don't add option if it already exists
    var option = new Option(text, value);
    obj.options[obj.options.length] = option;
    
    return option;
  }
  
  return false;
}

/**
 * remove option from select field
 *    
 * @param mixed obj    select field object or select field id
 * @param value        option value attribute
 * @return void
 */
function formSelectRemoveOption(obj, value) {
  if (document.getElementById(obj)) {    // object identified by its id
    obj = document.getElementById(obj);
  }
  
  if (obj.options) {
    for (var i=0; i<obj.options.length; i++) {
      if (obj.options[i].value == value) {
        obj.options[i] = null;
      }
    }
  }
}

/**
 * check whether option exists in select field
 *    
 * @param mixed obj    select field object or select field id
 * @param value        option value attribute
 * @return boolean     true if option exists, false otherwise
 */
function formSelectOptionExists(obj, value) {
  if (document.getElementById(obj)) {    // object identified by its id
    obj = document.getElementById(obj);
  }

  if (obj.options) {
    for (var i=0; i<obj.options.length; i++) {
      if (obj.options[i].value == value) {
        return true;
      }
    }
  }
  
  return false;
}

/**
 * return text of option
 *    
 * @param mixed obj    select field object or select field id
 * @param value        option value attribute
 * @return boolean     option text
 */
function formSelectGetOptionText(obj, value) {
  var t = "";

  if (document.getElementById(obj)) {    // object identified by its id
    obj = document.getElementById(obj);
  }
  
  if (obj.options) {
    for (var i=0; i<obj.options.length; i++) {
      if (obj.options[i].value == value) {
        return obj.options[i].text;
      }
    }
  }  

  return t;
}

/**
 * replace option text
 *    
 * @param mixed obj              select field object or select field id
 * @param string old_text        current option text
 * @param string new_text        replacement option text
 * @return void
 */
function formSelectReplaceOptionText(obj, old_text, new_text) {
  if (document.getElementById(obj)) {    // object identified by its id
    obj = document.getElementById(obj);
  }
  
  if (obj.options) {
    for (var i=0; i<obj.options.length; i++) {
      if (obj.options[i].text == old_text) {
        obj.options[i].text = new_text;
      }
    }
  }
}

/*
 * field: select functions / END
 */
 
 
/* 
 * server check feature functions / START
 */
 
var server_check = new Object();    // object stores data for all server checks in the form
var server_check_value = new Object();    // stores custom field values

/**
 * check form values on the server
 *    
 * @param string form_id    form id
 * @return boolean          allways returns false
 *                          note: this function is placed as the last function in 'onsubmit' form attribute. If form has to be submitted (no errors found), it is submitted manually by this function (see .onSuccess function)
 */
function formServerCheck(form_id) {
  var form = document.getElementById(form_id);

	// display preloader image
	var img = new Image();
	img.src = server_check_preloader_img;
	img.id = "form_server_check_preloader";
	
	// add indicator to form submit button
  var fields = form.elements;
  for (i in fields) {
    try {
      if (fields[i].className.indexOf("submit") !== -1) {
        var div = fields[i].parentNode;
        div.appendChild(img);
      }
    } catch (e) {}
  }
	
	// prepare values for server
	var obj;
	var value;
	var server_check_params = new Array();
	var server_check_values = new Array();
	
	var counter = 0;
	for (field_id in server_check) {
	  for (type in server_check[field_id]) {
	    obj = document.getElementById(field_id);
	    
	    // get value to be validated
	    if (obj) {
	      obj.server_check_tab_name = formGetFieldParentTabName(obj);
	    
	      if (server_check_value[field_id] && server_check_value[field_id][type]) {    // if custom method how to get value requested, execute
          eval("value = " + server_check_value[field_id][type]);
          
          if (!value) {    // ensure value is always set
            value = "";
          }
	      } else {    // default way how to get value from field
          value = obj.value;
        }
        
        // escape some special characters
	      value = value.replace(/\&/g, "*ampersand*");
	      value = value.replace(/\,/g, "*comma*");
	      value = value.replace(/\+/g, "*plus*");
	      value = value.replace(/\%/g, "*percent*");

	    } else {
	      value = "";
	    }
	    
      server_check_params[counter] = server_check[field_id][type];
      server_check_values[counter] = value;
      
      counter++;  
	  }
	}
  
  // make request to check values on server
  var ajax = new traxi();
  ajax.action_script = server_check_action_script;
  ajax.execute_response = false;
  ajax.set("action", "form_server_check");
  ajax.set("form_id", form_id);
  ajax.set("server_check_params", server_check_params);
  ajax.set("server_check_values", server_check_values);

  ajax.onSuccess = function () {    // run this action if all values validated
    var img = document.getElementById("form_server_check_preloader"); 
    var form = document.getElementById(form_id);

    if (this.response == "OK") {
      form.submit();
    } else {
      try { 
        eval(this.response);
      } catch(e) {};
      img.parentNode.removeChild(img);
    }
  };
  
  ajax.onFailure = function () {    // run this action if some value not validated
    var img = document.getElementById("form_server_check_progress"); 
    img.parentNode.removeChild(img);
  };

  ajax.run();

  return false;
}

/**
 * get id of tab which is parent for given form element
 *
 * @param object obj    form field object
 * @return mixed        parent tab name if parent tab found or null if parent tab not found
 */
function formGetFieldParentTabName(obj) {
	var parent;
	
	try {
    parent = obj.parentNode;
  } catch (e) {}

	while (parent) {
	  if (parent.tagName == "DIV" && parent.id.substring(0,3) == "tab") {
	    return parent.id.substring(4);
	  }
	  parent = parent.parentNode;
	}
	
	return null;
} 
 
/*
 * server check feature functions / END
 */
 
 
/*
 * multiple action functions / START
 */ 

/**
 * un/checks all checkbox fields with the same name
 *    
 * @param boolean check             set status - if true, check boxes, if false, uncheck boxes
 * @param array checkboxes_array    array containing list of checkbox objects with the same name
 * @return void
 */
function formCheckAllBoxes(check, checkboxes_array) {
  for (var i=0;i<checkboxes_array.length;i++) {
    if ((check && !checkboxes_array[i].checked) || (!check && checkboxes_array[i].checked)) {
      checkboxes_array[i].checked = check;
      switchClass(checkboxes_array[i].parentNode.parentNode.parentNode, "multiple_checked", "");    // (de)highlight whole row
    }
  }
}

/**
 * checks/unchecks all checkboxes in list of results (method showResults())
 *    
 * @param array checkboxes_array    array containing list of checkbox objects with the same name
 * @return void
 */
function formMultipleActionCheckAllBoxes(checkboxes_array) {
  if (!checkboxes_array.length) {    // ensure we process an array (when there is only one result in the list)
    checkboxes_array = new Array(checkboxes_array);
  }

  var link = document.getElementById("multiple_check_link");

  if (link.my_checked) {
    formCheckAllBoxes(false, checkboxes_array);
    link.my_checked = false;
  } else {
    formCheckAllBoxes(true, checkboxes_array);
    link.my_checked = true;
  }
  
  switchClass(link, "multiple_checked", "multiple_unchecked");
}

/**
 * confirm execution of multiple action (make some controls before multiple action is executed)
 *    
 * @param mixed action_obj    object or id of object which is used for selecting multiple action (selectbox)
 * @param mixed range_obj     object or id of object which is used for selecting range of multiple action's impact
 * @return boolean            true if no error occured and user confirmed execution, false otherwise
 */
function formMultipleActionConfirm(action_obj, range_obj) {
  if (document.getElementById(action_obj)) {    // object identified by its id
    action_obj = document.getElementById(action_obj);
  }
  if (document.getElementById(range_obj)) {    // object identified by its id
    range_obj = document.getElementById(range_obj);
  }

  var checkboxes_array = document.form_multiple_action.multiple_action_check;
  if (!checkboxes_array.length) {    // ensure we process array (when there is only one result in the list)
    checkboxes_array = new Array(checkboxes_array);
  }
  
  if (range_obj.value == "selected") {    // when processing manually selected records, check whether there are some selected
	  var count_checked = 0;
	  
	  for (var i=0;i<checkboxes_array.length;i++) {
		  if (checkboxes_array[i].checked) {
		    count_checked++;
		  }
	  }
	
	  if (count_checked == 0) {    // inform user that he didn't select any records for multiple action
	    alert(label("FORM_MULTIPLE_ACTION_NO_RECORDS_SELECTED"));
	    return false;
	  }
	}

  // actions which require user confirmation
  if (action_obj.value == "delete") {
    var msg = "";
    var template_values = new Array();
    
    if (range_obj.value == "selected") {    // information about manually selected records
      template_values["count"] = count_checked;
      msg = label("FORM_MULTIPLE_ACTION_NUMBER_OF_SELECTED_RECORDS", template_values) + "\n";
    }
    
    template_values["name"] = action_obj.options[action_obj.options.selectedIndex].text;
    msg += label("FORM_MULTIPLE_ACTION_CONFIRMATION", template_values);

    return dialogConfirm(msg);
  }
  
  return true;
}

/*
 * multiple action functions / END
 */
 
/**
 * check value length
 *
 * @param mixed obj      object or object's id to get value from
 * @param string msg     [optional] message to be displayed in case error has appeared
 * @param integer min    [optional] value minimal length
 * @param integer max    [optional] value maximum length
 * @return boolean       true if value meets conditions, false otherwise
 */
function formCheckLength(obj, msg, min, max) {
  var status = true;
  if (element(obj)) {    // object identified by its id
    obj = element(obj);
  }
  var txt = obj.value;
  
  if (min != null && max != null) {
    if (txt.length < min || txt.length > max) {
      status = false;
    }
  } else {
    if (min != null) {
      if (txt.length < min) {
        status = false;
      }
    } else {
      if (txt.length > max) {
        status = false;
      }   
    }
  }
  
  if (!status && msg != null) {
    alert(msg);
  }
  
  return status;
}

