///////////////////////////////////////////////////////////////////////////
//
// 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");
}

// IE fix getElementsByName
if (CheckIE())
{
  getElementsByName_ie_fix()
}

// IE functiom fix
function getElementsByName_ie_fix()
{
  document.getElementsByName = function (name, tag)
  {
    if (!tag)
    {
      tag = '*';
    }
    var elems = document.getElementsByTagName(tag);
    var res = []
    for (var i = 0; i < elems.length; i++)
    {
      att = elems[i].getAttribute('name');
      if (att == name)
      {
        res.push(elems[i]);
      }
    }
    return res;
  }
}

// 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
    if (CheckIE()) // only if IE **by Iv
    {
      var re = new RegExp(attributeName + "=\"([^\"]*)\"", "i");
      var matches = elt.outerHTML.match(re);
      if (matches) {
        return (matches[1])
      } else return null;
    }
    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) {
      if (document.getElementById(btnName).click != null ) 
        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();
    }
  }
}

// Tale funkcija bi morala biti v WebResources.axd
// ki pa ga nas aspnet ne zgenerira. Tole je njen zacasni 
// fake. Glej bug 9690
function WebForm_AutoFocus(elId) 
{
  document.getElementById(elId).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";
  }
}

/// Function meant for eVAT/Acct portal
/// Toogles visible/invisible style of provided element.
/// name: id of element to toogle visibility
function SwapVisibleVAT(name)
{
  elt = document.getElementById(name);
  SwapVisibleByElementVAT(elt);
}

/// Function meant for eVAT/Acct portal
/// Toogles visible/invisible style of provided element. 
/// elt: reference to element to toogle visibility
function SwapVisibleByElementVAT(elt)
{
  if (elt.style.display == "none")
  {
    elt.style.display = "";
  }
  else
  {
    elt.style.display = "none";
  }
}

/// Set readonly state of all child elements  to tf
/// use: 
///   setAllChildInputsReadOnly(row, true);
///   setAllChildInputsReadOnly(document, true); // all elements
function setAllChildInputsReadOnly(parent, tf)
{
  var elems = parent.getElementsByTagName('input');
  for (var i = 0; i < elems.length; i++)
  {
    elems[i].readOnly = tf;
    if (tf == true)
      elems[i].className = 'label';
  }
}


/// Returns element with provided id that is a descender of provided element.
function GetElementById(parentElt, id)
{
  var chNodes = parentElt.childNodes;
  if (chNodes == null) return null;

  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) 
{
  if (list == null) return;
  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 <= this.templateRowIndex + this.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(this.templateRowsCount);
    for(var i = 0; i < this.templateRowsCount; i++)
    {
      // Clone row
      var originalRow = this.dynamicTable.rows[this.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 (this.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 < this.templateRowsCount; i++) {
      this.dynamicTable.deleteRow(rowIndex);
    } 
    this.InitTable();
    this.UpdateRowIndex();
  }
  
  function UpdateRowIndex()
  {
    if (this.hasRowEnumeration) {
      rows = this.dynamicTable.rows;
      for (var i = this.templateRowIndex; i < rows.length; i = i + this.templateRowsCount) 
      {
        var el = GetElementById(rows[i], "rowIndex");
        if (el != null) 
        {
          el.innerHTML = (i - this.templateRowIndex) / this.templateRowsCount;
        }
        // za rowindex v drugem TR; glej Doh_Prem_1.ascx
        var j = i + 1;
        if (this.templateRowsCount > 1 && rows.length > j) 
        {
          
          var el1 = GetElementById(rows[j], "rowIndex1");
          if (el1 != null) {
            el1.innerHTML = (i - this.templateRowIndex) / this.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
// - CurrencyBoxSetDecimals: fill trailing zeroes
//
///////////////////////////////////////////////////////////////////////////
var CurrencyBox = {};
var decCh = ',';
function DecimalChar()
{
  return decCh;  
}
function GroupChar()
{
  return (decCh == '.')? ',':'.';
}

CurrencyBox.MaxLen = function(self)
{
  return GetTagAttribute(self,"maxLength")!=null ? GetTagAttribute(self,"maxLength"):15;
}
CurrencyBox.Decimals = function(self)
{
  return GetTagAttribute(self,"CurrencyBoxDecimals")!=null ? GetTagAttribute(self,"CurrencyBoxDecimals"):2;
}
CurrencyBox.SetDecimals = function(self)
{
  return GetTagAttribute(self,"CurrencyBoxSetDecimals")!=null ? GetTagAttribute(self,"CurrencyBoxSetDecimals"):true;
}
CurrencyBox.NonNegative = function(self)
{
  return GetTagAttribute(self,"CurrencyBoxNonNegative")!=null ? GetTagAttribute(self,"CurrencyBoxNonNegative"):false;
}


// 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(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 + 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 = 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)==GroupChar())) {
    if ((pointPos == 3) || ((pointPos > 3) && (inp.charAt(pointPos-4)==GroupChar()))) {
       out += 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 + 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.
// Mozilla functionallity added *iv
CurrencyBox.OnKeyPress = function(self, e) 
{
    k = keyPressed(e);
    if (k==0) return true;  
    
    inp = self.value;
    
    // Allows only numerals and punctuations
    if (k==44 || k==46) { // comma pressed
      if (inp.indexOf(DecimalChar()) == -1 && CurrencyBox.Decimals(self) > 0) {
        return true;
      } else {
        return false;
      }
    } else if ((k>=48) && (k<=57)) { // digit pressed
        return true;
    } else if (k==45 && CurrencyBox.NonNegative(self) != "True") { // minus pressed
        return true;
    }
    else if (k == 13) {
      return true;
    } else {
      return false;
    }
    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, CurrencyBox.Decimals(self), CurrencyBox.NonNegative(self)=="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) 
{
  self.value = formatNumber(self.value, CurrencyBox.MaxLen(self), CurrencyBox.NonNegative(self), CurrencyBox.Decimals(self),  GroupChar(), DecimalChar(), CurrencyBox.SetDecimals(self)) 
}

///////////////////////////////////////////////////////////////////////////
//
// Percentage Box
//
// Handles entering percentage values with real-time decimal point formatting (eg. 23,50)
//
// Example:
// <input type="text" PercentageBoxIntegers="2" PercentageBoxDecimals="2" PercentageBoxNonNegative="True" style="text-align: right" onkeypress="return PercentageBox.OnKeyPress(this, event)" onkeyup="PercentageBox.OnKeyUp(this, event)" onblur="PercentageBox.OnBlur(this, event)">
//
// HTML parameters:
// - PercentageBoxIntegers: number of integer part digits
// - PercentageBoxDecimals: number of decimal part digits
// - PercentageBoxNonNegative: true to allow only non-negative numbers
// - PercentageBoxSetDecimals: fill trailing zeroes
//
///////////////////////////////////////////////////////////////////////////
var PercentageBox = {};

setDecimals = false; // default value

// Formats provided string to percentage number.
// inp: input string
// maxIntegers: maximum number of integer places
// maxDecimals: maximum number of decimal places
// RETURNS: Formated string
PercentageBox.FormatPercentage = function(inp, maxIntegers, maxDecimals) {
  out='';

  if (maxIntegers==null) maxIntegers = 2; // Default is 2 integers
  if (maxDecimals==null) maxDecimals = 2; // Default is 2 decimals

  pointPos = inp.indexOf(DecimalChar());
  if (pointPos == -1) {
    pointPos = inp.length-1;
    point=false;
  } else {
    if (pointPos == 0) out = '0';
    pointPos--;
    if (maxDecimals > 0) out = out + DecimalChar();
    point=true;
  }

  // Parse numbers left from the decimal point
  integers=0;
  for (var i=pointPos; i>=0; i--) {
    znak=inp.charAt(i);
    if (integers >= maxIntegers) break;
    integers++;
    out = znak + out;
  }

  // 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 + DecimalChar();
    }
    while (decimals < maxDecimals) {
      out = out + '0';
      decimals++;
    }
  }
    
  return(out);
}

///*** PercentageBox  ***
// Checks whether user pressed valid key based on percentage formatting.
// Mozilla functionallity added *iv
PercentageBox.OnKeyPress = function(self, e) 
{
    k = keyPressed(e);
    if (k==0) return true;  
    
    inp = self.value;
    
    // Allows only numerals and punctuations
    if (k==44) { // comma pressed
      if (inp.indexOf(DecimalChar()) == -1 && GetTagAttribute(self, "PercentageBoxDecimals") > 0) {
        return true;
      } else {
        return false;
      }
    } else if ((k>=48) && (k<=57)) { // digit pressed
      if (inp.indexOf(DecimalChar()) == -1 && GetTagAttribute(self, "PercentageBoxIntegers") == inp.length) {
        return false;
      } else {
        return true;
      }
    }
    else if (k == 13) {
      return true;
    } else {
      return false;
    }
    return true; 
}

// *** PercentageBox ***
// Execute real-time percentage formatting.
PercentageBox.OnKeyUp = function(self, e) {
  if (CheckIE()) {
    // Get old cursor position
    rightPos = self.value.length + document.selection.createRange().move('character', -0x7FFFFFFF);

    // Format percentage number
    newVal = PercentageBox.FormatPercentage(self.value, GetTagAttribute(self,"PercentageBoxIntegers"), GetTagAttribute(self,"PercentageBoxDecimals")); 
    self.value = newVal;

    // Position the cursor
    rng = self.createTextRange();
    rng.move('character', newVal.length-rightPos);
    rng.select();
  }
  else 
  {
    var iIntegers = GetTagAttribute(self,"PercentageBoxIntegers");
    var iDecimals = GetTagAttribute(self,"PercentageBoxDecimals");
    self.value = formatNumberCurrency(self.value, iIntegers, iDecimals, DecimalChar()) 
  }
}

// *** PercentageBox ***
// Formats percentage box on textbox blur event
PercentageBox.OnBlur = function(self, e) 
{
  var iIntegers = GetTagAttribute(self,"PercentageBoxIntegers");
  var iDecimals = GetTagAttribute(self,"PercentageBoxDecimals");
  self.value = formatNumberCurrency(self.value, iIntegers, iDecimals, DecimalChar()) 
}

/**********************************************iv*
Formats currency number and fills 
zeroes at decimal places. 
PARAMETERS: 
  strValue - input string
  intLen - number of integer digits
  decLen - number of decimal digits
  decChar - decimal char  (.,)
RETURNS: formated string
USAGE:    self.value = formatNumber(self.value, iIntegers, iDecimals, DecimalChar) 
*************************************************/
function formatNumberCurrency( strValue, intLen, decLen, decChar) 
{
 if (strValue != "")
 {
   strValue = leftTrim(strValue);
   decIx = strValue.indexOf(decChar);
   if (decIx==0)
   {
      strValue="0"+strValue;
      decIx = strValue.indexOf(decChar);
   }

   var point = decChar;
   if (decIx<0) point = "";
   if (decIx<0) decIx = strValue.length;
   var wholepart = strValue.substring(0,decIx);
   
   if (wholepart.length > intLen) wholepart = wholepart.substring(0, intLen-1);
   if (decLen > 0)
   {
     var decimalpart = strValue.substring(decIx+1, strValue.length);
     if (decimalpart.length > 0)
       strValue = wholepart + decChar + decimalpart.substring(0,decLen);
     else
       strValue = wholepart + point;

   }
   else
   {
     strValue = wholepart;
   }
 }
 return strValue;
}

/*****************************************iv*
Returns keycode pressed (Crossbrowser) 
in mozilla it returns 0 for:
  arrows, del, backsp, ctrl-c-v
Use this to pass this special characters for 
Crossbrowser OnKeyPress-like functions
USAGE:
    k = keyPressed(e);
    if (k==0) return true;  
********************************************/
function keyPressed(e)
{
	var code;
	if (!e) var e = window.event;
	if (e.keyCode) code = e.keyCode;
	else if (e.which) code = e.which;
//	var character = String.fromCharCode(code);
//	alert(code + ':' + character);
	
  if (!window.event) // not IE
  {
    if (code>33 && code<41 ||  code==8 || code==9 || code==46 ) //pgupd home end arrows, del, tab, backsp 
      return 0;
    if (e.ctrlKey && (code==99 || code==118) )  // ctrl-c-v
      return 0;
  }
	return code;
}

/**********************************************iv*
Formats number with group chars and fills 
zeroes at decimal places. 
PARAMETERS: 
  strValue - input string
  maxlen - formated number max length (incl. '.' and ',')
  nonNegative - true to allow only non-negative numbers
  decLen - number of decimal digits
  groupChar - 1000 group char (,.)
  decChar - decimal char  (.,)
  fill0: auto fill trailing zeroes
RETURNS: formated string
USAGE:    self.value = formatNumber(self.value, maxlen, nonNegative, iDecimals,  GroupChar, DecimalChar, setDec) 
*************************************************/
function formatNumber( strValue, maxlen, nonNegative, decLen, groupChar, decChar, fill0) 
{
 if (strValue != "")
 {
   strValue = leftTrim(strValue);

   if (nonNegative.toLowerCase()=="false" && strValue.indexOf("-")==0)
     strValue = '-' + removeCharacters(strValue,'[^0-9,.]');
   else
     strValue = removeCharacters(strValue,'[^0-9,.]');

 
   strValue = removeGroupChars(strValue,groupChar);
   maxnumlen = maxlen - (maxlen / 4 )+1;
   
   decIx = strValue.indexOf(decChar);
   if (decIx<0) decIx = strValue.length;
   var wholepart = strValue.substring(0,decIx);
   
   if (wholepart.length > maxnumlen) wholepart = wholepart.substring(0, maxnumlen);

   wholepart = addGroupChars(wholepart,groupChar);
   
   if (decLen > 0)
   {
     var decimalpart = strValue.substring(decIx+1, strValue.length);
     if (fill0) decimalpart += "0000000000";
     if (decimalpart.length > 0)
       strValue = wholepart + decChar + decimalpart.substring(0,decLen);
     else
       strValue = wholepart;
   }
   else
   {
     strValue = wholepart;
   }
 }
 return strValue;
}

/**********************************************iv*
Removes Group Chars from numeric string.
PARAMETERS: 
  strValue - input string
  ch - group char  (.,)
RETURNS: formated string 
USAGE: strValue = removeGroupChars(strValue,groupChar);
*************************************************/
function removeGroupChars( strValue, ch ) 
{
  var pattern = "\\"+ch;
  var objRegExp = new RegExp(pattern,"g"); 
  return strValue.replace(objRegExp,'');
}

/**********************************************iv*
Inserts Group Chars into numeric string.
PARAMETERS: 
  strValue - input string
  ch - group char  (.,)
RETURNS: formated string
USAGE: strValue = addGroupChars(strValue,groupChar);
*************************************************/
function addGroupChars( strValue, groupChar ) {
  var objRegExp  = new RegExp('(-?[0-9]+)([0-9]{3})'); 
  while(objRegExp.test(strValue)) 
  { //replace original string with first group match, a comma, then second group match
    strValue = strValue.replace(objRegExp, '$1'+groupChar+'$2');
  }
  return strValue;
}

/**********************************************iv*
Removes characters from a source string
  based upon matches of the supplied pattern.
PARAMETERS: 
  strValue - source string containing number.
  strMatchPattern - matching pattern to remove
RETURNS: String modified with characters
  matching search pattern removed
USAGE:  strValue = removeCharacters(strValue,'[^0-9,.]');
*************************************************/
function removeCharacters( strValue, strMatchPattern ) 
{
var objRegExp =  new RegExp( strMatchPattern, 'gi' );
  return strValue.replace(objRegExp,'');
}

/*********************************************iv*
Trims leading whitespace chars.
PARAMETERS:
   strValue - String to be trimmed
RETURNS:
   Source string with left whitespaces removed.
*************************************************/
function leftTrim( strValue ) {
var objRegExp = /^(\s*)(\b[\w\W]*)$/;

  if(objRegExp.test(strValue)) 
  {
    strValue = strValue.replace(objRegExp, '$2');
  }
  return strValue;
}

///////////////////////////////////////////////////////////////////////////
//
// 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 = {};

// Mozilla functionallity added *iv
NumberBox.OnKeyPress = function(self, e) 
{
  k = keyPressed(e);
  if (k==0) return true;  

  if ((k>=48) && (k<=57)) {
      // 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;
  }
}

NumberBox.OnBlur = function(self, e) 
{
  if (GetTagAttribute(self,"NoCheck") == null) 
  {
    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)" onblur="DateBox.OnBlur(this, event)" >
//
// HTML parameters:
// - DateSeparator: separator character
//
///////////////////////////////////////////////////////////////////////////
var DateBox = {};

var DateBoxProperties = {
  Separator: '.'
};

///*** DateBox  ***
// Checks whether user pressed valid key
// Mozilla functionallity added *iv
DateBox.OnKeyPress = function(self, e) 
{
  k = keyPressed(e);
  if (k==0) return true;  
  inp = self.value;

  // Allows only numerals and punctuations
  if (k == DateBoxProperties.Separator.charCodeAt(0)) { // comma pressed
    return true;
  } else if ((k>=48) && (k<=57)) { // digit pressed
    return true;
  }
  else if (k == 13) {
    return true;
  } else {
    return false;
  }
}

// *** DateBox ***
// Execute real-time date formatting.
// Mozilla functionallity added *iv
DateBox.OnKeyUp = function(self, e) 
{
  k = keyPressed(e);
  if (k==0) return true;  
    
  if (k!=8 && k!=46) 
  { // if anything but del or BS pressed
    // Get old cursor position
    if (document.selection != null)
      rightPos = self.value.length + document.selection.createRange().move('character', -0x7FFFFFFF);

    if ((k>=48 && k<=57) || (k>=96 && k<=110)) //is number or number on numeric keyb.
    {
      // Format date
      re = /(^\d{2}$)|(^\d{1,2}\.\d{2}$)/;
      if (re.test(self.value)) self.value += ".";
      // Remove duplicated commas
      while (self.value.indexOf('..') != -1) self.value = self.value.replace('..','.');
    }
  }
}

// *** DateBox ***
// Execute real-time date formatting.
// added *iv
// decision whether to check date or not, not made yet
DateBox.OnBlur = function(self, e) 
{
  if (validateSIDate(self.value)== false && self.value !="")
  {
//    self.style.background = "#FF919E"; 
    self.style.borderBottom = "1px dotted red";
  }
  else
  {
//    self.style.background = "#ffffff"; 
    self.style.borderBottom = "";
  }
}

function validateSIDate( strValue ) {
/************************************************
DESCRIPTION: Validates that a string contains only 
    valid dates with 2 digit month, 2 digit day, 
    4 digit year. Date separator can be ., -, or /.
    Uses combination of regular expressions and 
    string parsing to validate date.
    Ex.  dd.mm.yyyy
PARAMETERS:
   strValue - String to be tested for validity
RETURNS:
   True if valid, otherwise false.
REMARKS:
   Avoids some of the limitations of the Date.parse()
   method such as the date separator character.
*************************************************/
  var objRegExp = /^\d{1,2}(\-|\/|\.)\d{1,2}\1\d{4}$/
 
  //check to see if in correct format
  if(!objRegExp.test(strValue))
    return false; //doesn't match pattern, bad date
  else
  {
    var arrayDate = strValue.split(RegExp.$1); //split date into month, day, year
	  var intDay = parseInt(arrayDate[0],10); 
	  var intYear = parseInt(arrayDate[2],10);
    var intMonth = parseInt(arrayDate[1],10);
	
	  //check for valid month
	  if(intMonth > 12 || intMonth < 1) 
	  {
		  return false;
	  }
	
    //create a lookup for months not equal to Feb.
    var arrayLookup = { '01' : 31,'03' : 31, '04' : 30,'05' : 31,'06' : 30,'07' : 31, '08' : 31,'09' : 30,'10' : 31,'11' : 30,'12' : 31
    }
  
    if (arrayDate[1].length == 1) arrayDate[1] = "0"+arrayDate[1];
    //check if month value and day value agree
    if(arrayLookup[arrayDate[1]] != null) 
    {
      if(intDay <= arrayLookup[arrayDate[1]] && intDay != 0)
        return true; //found in lookup table, good date
    }
		
    //check for February
  	var booLeapYear = (intYear % 4 == 0 && (intYear % 100 != 0 || intYear % 400 == 0));
    if( ((booLeapYear && intDay <= 29) || (!booLeapYear && intDay <=28)) && intDay !=0)
      return true; //Feb. had valid number of days
  }
  return false; //any other values, bad date
}


///////////////////////////////////////////////////////////////////////////
//
// 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="Brii 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="Brii 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";
  }
}

///////////////////////////////////////////////////////////////////////////
//
// Removes all occurences of char from string
//
///////////////////////////////////////////////////////////////////////////
function removeAllChars( strValue, ch ) {
  var objRegExp = new RegExp("/"+ch+"/g"); 
  return strValue.replace(objRegExp,'');
}

///////////////////////////////////////////////////////////////////////////
//
// Dropdown List Edit 
//
// Handles select from list or edit input value
//
// Example:
//    <select id="list11" name="list11" item0=""  ItemMaxlength="16" ItemEdit="true" NumOnly='true' onkeypress=DdListEdit.OnKeyPress(this,event); onkeydown=DdListEdit.OnKeyDown(this,event); onblur=DdListEdit.OnBlur(this);  language="javascript" id="Select1" style="width: 88%;">
//       <option value=-1>Izberi ali vpii..</option>
// Params: edit="true" ( or false - noneditable)
//
///////////////////////////////////////////////////////////////////////////
var DdListEdit = {};

DdListEdit.OnKeyDown = function(self, e) 
{
    if (self.item0 == null)
    {
      self.item0 = '';
    }
    // Delete Key resets previous search keys
    var key = anyKeyPressed(e);
    KeyDown = key;

    if(key == 46)
        clr(self);
    if(key == 8)
    {
 //     elKeys = document.getElementById("keys");
      if (self.item0.length > 0) 
      {
        self.item0 = self.item0.substring(0,self.item0.length-1);
        self.options[0].text  = self.item0;
      }
      if (typeof window.event != 'undefined') event.keyCode = 0; //disable Back in IE
    }
}

DdListEdit.OnKeyPress = function(self, e) 
{
    if (self.item0 == null)
    {
      self.item0 = '';
    }
    
    var fEdit = GetTagAttribute(self, "ItemEdit")=='true'? true:false;
    var fNumOnly = GetTagAttribute(self, "NumOnly")=='true'? true:false;
   
    var pre = self.item0;
    var key = anyKeyPressed(e);

    
    var kchar = String.fromCharCode(key);

    if (KeyDown == 45 || KeyDown == 46) //disable Insert and Del in FF
      return;
    // if not 0..9 or ,.- or a..z or A..Z or 蚞
    if (!((key >=44 && key <=46) || (key >=48 && key <=57) 
          || (!fNumOnly && 
                ((key >=64 && key <=90)  || (key >=97 && key <=125) || key==269 || key==268 || key==263 || key==262 || key==353 || key==352 || key==382 || key==381 || key==273 || key==272))
         ))
      return;
        
    var re = new RegExp("^" + pre + kchar, "i"); // "i" -> ignoreCase
    var found=false;
    for(var i=0; i<self.options.length; i++)
    {
        if(re.test(self.options[i].text))
        {
            self.options[i].selected=true;
            self.item0 += kchar;
            
            if (e.preventDefault) e.preventDefault();
            else window.event.returnValue = false;
            found=true;
            break;
        }
    }
    if (!found)
    {
      if (fEdit)
      {
        maxLength = GetTagAttribute(self, "ItemMaxlength");
        if (self.item0.length < maxLength)
        {
          self.item0 += kchar;
          if (self.options[0].value != -2)  
            self.options[0] = new Option(self.item0,-2);
          self.options[0].text  = self.item0;
          self.options[0].selected=true;
        }
        if (e.preventDefault) e.preventDefault();
        else window.event.returnValue = false;
      }
    }
}
DdListEdit.OnBlur = function (self)
{
   if (self.value == -2)
   {
     self.options[0].value = self.item0;
   }
}

/// Selects an option in drop down list that has provided value.
DdListEdit.SelectItem = function (list, value)
{
  if (list == null) return;
  for (i=0; i<list.options.length; i++) 
  {
    if (list.options[i].value == value) 
    {
      list.options[i].selected = true;
      return;
    }
  }
  list.item0=value;
  list.options[0] = new Option(list.item0,list.item0);
  list.options[0].text  = list.item0;
  list.options[0].selected=true;
}

function clr(self)
{
  self.options[0].value = '';
  self.options[0].text = '';
  self.item0 = '';
  self.options[0].selected=true;
}


/// end Dropdown List Edit ////////////////////////////////////////////////////// 

///////////////////////////////////////////////////////////////////////////
//
// event support function (used in Dropdown List Edit )
//
///////////////////////////////////////////////////////////////////////////


function anyKeyPressed(e)
{
  var code;
  if (!e) var e = window.event;
  if (e.keyCode)
  {
    code = e.keyCode ? e.keyCode : e.charCode;
  }
  else 
  {
    if (e.which) code = e.which;
  }
  return code;
}

if (typeof window.event != 'undefined')//ie
	document.onkeydown = function()
	{
		if (event.srcElement.tagName.toUpperCase() == 'SELECT')
			return (event.keyCode != 8);
	}
else
	document.onkeypress = function(e)// moz disable BACK in select
	{
		if (e.target.nodeName.toUpperCase() == 'SELECT')
			return (e.keyCode != 8);
	}
	
///////////////////////////////////////////////////////////////////////////
// floating errorpanel support
///////////////////////////////////////////////////////////////////////////
var divPnlErrX ; 
var divPnlErrY ; 
var divPnlErrStarted = 0;
function StartErrFloating()
{
   if (divPnlErrStarted == 1) return;
	 var divPnlErr  = document.getElementById("divPnlErr");
	 if (divPnlErr!=null)
	 {
     divPnlErrX = divPnlErr.style.left;
     divPnlErrY = divPnlErr.style.top;
     divPnlErr.style.position = "absolute";
     divPnlErrStarted = 1;
     document.getElementById("imgFloat").src = "../../Gui/pin_down.gif";
     every10msLoop() ;
   }
}
function StopErrFloating()
{
	 var divPnlErr  = document.getElementById("divPnlErr");
	 if (divPnlErr!=null)
	 {
     divPnlErr.style.left=divPnlErrX;
     divPnlErr.style.top=divPnlErrY;
     divPnlErr.style.position = "relative";
     document.getElementById("imgFloat").src = "../../Gui/pin_up.gif";
   }
   divPnlErrStarted = 0;
}
function ToggleErrFloating()
{
   if (divPnlErrStarted == 1) 
     StopErrFloating();
   else
     StartErrFloating();
}

function every10msLoop()
{
   if (divPnlErrStarted == 0) return;
	 var divPnlErr  = document.getElementById("divPnlErr");
	 if (divPnlErr!=null)
	 {
     divPnlErr.style.left=10;
     //get divPnlErr.style.top=window.pageYOffset;
     if( typeof( window.pageYOffset ) == 'number' ) 
       divPnlErr.style.top = window.pageYOffset;
     else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) 
         divPnlErr.style.top = document.body.scrollTop;
       else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) )
           divPnlErr.style.top = document.documentElement.scrollTop;
     
   }
   setTimeout("every10msLoop()",100);
}

function InitErrFloating()
{
	 var divPnlErr  = document.getElementById("divPnlErr");
	 if (divPnlErr!=null)
	 {
    divPnlErrX = divPnlErr.style.left;
    divPnlErrY = divPnlErr.style.top;
    divPnlErrStarted = 0;
    divPnlErr.style.position = "relative";
  }
}

setTimeout("InitErrFloating()",200);
///////////////////////////////////////////////////////////////////////////
// endof floating errorpanel support
///////////////////////////////////////////////////////////////////////////


function getAscendingLefts(elem)
{
  if (elem==null)
    return 0;
  else
    return elem.offsetLeft+getAscendingLefts(elem.offsetParent);
}

function getAscendingTops(elem)
{
  if (elem==null)
    return 0;
  else
    return elem.offsetTop+getAscendingTops(elem.offsetParent);
}


///////////////////////////////////////////////////////////////////////////
// JQUERY
// helpWindow 
// datepicker
///////////////////////////////////////////////////////////////////////////
var oldel;
function helpWindow(el, text)
{
   if ($("#jqHelpWin").dialog( 'isOpen' ))
   {
    $("#jqHelpWin").dialog('close');  
    if (el != oldel)
      openHelpWindow(el, text);
    else
      oldel = "";
  }
  else
  {
    openHelpWindow(el, text);
  }
  return false;
}

function openHelpWindow(el, text)
{
    var x = getAscendingLefts(el) + el.offsetWidth; //el.offsetLeft;
    var y = getAscendingTops(el); //el.offsetTop;
    $("#jqHelpWin").dialog('open');
    $("#jqHelpWin").dialog('option', 'position', [x+30, y-16]);      
    $("#jqHelpWin").text(text);
    oldel = el;
}

// check if jQuery.js is included to page
if (typeof jQuery != 'undefined') 
{
  // sort of body-onload function
  // all elements and initialisation should be created here
  $(document).ready(function()
  {
   //create dialog div element
    if (decCh == ',')
      $("body").prepend('<div id="jqHelpWin" style="display: none;" title="Pomoč"></div>');
    else
      $("body").prepend('<div id="jqHelpWin" style="display: none;" title="Help"></div>');
    
    // dialog constructor
    $("#jqHelpWin").dialog(
    {
      bgiframe: true,
      autoOpen: false,
      // hide: true,
      show: true
    });
    
    // create datepicker
    $(".jqDate").datepicker();

    // set size of elements date, helpwin    
    $("div.ui-datepicker").css("font-size","77%");
    $("div.ui-dialog").css("font-size","77%");
    
  });

// datepicker Localization
  (function($) {
    if (decCh == ',')
    {
      $.datepicker.setDefaults({
        clearText: 'Izbri&#x161;i', clearStatus: 'Izbri&#x161;i trenutni datum',
        closeText: 'Zapri', closeStatus: 'Zapri brez spreminjanja',
        prevText: '&lt;Prej&#x161;nji', prevStatus: 'Prika&#x17E;i prej&#x161;nji mesec',
        prevBigText: '&#x3c;&#x3c;', prevBigStatus: '',
        nextText: 'Naslednji&gt;', nextStatus: 'Prika&#x17E;i naslednji mesec',
        nextBigText: '&#x3e;&#x3e;', nextBigStatus: '',
        currentText: 'Trenutni', currentStatus: 'Prika&#x17E;i trenutni mesec',
        monthNames: ['Januar','Februar','Marec','April','Maj','Junij',
        'Julij','Avgust','September','Oktober','November','December'],
        monthNamesShort: ['Jan','Feb','Mar','Apr','Maj','Jun',
        'Jul','Avg','Sep','Okt','Nov','Dec'],
        monthStatus: 'Prika&#x17E;i drug mesec', yearStatus: 'Prika&#x17E;i drugo leto',
        weekHeader: 'Teden', weekStatus: 'Teden v letu',
        dayNames: ['Nedelja','Ponedeljek','Torek','Sreda','&#x10C;etrtek','Petek','Sobota'],
        dayNamesShort: ['Ned','Pon','Tor','Sre','&#x10C;et','Pet','Sob'],
        dayNamesMin: ['Ne','Po','To','Sr','&#x10C;e','Pe','So'],
        dayStatus: 'Nastavi DD za prvi dan v tednu', dateStatus: 'Izberi DD, d MM yy',
        dateFormat: 'dd.mm.yy', firstDay: 1,
        initStatus: 'Izbira datuma', isRTL: false,
        showMonthAfterYear: false, yearSuffix: ''
      }); 
    }
    else
    {
      $.datepicker.setDefaults({
        clearText: 'Clear', clearStatus: 'Erase the current date',
        closeText: 'Done', closeStatus: 'Close without change',
        prevText: 'Prev', prevStatus: 'Show the previous month',
        prevBigText: '&#x3c;&#x3c;', prevBigStatus: 'Show the previous year',
        nextText: 'Next', nextStatus: 'Show the next month',
        nextBigText: '&#x3e;&#x3e;', nextBigStatus: 'Show the next year',
        currentText: 'Today', currentStatus: 'Show the current month',
        monthNames: ['January','February','March','April','May','June',
        'July','August','September','October','November','December'],
        monthNamesShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        monthStatus: 'Show a different month', yearStatus: 'Show a different year',
        weekHeader: 'Wk', weekStatus: 'Week of the year',
        dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
        dayNamesShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
        dayNamesMin: ['Su','Mo','Tu','We','Th','Fr','Sa'],
        dayStatus: 'Set DD as first week day', dateStatus: 'Select DD, M d',
        dateFormat: 'dd/mm/yy', firstDay: 1,
        initStatus: 'Select a date', isRTL: false,
        showMonthAfterYear: false, yearSuffix: ''
      }); 
    }
  
  })(jQuery);
}


///////////////////////////////////////////////////////////////////////////
// end jQuery support
///////////////////////////////////////////////////////////////////////////


