///////////////////////////////////////////////////////////////////////////
//
// ui.js
//
// Copyright (c) 2003 by HERMES SoftLab
//
///////////////////////////////////////////////////////////////////////////
//
// Common client-side javascript code
//
///////////////////////////////////////////////////////////////////////////

// Checks browser
// Returns: true if Internet Explorer, otherwise false
function CheckIE()
{
  return (navigator.appName == "Microsoft Internet Explorer");
}

// Gets attribute value of a provided html element
// Returns attribute value or null if attribute does not exist
function GetTagAttribute(elt, attributeName) {
  if (elt.attributes[attributeName]) {
    return elt.attributes[attributeName].nodeValue;
  } else if (elt.attributes[attributeName.toLowerCase()]) {
    return elt.attributes[attributeName.toLowerCase()].nodeValue;
  } else {
    // IE 5.5 browser must extract attribute from actual html tag since custom properties aren't saved to DOM
    var re = new RegExp(attributeName + "=\"([^\"]*)\"", "i");
    var matches = elt.outerHTML.match(re);
    if (matches) {
      return (matches[1]);
    } else return null;
  }
}

// Attaches event to element
// el: element to attach event to
// evname: event name to attach (without "on" prefix)
// func: function to envoke on event
function AddEvent(el, evname, func) {
  if (el.attachEvent) { // IE
	  el.attachEvent("on" + evname, func);
  } else if (el.addEventListener) { // Gecko / W3C
	  el.addEventListener(evname, func, true);
  } else { // Old browsers)
	  el["on" + evname] = func;
  }
}

// Returns element that invoked provided event
function GetEventElement(e) {
  if ( typeof( window.event ) != "undefined" ) {
	  return window.event.srcElement;
  }
  if ( e != null && typeof( e.target ) != "undefined" ) {
	  return e.target;
  }
  return null;
}

/// Sets state of checkboxes
/// refname: all checkboxes on page of which custom attribute "refname" has a value of refname
/// state: boolean value to set checkboxes to
/// will be set to the master checkbox value
/// Example: ToggleAllCheckBoxes(masterChk, "house")
/// will set checkboxes that have custom attribute refname="house"
function SetCheckBoxes(refname, state)
{
  var tagCollection = document.getElementsByTagName("input");
  for (i=0; i<tagCollection.length; i++)
  {
    elt = tagCollection[i];
    if (elt.type == "checkbox" && GetTagAttribute(elt, "refname") != null && GetTagAttribute(elt, "refname") == refname)
    {
      elt.checked = state;
    }
  }
}

/// Envoke click on targetEltName
function SubmitOnEnter(e, btnName) {
  if (CheckIE()) {
    k = event.keyCode;
    if (k == 13) {
      event.returnValue = false;
      event.cancel = true;
      document.getElementById(btnName).click();
    }
  } else {
    // NonIE browsers
    if (e.which == 13) {
      document.getElementById(btnName).click();
    }
  }
}

/// Put focus on targetEltName
function FocusOnEnter(e, targetEltName) {
  if (CheckIE()) {
    k = event.keyCode;
    if (k == 13) {
      event.returnValue = false;
      event.cancel = true;
      document.getElementById(targetEltName).focus();
    }
  } else {
    // NonIE browsers
    if (e.which == 13) {
      document.getElementById(targetEltName).focus();
    }
  }
}

/// Toogles visible/invisible style of provided element.
/// name: id of element to toogle visibility
function SwapVisible(name)
{
  elt = document.getElementById(name);
  SwapVisibleByElement(elt);
}

/// Toogles visible/invisible style of provided element.
/// elt: reference to element to toogle visibility
function SwapVisibleByElement(elt)
{
  if (elt.style.display == "inline")
  {
    elt.style.display = "";
  }
  else
  {
    elt.style.display = "inline";
  }
}

/// Returns element with provided id that is a descender of provided element.
function GetElementById(parentElt, id)
{
  var chNodes = parentElt.childNodes;
  var i;
  for(i=0; i < chNodes.length; i++)
  {
    if (chNodes[i].id == id) return chNodes[i];
    var tmpNode = GetElementById(chNodes[i], id);
    if (tmpNode != null) return tmpNode;
  }
  return null;
}

/// Selects an option in drop down list that has provided value.
function SelectDropDownList(list, value)
{
  for (i=0; i<list.options.length; i++) {
    if (list.options[i].value == value) {
      list.options[i].selected = true;
      return;
    }
  }
}

///////////////////////////////////////////////////////////////////////////
//
// Dynamic table
//
// Dynamic table functionality that enables to
// add/delete table rows with form fields dynamicaly client-side.
//
// Constructor:
// - tableId: id name of HTML table to become dynamic
// - templateRowIndex: index of template row
// - templateRowsCount: number of template rows (e.g. if a template row actually consists of more rows)
// - hasRowEnumeration: true if table has row enumration
//
// Guidelines
// 1. Create a HTML table with one or more header rows
// 2. In stylesheet define class .hidden {display: none}
// 3. As last row in a table create a "template" row and set TR class="hidden" to become hidden.
//    This row will be used as a template row (when it's dynamicaly added client-side)
// 4. Somewhere in the hidded row add <span id="rowIndex">1</span> which will be used
//    to dynamicaly enumerate rows.
//
///////////////////////////////////////////////////////////////////////////
function DynamicTable(tableId, templateRowIndex, templateRowsCount, hasRowEnumeration)
{
  this.tableId = tableId;
  this.templateRowIndex = templateRowIndex;
  this.templateRowsCount = templateRowsCount;
  this.hasRowEnumeration = hasRowEnumeration;
  this.dynamicTable = null;
  
  this.AddRow = AddRow;
  this.AddRows = AddRows;
  this.DeleteRow = DeleteRow;
  this.UpdateRowIndex = UpdateRowIndex;
  this.InitTable = InitTable;
  
  function InitTable()
  {
    if (this.dynamicTable == null) this.dynamicTable = document.getElementById(this.tableId);
    if (this.dynamicTable.rows.length <= templateRowIndex+templateRowsCount) this.AddRow();
  }
  
  /// Add new row to table
  /// This function will add new row to the bottom of the table.
  /// It's recommended that first table row is created as a template,
  /// and it's style set to hidden.
  function AddRow()
  {
    if (this.dynamicTable == null) this.dynamicTable = document.getElementById(this.tableId);
    var lastRow = new Array(templateRowsCount);
    for(var i=0; i<templateRowsCount; i++)
    {
      // Clone row
      var originalRow = this.dynamicTable.rows[templateRowIndex+i];
      lastRow[i] = originalRow.cloneNode(true);
      lastRow[i].className = "";
      this.dynamicTable.tBodies[0].appendChild(lastRow[i]);
      
      // Update default selections in all combo boxes (because cloning ignores them)
      if (CheckIE()) {
        var combos = lastRow[i].getElementsByTagName("select");
        for (x=0; x<combos.length; x++) {
          originalValue = GetElementById(originalRow, combos[x].id).value;
          if (originalValue) combos[x].value = originalValue;
        }
      }
      
      // Update rows indexes in table has them defined
      this.UpdateRowIndex(); 
    }
    if (templateRowsCount == 1)
      return lastRow[0];
    else
      return lastRow;
  }
  
  /// Add more rows to table
  /// numberOfRows: number of rows to add
  function AddRows(numberOfRows)
  {
    for(var i=0; i<numberOfRows; i++) this.AddRow();
  }
  
  /// Deletes a row from table
  /// row: Row object to be deleted
  /// Elt can be any element contained in the row.
  function DeleteRow(row)
  {
    var rowIndex = row.rowIndex;
    for (var i=0; i<templateRowsCount; i++) {
      this.dynamicTable.deleteRow(rowIndex);
    } 
    this.InitTable();
    this.UpdateRowIndex();
  }
  
  function UpdateRowIndex()
  {
    if (this.hasRowEnumeration) {
      rows = this.dynamicTable.rows;
      for (var i=templateRowIndex; i<rows.length; i=i+templateRowsCount) {
        GetElementById(rows[i], "rowIndex").innerHTML = (i-templateRowIndex)/templateRowsCount;
      }
    }
  }
};

///////////////////////////////////////////////////////////////////////////
//
// Currency Box
//
// Handles entering currency values with real-time decimal point formatting (eg. 1.230.000,50)
//
// Example:
// <input type="text" CurrencyBoxDecimals="2" CurrencyBoxNonNegative="True" style="text-align: right" onkeypress="return CurrencyBox.OnKeyPress(this, event)" onkeyup="CurrencyBox.OnKeyUp(this, event)" onblur="CurrencyBox.OnBlur(this, event)">
//
// HTML parameters:
// - CurrencyBoxNonDecimals: number of decimal digits
// - CurrencyBoxNonNegative: true to allow only non-negative numbers
//
///////////////////////////////////////////////////////////////////////////
var CurrencyBox = {};

var CurrencyBoxProperties = {
  GroupChar: '.', DecimalChar: ','
};

// Formats provided string to currency number.
// inp: input string
// maxDecimals: maximum number of decimal places
// nonNegative: true to allow only non-negative numbers (>=0)
// setDecimals: whether to add trailing decimal zeros to fill max decimals
// RETURNS: Formated string
CurrencyBox.FormatCurrency = function(inp, maxDecimals, nonNegative, setDecimals) {
  out='';
  minus='';
  if (maxDecimals==null) maxDecimals = 2; // Default is 2 decimals
  // Save minus sign and add in at the end
  if (inp.charAt(0) == '-') {
    minus='-';
    inp = inp.substring(1);
  }

  pointPos = inp.indexOf(CurrencyBoxProperties.DecimalChar);
  if (pointPos == -1) {
    if ((setDecimals==true) && (inp.length == 0)) out = '0';
    pointPos = inp.length-1;
    point=false;
  } else {
    if (pointPos == 0) out = '0';
    pointPos--;
    if (maxDecimals > 0) out = out + CurrencyBoxProperties.DecimalChar;
    point=true;
  }

  // Parse numbers left from the decimal point
  range=0;
  for (var i=pointPos; i>=0; i--) {
    znak=inp.charAt(i);
    if ((znak<'0' || znak>'9')) continue;
    range++;
    if (range==4) {
        out = CurrencyBoxProperties.GroupChar + out;
        range=1;
    }
    out = znak + out;
  }

  // Check if last character is '.' and leave it if it's in proper position
  if ((pointPos == inp.length-1) && (inp.charAt(pointPos)==CurrencyBoxProperties.GroupChar)) {
    if ((pointPos == 3) || ((pointPos > 3) && (inp.charAt(pointPos-4)==CurrencyBoxProperties.GroupChar))) {
       out += CurrencyBoxProperties.GroupChar;
    }
  }

  // Parse numbers right from the decimal point
  decimals=0;
  if (point == true) {
    for (i=pointPos+1; i<inp.length; i++) {
      znak=inp.charAt(i);
      if (znak<'0' || znak>'9') continue;
      if (decimals >= maxDecimals) break;
      decimals++;
      out = out + znak;
    }
  }
  
  // Add missing decimals (if setDecimals argument is true)
  if ((setDecimals == true) && (decimals < maxDecimals))
  {
    if (point == false) {
      out = out + CurrencyBoxProperties.DecimalChar;
    }
    while (decimals < maxDecimals) {
      out = out + '0';
      decimals++;
    }
  }
  
  // Handle minus sign
  out = minus + out;
  
  return(out);
};
///*** CurrencyBox  ***
// Checks whether user pressed valid key based on currency formatting.
CurrencyBox.OnKeyPress = function(self, e) {
  if (CheckIE())
  {
    k = e.keyCode;
    inp = self.value;
    
    // Allows only numerals and punctuations
    if (k==44) { // comma pressed
      if (inp.indexOf(CurrencyBoxProperties.DecimalChar) == -1 && GetTagAttribute(self, "CurrencyBoxDecimals") > 0) {
        return true;
      } else {
        return false;
      }
    } else if ((k>=48) && (k<=59)) { // digit pressed
        return true;
    } else if (k==45 && GetTagAttribute(self, "CurrencyBoxNonNegative")!= "True") { // minus pressed
        return true;
    }
    else if (k == 13) {
      return true;
    } else {
      return false;
    }
  } else { // For nonIE allow all
    return true; 
  }
};
// *** CurrencyBox ***
// Execute real-time currency formatting.
CurrencyBox.OnKeyUp = function(self, e) {
  if (CheckIE()) {
    // Get old cursor position
    rightPos = self.value.length + document.selection.createRange().move('character', -0x7FFFFFFF);

    // Format currency number
    newVal = CurrencyBox.FormatCurrency(self.value, GetTagAttribute(self,"CurrencyBoxDecimals"),GetTagAttribute(self,"CurrencyBoxNonNegative")=="True", false); 
    self.value = newVal;

    // Position the cursor
    rng = self.createTextRange();
    rng.move('character', newVal.length-rightPos);
    rng.select();
  }
};
// *** CurrencyBox ***
// Formats currency box on textbox blur event
CurrencyBox.OnBlur = function(self, e) {
  if (self.value != "")
    self.value = CurrencyBox.FormatCurrency(self.value, GetTagAttribute(self,"CurrencyBoxDecimals"),GetTagAttribute(self,"CurrencyBoxNonNegative")=="True", true);
};
///////////////////////////////////////////////////////////////////////////
//
// Number Box
//
// Handles entering positive and/or negative integer numbers
//
// Example:
// <input type="text" NumberBoxNonNegative="false" onkeypress="return NumberBox.OnKeyPress(this, event)" onblur="NumberBox.OnBlur(this, event)">
//
// HTML parameteres:
// - NumberBoxNonNegative: true to allow only non-negative integers (>=0)
//
///////////////////////////////////////////////////////////////////////////
var NumberBox = {};

NumberBox.OnKeyPress = function(self, e) {
  if (CheckIE()) {
    k = event.keyCode;

    if ((k>=48) && (k<=59)) {
        // Allows numerals
        return true;
    } else if (k == 45 && GetTagAttribute(self,"NumberNonNegative") != "True") {
      // Allow minus sign if nonNegative parameter is not true
      return true;
    } else if (k == 13) {
      return true;
    } else {
      return false;
    }
  } else {
    // NonIE browsers allow all
    return true;
  }
};
NumberBox.OnBlur = function(self, e) {
  val = self.value;
  newval = '';
  // Handle digits
  for (i=0; i<val.length; i++) {
    c = val.charAt(i);
    if ((c >= '0') && (c <= '9')) newval += c;
  }
  
  // Handle minus
  if (val.charAt(0) == '-' && GetTagAttribute(self,"NumberBoxNonNegative") != "True") {
   newval = '-' + newval;
  }
  self.value = newval;
};
///////////////////////////////////////////////////////////////////////////
//
// Date Box
//
// Handles entering date with real-time point formatting (eg. 12.12.2004)
//
// Example:
// <input type="text" DateSeparator="." onkeypress="return DateBox.OnKeyPress(this, event)" onkeyup="DateBox.OnKeyUp(this, event)">
//
// HTML parameters:
// - DateSeparator: separator character
//
///////////////////////////////////////////////////////////////////////////
var DateBox = {};

var DateBoxProperties = {
  Separator: '.'
};

///*** DateBox  ***
// Checks whether user pressed valid key
DateBox.OnKeyPress = function(self, e) {
  if (CheckIE())
  {
    k = e.keyCode;
    inp = self.value;

    // Allows only numerals and punctuations
    if (k == DateBoxProperties.Separator.charCodeAt(0)) { // comma pressed
      return true;
    } else if ((k>=48) && (k<=59)) { // digit pressed
      return true;
    }
    else if (k == 13) {
      return true;
    } else {
      return false;
    }
  } else { // For nonIE allow all
    return true; 
  }
};
// *** DateBox ***
// Execute real-time date formatting.
DateBox.OnKeyUp = function(self, e) {
  if (CheckIE()) {
    k = e.keyCode;
    
    if (k!=8 && k!=46) { // if anything but del or BS pressed
      // Get old cursor position
      rightPos = self.value.length + document.selection.createRange().move('character', -0x7FFFFFFF);

      // Format date
      re = /(^\d{2}$)|(^\d{1,2}\.\d{2}$)/;
      if (re.test(self.value)) self.value += ".";
      
      // Remove duplicated commas
      if (self.value.indexOf('..') != -1) self.value = self.value.replace('..','.');

    }

  }
};
///////////////////////////////////////////////////////////////////////////
//
// Time Box
//
// Handles entering time with real-time separator formatting (eg. 10:30)
//
// Example:
// <input type="text" TimeSeparator=":" onkeypress="return TimeBox.OnKeyPress(this, event)" onkeyup="TimeBox.OnKeyUp(this, event)">
//
// HTML parameters:
// - TimeSeparator: hh:mm separator character
//
///////////////////////////////////////////////////////////////////////////
var TimeBox = {};

var TimeBoxProperties = {
  Separator: '.'
};

///*** TimeBox  ***
// Checks whether user pressed valid key
TimeBox.OnKeyPress = function(self, e) {
  if (CheckIE())
  {
    k = e.keyCode;
    inp = self.value;

    // Allows only numerals and punctuations
    if (k == TimeBoxProperties.Separator.charCodeAt(0)) { // separator pressed
      return true;
    } else if ((k>=48) && (k<=59)) { // digit pressed
      return true;
    }
    else if (k == 13) {
      return true;
    } else {
      return false;
    }
  } else { // For nonIE allow all
    return true; 
  }
};
// *** TimeBox ***
// Execute real-time time formatting.
TimeBox.OnKeyUp = function(self, e) {
  if (CheckIE()) {
    k = e.keyCode;
    
    if (k!=8 && k!=46) { // if anything but del or BS pressed
      // Get old cursor position
      rightPos = self.value.length + document.selection.createRange().move('character', -0x7FFFFFFF);

      // Format time
      re = /(^\d{2}$)|(^[3-9]$)/;
      if (re.test(self.value)) self.value += TimeBoxProperties.Separator;
      
      // Remove duplicated commas
      var duplicateSeparator = TimeBoxProperties.Separator + TimeBoxProperties.Separator;
      if (self.value.indexOf(duplicateSeparator) != -1) self.value = self.value.replace(duplicateSeparator, TimeBoxProperties.Separator);

    }

  }
};
///////////////////////////////////////////////////////////////////////////
//
// Text Area size limit
//
// Limits number of characters in textarea
//
// Example:
// <textarea TextAreaMaxLength="10" onkeyup="TextArea.OnChange(this, event)" onblur="TextArea.OnChange(this, event)"></textarea>
//
// HTML parameteres:
// - TextAreaMaxLength: maximum number of characters to allow inserting in textarea
//
///////////////////////////////////////////////////////////////////////////
var TextArea = {};

TextArea.OnChange = function(self, e) {
  maxLength = GetTagAttribute(self, "TextAreaMaxLength");
  if (maxLength && self.value.length > maxLength) self.value = self.value.substring(0, maxLength);
};
///////////////////////////////////////////////////////////////////////////
//
// AttachmentList
//
// Web part to handle attaching files
//
// Example (web part for attaching one file):
//     <table id="AttachmentListTable" style="display: none" cellspacing="0" class="tablebullet">
//      <tr class="first">
//        <td>Oznaka</td>
//        <td>Datoteka</td>
//        <td>Komentar</td>
//        <td></td>
//      </tr>
//      <tr id="P1_RowEdit" style="display: none">
//        <td>P1</td>
//        <td><input type="file" id="P1_AttachmentFile" name="P1"></td>
//        <td><input type="text" id="P1_AttachmentComment" class="tabledisplay" name="status"></td>
//        <td><input type="button" value="Briši prilogo" onclick="AttachmentList.DeleteTemp('P1')"></td>
//      </tr>
//      <tr id="P1_RowView">
//        <td>P1</td>
//        <td><a href="GetAttachment.aspx?id=XXX" target="_blank">ime1.doc</a></td>
//        <td>Komentar 1</td>
//        <td><input type="button" value="Briši prilogo" onclick="AttachmentList.DeleteStored('P1')"><input type="hidden" id="P1_AttachmentAction" name="P1_AttachmentAction"></td>
//      </tr>
//    </table>
//
//
///////////////////////////////////////////////////////////////////////////
var AttachmentList = {};

// Shows attachment editor table
AttachmentList.Show = function() {
  document.getElementById("AttachmentListLink").style.display = "none";
  document.getElementById("AttachmentListTable").style.display = "inline";
};
// Deletes newly added attachment
AttachmentList.DeleteTemp = function(id) {
  // Delete attachment (since we can't delete file box value, replace whole file box with new one)
  oldelt = document.getElementById(id+"_AttachmentFile");
  newelt = document.createElement("input");
  newelt.type = "file";
  newelt.id = id+"_AttachmentFile";
  oldelt.parentNode.appendChild(newelt);
  oldelt.parentNode.removeChild(oldelt);
  
  // Delete comment
  document.getElementById(id+"_AttachmentComment").value = "";
};
// Deletes attachment stored on server
AttachmentList.DeleteStored = function(id) {
  // Hide view table row
  document.getElementById(id+"_RowView").style.display = "none";
  // Show edit table row
  document.getElementById(id+"_RowEdit").style.display = "";
  // Set "action" hidden box to "Delete" so that server will know to delete attachment
  document.getElementById(id+"_AttachmentAction").value = "Delete";
};
///////////////////////////////////////////////////////////////////////////
//
// ColapsPanel web control functionality
//
// See Hsl.Edp.Gui.WebControls.ColapsPanel documentation
//
///////////////////////////////////////////////////////////////////////////
function ColapsPanelToggle(id, expandedClass, colapsedClass)
{
  elt = document.getElementById(id + ":header");
  // Toggle panel header class name
  if (elt) {
    if (elt.className == expandedClass)
      elt.className = colapsedClass;
    else
      elt.className = expandedClass;
  }
  // Toggle main panel visibility
  elt = document.getElementById(id);
  if (elt) {
    if (elt.style.display == "none")
      elt.style.display = "";
    else
      elt.style.display = "none";
  }
}


///////////////////////////////////////////////////////////////////////////
//
// AutoCompleteDropDown
//
// Control that simulates combo box with autocomplete user input functionality.
//
// AutoCompleteDropDown ASP user control uses this functionality.
//
///////////////////////////////////////////////////////////////////////////
function AutoCompleteDropDown(textbox, list)
{
	var activeElement = null;
	var textbox = textbox;
	var list = list;

	RegisterControls();
		
	function RegisterControls() {
      var listOnChange;
      var listOnKeyDown;
      if (list.onchange != null){
          listOnChange = list.onchange;
      }
      else {
          listOnChange = function(){};
      }
      if (list.onkeydown != null){
          listOnKeyDown = list.onkeydown;
      }
      else {
          listOnKeyDown = function(){};
      }
	  textbox.onkeydown = function(e) { OnKeyDown(e); window.setTimeout(listOnKeyDown, 50);
	  }; //OnKeyDown;
	  textbox.onkeyup = OnKeyUp;
	  textbox.onfocus = function() { activeElement=textbox; ShowListBox(); textbox.select(); };
	  textbox.onchange = function() { SelectListItem(); };
	  textbox.onblur = function() { activeElement=null; window.setTimeout(HideListBox, 300); };
	  list.onchange = function() { textbox.value = list.options[list.selectedIndex].text; MarkAsValid(true); ForceHideListBox(); window.setTimeout(listOnChange, 50);
	  };
	  list.onfocus = function() { activeElement=list; };
	  list.onblur = function() { activeElement=null; window.setTimeout(HideListBox, 300); };
	}

	function ShowListBox() {
	  list.parentNode.style.display = "";
	}
	
	function HideListBox() {
	 if (activeElement != textbox && activeElement != list) ForceHideListBox();
	}
	
	function ForceHideListBox() {
	 list.parentNode.style.display = "none";
	}
	
	function OnKeyUp(e) {
	  var k = e != null ? e.which : event.keyCode;
	
	  if (k==35 || k==36 || k==38 || k==40 || k==13) {
		// Ignore key events already handled in keydown event
		return false;
	  } else if (textbox.value.length >= 0) {
		MarkAsValid(true);
		var listText = SelectListItem();    
		if (listText && listText != textbox.value) { // Fill textbox
		  if (k!=8 && k!=46 && k!=33 && k!=34 && k!=37 && k!=39) { // Do not fill textbox if del or cursors pressed
			if (textbox.createTextRange) {
			  var textboxLength = textbox.value.length;
			  textbox.value = listText;
			  var rng = textbox.createTextRange();
			  rng.moveStart('character', textboxLength);
			  rng.select();
			}
		  }
		}
	  }
	  return true;
	}

	function OnKeyDown(e) {
	  var k = e != null ? e.which : event.keyCode;
	  
	  if (k==13) { // ENTER pressed
		textbox.value = list.options[list.selectedIndex].text;
		textbox.blur();
		ForceHideListBox();
		return false;
	  } else if (k==38 && list.selectedIndex > 0) { // Cursor UP
		list.selectedIndex--;
	  } else if (k==40 && list.selectedIndex < list.length-1) { // Cursor DOWN
		list.selectedIndex++;
	  } else if (k==36) { // HOME
		list.selectedIndex = 0;
	  } else if (k==35) { // END
		list.selectedIndex = list.length-1;
	  } else return true;
	
	  MarkAsValid(true);
	  textbox.value = list.options[list.selectedIndex].text;
	  textbox.select();
	  return false;
	}

	// Selects item in list which has the same value than in provided textbox
	function SelectListItem() {
	  var textboxValue = textbox.value;
	  for (var i=0; (i < list.length); i++) {
		var listText = list.options[i].text;
		if (textboxValue.length > 0 && listText.toUpperCase().indexOf(textboxValue.toUpperCase()) == 0) {
		  list.options[i].selected = true;
		  MarkAsValid(true);
		  return listText;
		}
	  }
	  list.selectedIndex = -1;
	  if (textboxValue.length > 0) MarkAsValid(false);
	  textbox.focus();
	  return null;
	}

	// Mark textbox valid or invalid, depending whether textbox contains possible value or not
	function MarkAsValid(isValid) {
		if (GetTagAttribute(textbox, "_allowfreeinput") == "False") {
			if (isValid) {
				textbox.parentNode.parentNode.parentNode.parentNode.style.borderColor = "";
			} else {
				textbox.parentNode.parentNode.parentNode.parentNode.style.borderColor = "red";
			}
		}
	}

}


///////////////////////////////////////////////////////////////////////////
//
// TabControl
//
// Functionality for using "page tabs"
//
///////////////////////////////////////////////////////////////////////////
var TabControl = {
    selectedTab: null
};

TabControl.Select = function(elt)
{	
    if (elt.id != this.selectedTab) {
	if (this.selectedTab) document.getElementById(this.selectedTab).className = "tab";
	elt.className = "tabactive";
	this.selectedTab = elt.id;
    }
};
///////////////////////////////////////////////////////////////////////////
//
// HttpGet
//
// Functionality for dynamic client-side communication with server.
//
///////////////////////////////////////////////////////////////////////////

var HttpGet = {};

// Send a HTTP request to server and get a response
HttpGet.LoadValueFromUrl = function(url, onDataLoad) {
	var xmlhttp;
	if (window.ActiveXObject) {
		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
 	} else {
 		try {
 			xmlhttp = new XMLHttpRequest();
 		} catch(e) {
 			return;
 		}
 	}

	xmlhttp.onreadystatechange = function () {
		if (xmlhttp.readyState == 4) OnReadyStateChange(); };
    xmlhttp.open("GET", url);
	xmlhttp.send("");
	
	function OnReadyStateChange() {
		if (xmlhttp.status == 200) 
        {
		    onDataLoad(xmlhttp.responseText);
		    //onDataLoad(xmlhttp.responseXML);
	    }
	}
};
// 
// - Value
///////////////////////////////////////////////////////////////////////////
//
// Sends a HTTP request to server and fill the result in provided input field
//
// ValueTextBoxId: client id of textbox in the main window, which contains key value for http request
// DescriptionTextBoxId: client id of textbox in the main window, that will be filled with result value
// SearchUrl: Url of page that should return request in format <result value="[result_string]"/> (this function automatically appends
//   query string parameter "id=[key]" to the url, where "[key]" is value user entered in text box provided in ValueTextBoxId param
//
///////////////////////////////////////////////////////////////////////////
HttpGet.LookupPopupCheckValue = function(ValueTextBoxId, DescriptionTextBoxId, SearchUrl) {
    var val = document.getElementById(ValueTextBoxId).value;
    HttpGet.LookupPopupCheckValue_ByValue(val, DescriptionTextBoxId, SearchUrl);
};
var completed = false;

// Same that previous function but the first parameter "Value" is actual value (not id of text box).
HttpGet.LookupPopupCheckValue_ByValue = function(Value, DescriptionTextBoxId, SearchUrl) {

    var val = Value;
    var qstring = "";
    if (val != "") 
    {
      qstring = (SearchUrl.indexOf("?") != -1) ? "&" : "?";
        qstring += "oznaka=" + val;
      SearchUrl += qstring;
      this.LoadValueFromUrl(SearchUrl, OnDataLoad);
    }
    
    function OnDataLoad(xmlDoc) {
        /*
        alert (xmlDoc);
        var resultNodes = xmlDoc.getElementsByTagName("result");
        alert (resultNodes.length);
        if (resultNodes.length > 0) {
	    var result = resultNodes[0].attributes[0].value;
	    }
        */
        
        //Spremenil sem v delujoce stanje in omittal XML parser, ker ni deloval.
        
        
        var iBeginRes = xmlDoc.indexOf("<result value=");
        iBeginRes += "<result value=".length + 1;
        var iEndRes   = xmlDoc.indexOf(">");
        iEndRes -= 1;
        
        var result = xmlDoc.substring(iBeginRes, iEndRes);
        
	    if (result) 
	    {
	        completed = true;
	        var el = document.getElementById(DescriptionTextBoxId);
                if (el.tagName == "INPUT") el.value = result;
                else el.innerHTML = result;
	    }
    }
};
HttpGet.LookupPopupCheckValue_Double = function(ValueTextBoxId, DescriptionTextBoxId1, DescriptionTextBoxId2, SearchUrl) {
    var qstring = "";
    var val = document.getElementById(ValueTextBoxId).value;
    if (val != "") 
    {
      qstring = (SearchUrl.indexOf("?") != -1) ? "&" : "?";
        qstring += "oznaka=" + val;
      SearchUrl += qstring;
      this.LoadValueFromUrl(SearchUrl, OnDataLoad);
    }
    
    function OnDataLoad(xmlDoc) {
        var iBeginRes = xmlDoc.indexOf("<result value=");
        iBeginRes += "<result value=".length + 1;
        var iEndRes   = xmlDoc.indexOf(">");
        iEndRes -= 1;
        
        var result = xmlDoc.substring(iBeginRes, iEndRes);
	    if (result) 
	    {
	        iBeginRes = 0;
	        iEndRes = result.indexOf("*");
	        FillTextBox(DescriptionTextBoxId1, result.substring(iBeginRes, iEndRes));
	        iBeginRes = iEndRes + 1;
            iEndRes = result.indexOf("*", iBeginRes);
	        FillTextBox(DescriptionTextBoxId2, result.substring(iBeginRes, iEndRes));
	    }
    }
};

function FillTextBox(DescriptionTextBoxId, Value)
{
    var result = Value;
    if (result)
    {
	    completed = true;
	    var el = document.getElementById(DescriptionTextBoxId);
            if (el.tagName == "INPUT") el.value = result;
            else el.innerHTML = result;
    }
}
///////////////////////////////////////////////////////////////////////////
//
// Sets focus on first input control on page
//
// parentElt: parent element where to search for first control in
// Returns: true if element to focus was found, false otherwise.
//
///////////////////////////////////////////////////////////////////////////

function FocusOnFirstControl(parentElt) {
  var chNodes = parentElt.childNodes;
  var i;
  for(i=0; i < chNodes.length; i++)
  {
    if (chNodes[i].tagName && chNodes[i].tagName.toLowerCase() == "input" && chNodes[i].type != "hidden") {
        chNodes[i].focus();
        return true;
    }
    if (FocusOnFirstControl(chNodes[i])) return true;
  }
  return false;
}

