/******************************************************************************\

  IS

  @File:              intershift.js

  @Version:           1.00

  @Description:       This file defines the class 'IS' with all static functions.

  @Static Functions:  - Init()
                        Adds initialization to window onload event
                      - HandleInit()
                        Does the work on initializing all special elements on
                        the page
                      - GetWindowWidth()
                        Returns the width of the window
                      - GetWindow Height()
                        Returns the height of the window
                      - AddEvent()
                        Attaches an function to an event of a given object
                      - SetCenter()
                        Displays given object in center of the screen
                      - ReturnPos()
                        Returns an array with the position of given object
                      - ReturnDimension()
                        Returns an array with the dimensions of given object
                      - HasClass()
                        Returns the classname of given object, or false if not 
                        found
                      - MNW()
                        Creates a new window
                      - MakeNewWindow()
                        Creates a new window
                      - GetEl()
                        Short function for getting document.getElementById()
                      - GetArrayElements()
                        Returns an array with all specified elements
                      - ChangeHeight()
                        Changes the height of given element at a certain speed
                      - GetUniqueId()
                        Generates a unique ID on the page
                      - Stripe()
                        Stripes the given element
                      - Highlight()
                        Highlight rows on tables on mouseover
                      - GetParent()
                        Gets the first parent that matches the given tag name
                      - Sortable()
                        Handles initialization for sorting a given table
                      - GetInnerText()
                        Gets the text in an element
                      - ResortTable()
                        Executes a resort of the table
                      - SortDate()
                        Sorts two values on date
                      - SortCurrency()
                        Sorts two values on currency
                      - SortNumeric()
                        Sorts two values on numeric values
                      - SortCaseInsensitive()
                        Sorts two values alfabetic
                      - SortDefault()
                        Sorts two values by comparison
                      - DaysPerMonth()
                        Gets days in a given month
                      - IsLeapYear()
                        Checks if given year is a leap year
                      - Navbox()
                        Generates HTML for a Navigation box
                      - PanelSet()
                        Generates HTML for a Panel set
                      - HighlightButton()
                        Highlights a button on a Panel set
                      - ShowPanel()
                        Shows a panel of a panel set
                      - ShowPrev()
                        Shows previous panel in a panel set
                      - ShowNext()
                        Shows next panel in a panel set
                      - FormValidation()
                        Initializes form validation on a form
                      - HandleForm()
                        Handles submission of a form with form validation
                      - AddError()
                        Adds an error to the forms error object
                      - FormValidate()
                        Validates a given field with validation set
                      - CheckDate()
                        Checks if a date is a valid date

  @Examples:          To create a navbox:
                      
                      <v:navbox v:title="Navbox title" v:width="200px">
                        Text inside the navbox
                      </v:navbox>

                      
                      To create a panelset:

                      <v:panelset v:buttons="true">
                        <v:panel>
                          HTML in panel one
                        </v:panel>
                        <v:panel>
                          HTML in panel two
                        </v:panel>
                        <v:panel>
                          HTML in panel three
                        </v:panel>
                      </v:panelset>


                      Using form validation:

                      <form v:validation="true">
                        <input type="text" v:vals="req">
                        <input type="submit">
                      </form>


  @Author:            Tom Erwich

  @Company:           InterShift v.o.f.

  @Date:              21-11-2006

\******************************************************************************/
if(!document.getElementById)
  document.getElementById = function() { return null; };


function IS() {}

IS.version              = "1.000";
IS.nw                   = false;
IS.defaultWindowWidth   = 500;
IS.defaultWindowHeight  = 400;
IS.growSpeed            = 4;
IS.t_                   = false;
IS.uID                  = 0;
IS.stripeEvenColor      = "#ffeebb";
IS.stripeOddColor       = "#fff";
IS.highlightColor       = "#ffa526";
IS.navboxWidth          = "200px";
IS.panelWidth           = "300px";
IS.panelNext            = "Volgende";
IS.panelPrevious        = "Vorige";
IS.panelLast            = "Opslaan";
IS.panelLastLink        = "";
IS.panelLastType        = "button";
IS.panelButtons         = false;
IS.formErrorBefore      = "De volgende punten zijn niet juist";
IS.formErrorAfter       = "Het formulier is niet opgestuurd.";
IS.firstErrorField      = false;
IS.formErrorBackColor   = "blue";
IS.formErrorBorderColor = "black";
IS.SORT_COLUMN_INDEX;


/******************************************************************************\

  Init()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.Init   = function() {
  this.AddEvent(window,"load",this.HandleInit);
}

  
/******************************************************************************\

  HandleInit()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.HandleInit = function() {
  var fnc;
  var els;
  if(!document.getElementsByTagName) return;
  fnc       = [
    Array("stripe","IS.Stripe(thisFld,attrVal)",Array("table","ul","ol")),
    Array("fstripe","IS.tripe(thisFld,attrVal,true)",Array("table","ul","ol")),
    Array("sortable","IS.Sortable(thisFld)",Array("table")),
    Array("highlight","IS.Highlight(thisFld,attrVal)",Array("table")),
    Array("validation","IS.FormValidation(thisFld,attrVal)",Array("form"))
  ];
  for(var x=0;x<fnc.length;x++) {
    var flds  = IS.GetArrayElements(fnc[x][2]);
    for(var y=0;y<flds.length;y++) {
      thisFld = flds[y];
      if(thisFld.getAttributeNode("v:"+ fnc[x][0])) {
        attrVal = thisFld.getAttribute("v:"+ fnc[x][0]);
        eval(fnc[x][1]);
      }
    }
  }

  els   = [
    Array("navbox","IS.Navbox(thisFld)",Array("navbox","v:navbox")),
    Array("panelset","IS.PanelSet(thisFld)",Array("panelset","v:panelset"))
  ];

  for(x=0;x<els.length;x++) {
    var flds  = IS.GetArrayElements(els[x][2]);
    for(y=0;y<flds.length;y++) {
      thisFld = flds[y];
      eval(els[x][1]);
    }
  }
}


/******************************************************************************\

  GetWindowWidth

  @Type:        Static Function
  @Use:         Returns the window width
  @Parameters:  None
  @Returns:     int:      Width of window

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.GetWindowWidth = function() {
  var windowWidth=0;
  if (typeof(window.innerWidth)=='number') {
    windowWidth=window.innerWidth;
  } else {
    if (document.documentElement&&
      document.documentElement.clientWidth) {
        windowWidth=document.documentElement.clientWidth;
    } else {
      if (document.body&&document.body.clientWidth) {
        windowWidth=document.body.clientWidth;
      }
    }
  }
  return windowWidth;
}


/******************************************************************************\

  GetWindowHeight

  @Type:        Static Function
  @Use:         Returns the window height
  @Parameters:  None
  @Returns:     int:      Height of window

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.GetWindowHeight  = function() {
  var windowHeight=0;
  if (typeof(window.innerHeight)=='number') {
    windowHeight=window.innerHeight;
  } else {
    if (document.documentElement&&
      document.documentElement.clientHeight) {
        windowHeight=
          document.documentElement.clientHeight;
    } else {
      if (document.body&&document.body.clientHeight) {
        windowHeight=document.body.clientHeight;
      }
    }
  }
  return windowHeight;
}


/******************************************************************************\

  AddEvent

  @Type:        Static Function
  @Use:         Adds an event to a given object with a certain
  @Parameters:  - obj:      Object to attach event to
                - evType:   Type of event ('load','click',etc.)
                - fn:       Function to execute when event is triggered
  @Returns:     boolean:    true if succeeded, false if not

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.AddEvent = function(obj, evType, fn) {
	if(obj.addEventListener){
		obj.addEventListener(evType, fn, false); 
		return true;
	} else if (obj.attachEvent){
		var r = obj.attachEvent('on'+evType, fn);
		return r;
	} else {
		return false;
	}
}


/******************************************************************************\

  SetCenter

  @Type:        Static Function
  @Use:         Sets a given element in center of the screen
  @Parameters:  - ElementId[String]:    ID of Element to center
  @Returns:     Nothing

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.SetCenter = function(ElementId) {
  var is  = document.getElementById(ElementId);

  if(is) {
    var wHeight         = this.GetWindowHeight();
    var wWidth          = this.GetWindowWidth();
    if (wHeight>0 && wWidth>0) {
      var isPos         = this.ReturnDimension(is);
      is.style.position = 'absolute';
      is.style.top      = (wHeight/2 - (isPos[1]/2)) + 'px';
      is.style.left     = (wWidth/2 - (isPos[0]/2)) + 'px';
    }
  }
}


/******************************************************************************\

  ReturnPos

  @Type:        Static Function
  @Use:         Gives the exact position on the screen for a given Object
  @Parameters:  - obj[Object]:    Object
  @Returns:     Array(int left,int top)

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.GetPos = function(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft;
		curtop  = obj.offsetTop;
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft;
			curtop  += obj.offsetTop;
		}
	}
	return [curleft,curtop];
}

/******************************************************************************\

  ReturnDimension

  @Type:        Static Function
  @Use:         Gives the dimension of a given object set by style
  @Parameters:  - obj[Object]:    Object
  @Returns:     Array(int width,int height)

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.ReturnDimension = function(obj) {
  width   = 0 + "";
  height  = 0 + "";
  if(obj.style) {
    if(obj.style.width)
      width = obj.style.width;
    if(obj.style.height)
      height = obj.style.height;

    width   = width.replace("px","");
    height  = height.replace("px","");
  }

	return [width,height];
}


/******************************************************************************\

  HasClass

  @Type:        Static Function
  @Use:         Checks if object has a class and returns its name
  @Parameters:  - obj[Object]:    Object
  @Returns:     String name, or false if not found

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.HasClass = function(obj) {
	var result = false;
	if (obj.getAttributeNode("class") != null) {
		result = obj.getAttributeNode("class").value;
	}
	return result;
}


/******************************************************************************\

  MNW

  @Type:        Static Function
  @Use:         Creates a popup window
  @Parameters:  - url[Sring]:   url to load into the new window
                - w[int]:       width of window
                - h[int]:       height of window
  @Returns:     nothing

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.MNW = function(url,w,h) {
	w		= (w == null)?this.defaultWindowWidth:w;
	h		= (h == null)?this.defaultWindowHeight:h;
	var wl	= (this.GetWindowWidth-w)/2;
	var wt	= (this.GetWindowHeight-h)/2;

	if((!this.nw)||(this.nw.closed)) {
		this.nw	= window.open(url,"popup","width="+ w +",height="+ h +",left="+ wl +",top="+ wt +",resizable=yes,toolbar=no,status=no,statusbar=no,menubar=no,copyhistory=no,scrollbars=auto,location=no");
		if(!this.nw.opener) {
			this.nw.opener	= window;
		}
		this.nw.focus();
	} else {
		this.nw.location	= 'about:blank';
		this.nw.location	= url;
		this.nw.resizeTo(w,h);
		this.nw.moveTo(wl,wt);
		this.nw.focus();
	}
}


/******************************************************************************\

  MakeNewWindow

  @Type:        Static Function
  @Use:         Creates a popup window. Alias for IS.MNW
  @Parameters:  - url[Sring]:   url to load into the new window
                - w[int]:       width of window
                - h[int]:       height of window
  @Returns:     nothing

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.MakeNewWindow = function(url,w,h) {
	this.MNW(url,w,h);
}

/******************************************************************************\

  GetEl

  @Type:        Static Function
  @Use:         Returns object width given id
  @Parameters:  - elId[Sring]:  Id of element
  @Returns:     Object

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.GetEl = function(elId) {
  var obj = document.getElementById(elId);
  if(obj)
    return obj;
  else
    return null;
}

/******************************************************************************\

  GetArrayElements(arrEl)

  @Type:        Static Function
  @Use:         Returns an array with all object of given type
  @Parameters:  - arrEl[Array[String]]:  type of element
  @Returns:     Array[Object]

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.GetArrayElements = function(arrEl) {
  if(!document.getElementsByTagName) return;
  var rtn = Array();
  for(var x = 0; x<arrEl.length;x++) {
    var flds  = document.getElementsByTagName(arrEl[x]);
    for(var y=0;y<flds.length;y++) {
      var myfld = flds[y];
      rtn.push(myfld);
    }
  }
  return rtn;
}


/******************************************************************************\

  ChangeHeight()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.ChangeHeight = function(fldId,oldVal,newVal,isGrowing) {
  var fld   = this.GetEl(fldId);
  if(!fld)  return;

  growSpeed = (arguments[4])?arguments[4]:this.growSpeed;
  clearTimeout(this.t_);

  oldVal    = parseInt(oldVal);
  newVal    = parseInt(newVal);
  growSpeed = parseInt(growSpeed);

  if(isGrowing) {
    if(oldVal + growSpeed > newVal) {
      fld.style.height = (newVal) + 'px';
    } else {
      fld.style.height = (oldVal + growSpeed) + 'px';
      this.t_   = setTimeout('IS.ChangeHeight(\''+ fldId +'\','+ (oldVal+growSpeed) +','+ newVal +','+ isGrowing +','+ growSpeed +')',15);
    }
  } else {
    if(oldVal - growSpeed <= newVal) {
      fld.style.height = (newVal) + 'px';
    } else {
      fld.style.height = (oldVal - growSpeed) + 'px';
      this.t_   = setTimeout('IS.ChangeHeight(\''+ fldId +'\','+ (oldVal-growSpeed) +','+ newVal +','+ isGrowing +','+ growSpeed +')',15);
    }
  }
}

/******************************************************************************\

  GetUniqueId()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.GetUniqueId = function() {
  return "vFldId"+ ++this.uID;
}

/******************************************************************************\

  Stripe()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.Stripe = function(fld,val) {
	var even		= false;
  var force     = arguments[2] ? arguments[2] : false;
	var oddColor	= (fld.getAttributeNode("v:color1"))?fld.getAttribute("v:color1"):this.stripeOddColor;
	var evenColor	= (fld.getAttributeNode("v:color2"))?fld.getAttribute("v:color2"):this.stripeEvenColor;
  if(!fld || !fld.tagName) return;

  switch(fld.tagName) {
    case 'TABLE':
      var tbodies = fld.getElementsByTagName("tbody");
        h=0;
        var trs = tbodies[h].getElementsByTagName("tr");
        for (var i = 0; i < trs.length; i++) {
          if (! IS.HasClass(trs[i]) && ! trs[i].style.backgroundColor) {
            var tds = trs[i].getElementsByTagName("td");
            for (var j = 0; j < tds.length; j++) {
              var mytd = tds[j];
              if (force || (! IS.HasClass(mytd) &&	! mytd.style.backgroundColor)) {
                mytd.style.backgroundColor = even ? evenColor : oddColor;
              }
              if(val=="ver") even = !even;
				    }
			    }
		      if(val=="hor"||val=="stripe"||val=="fstripe")even =  ! even;
		    }

      break;
    case 'UL':
    case 'OL':
      var lis = fld.getElementsByTagName("li");
      for(var k = 0;k <lis.length;k++) {
        var myli = lis[k];
        if(force || (!IS.HasClass(myli) && !myli.style.backgroundColor)) {
          myli.style.backgroundColor = even?evenColor:oddColor;
        }
        even = !even;
      }
      break;
  }
}


/******************************************************************************\

  Highlight()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.Highlight = function(fld,val) {
  var overColor = (val=="yes"||val=="no")?this.highlightColor:val;
  if (!fld||!fld.tagName) return;
  
  switch(fld.tagName) {
    case 'TABLE':
      var tbodies = fld.getElementsByTagName("tbody");
      for(var h=0;h<tbodies.length;h++) {
        var trs = tbodies[h].getElementsByTagName("tr");
        for(var i=0;i<trs.length;i++) {
          var mytr  = trs[i];
          mytr.onmouseover  = function(evt) {
            this.oldbackground  = this.style.backgroundColor;
            this.style.backgroundColor = overColor;
            var tds = this.getElementsByTagName("td");
            for(var x=0;x<tds.length;x++) {
              mytd  = tds[x];
              mytd.oldbackground = mytd.style.backgroundColor;
              mytd.style.backgroundColor = '';
            }
          }

          mytr.onmouseout = function(evt) {
            this.style.backgroundColor=this.oldbackground;
            var tds = this.getElementsByTagName("td");
            for(var x=0;x<tds.length;x++) {
              mytd  = tds[x];
              mytd.style.backgroundColor = mytd.oldbackground;
            }
          }
        }
      }
      break;
  }
}


/******************************************************************************\

  GetParent()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.GetParent = function(el, pTagName) {
  if (el == null) return null;
  else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())	// Gecko bug, supposed to be uppercase
    return el;
  else
    return this.GetParent(el.parentNode, pTagName);
}


/******************************************************************************\

  Sortable()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.Sortable = function(table) {
  var funcs;
  if(table.rows && table.rows.length > 0) {
    var firstRow  = table.rows[0];
  }
  if(!firstRow) return;
  
  for(var i=0;i<firstRow.cells.length;i++) {
    var cell  = firstRow.cells[i];
    var txt   = IS.GetInnerText(cell);
    if(cell.getAttribute("nosort")=="nosort") {
    } else {
      if(table.getAttribute("stripe")) {
        func = "IS.Sstripe('"+ table.id +"');";
      } else {
        funcs = "";
      }
      cell.innerHTML = '<a href="#" class="sortheader" onclick="IS.ResortTable(this);'+ funcs +';return false;">'+ txt +'</a>';
    }
  }
}


/******************************************************************************\

  GetInnerText()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.GetInnerText = function(el) {
  if (typeof el == "string" || typeof el == "undefined"){
    s1 = new String(el);
    el = s1.replace(/,/g,"");
    return el;
  };
  if (el.innerText) {
    s1 = new String(el.innerText);
    el = s1.replace(/,/g,"");
    return el;
  }
  var str = "";
  var cs = el.childNodes;
  var l = cs.length;
  for (var i = 0; i < l; i++) {
    switch (cs[i].nodeType) {
      case 1:
        str += IS.GetInnerText(cs[i]);
        break;
      case 3:
        str += cs[i].nodeValue;
        break;
    }
  }
  s1 = new String(str);
  el = s1.replace(/,/g,"");
  return el;
}

/******************************************************************************\

  ResortTable()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.ResortTable = function(lnk) {
  var td      = lnk.parentNode;
  var column  = td.cellIndex;
  var table   = this.GetParent(td,'TABLE');
  if (table.rows.length <= 1) 
    return;
  
  var itm = IS.GetInnerText(table.rows[1].cells[column]);
  var s1 = new String(itm);
  itm = s1.replace(/,/g,"");
  var sortfn = IS.SortCaseInsensitive;
  
  if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) 
    sortfn = IS.SortDate;
  if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) 
    sortfn = IS.SortDate;
  if (itm.match(/^[£$€]/)) 
    sortfn = IS.SortCurrency;
  if (itm.match(/^[\d\.]+$/)) 
    sortfn = IS.SortNumeric;

  IS.SORT_COLUMN_INDEX = column;
  var firstRow = new Array();
  var newRows = new Array();
  var lngth = table.rows[0].length;
  for (var i=0;i<lngth;i++) { 
    firstRow[i] = table.rows[0][i]; 
  }
  for (var j=1;j<table.rows.length;j++) { 
    newRows[j-1] = table.rows[j]; 
  }
  newRows.sort(sortfn);
  
  if(lnk.getAttribute("sortdir") && lnk.getAttribute("sortdir") == 'down') {
    newRows.reverse();
    lnk.setAttribute('sortdir','up');
  } else {
    lnk.setAttribute('sortdir','down');
  }
  for (i=0;i<newRows.length;i++) {
    if (!newRows[i].className || (newRows[i].className && (newRows[i].className.indexOf('sortbottom') == -1))) 
      table.tBodies[0].appendChild(newRows[i]);
  }
  for (i=0;i<newRows.length;i++) {
    if (newRows[i].className && (newRows[i].className.indexOf('sortbottom') != -1)) 
      table.tBodies[0].appendChild(newRows[i]);
  }
}


/******************************************************************************\

  SortDate()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.SortDate = function(a,b) {
  var aa = IS.GetInnerText(a.cells[IS.SORT_COLUMN_INDEX]);
  var bb = IS.GetInnerText(b.cells[IS.SORT_COLUMN_INDEX]);
  var dt1, dt2, yr;
  if (aa.length == 10) {
    dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
  } else {
    yr = aa.substr(6,2);
    if (parseInt(yr) < 50) { 
      yr = '20'+yr; 
    } else { 
      yr = '19'+yr; 
    }
    dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
  }
  if (bb.length == 10) {
    dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
  } else {
    yr = bb.substr(6,2);
    if (parseInt(yr) < 50) { 
      yr = '20'+yr; 
    } else { 
      yr = '19'+yr; 
    }
    dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
  }
  if (dt1==dt2) 
    return 0;
  if (dt1<dt2) 
    return -1;
  return 1;
}


/******************************************************************************\

  SortCurrency()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.SortCurrency = function(a,b) {
  var aa = IS.GetInnerText(a.cells[IS.SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
  var bb = IS.GetInnerText(b.cells[IS.SORT_COLUMN_INDEX]).replace(/[^0-9.]/g,'');
  return parseFloat(aa) - parseFloat(bb);
}


/******************************************************************************\

  SortNumeric()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.SortNumeric = function(a,b) {
  var aa = parseFloat(IS.GetInnerText(a.cells[IS.SORT_COLUMN_INDEX]));
  var bb = parseFloat(IS.GetInnerText(b.cells[IS.SORT_COLUMN_INDEX]));
  if (isNaN(aa)) aa = 0;
  if (isNaN(bb)) bb = 0;
  return aa-bb;
}

/******************************************************************************\

  SortCaseInsensitive()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.SortCaseInsensitive = function(a,b) {
  var aa = IS.GetInnerText(a.cells[IS.SORT_COLUMN_INDEX]).toLowerCase();
  var bb = IS.GetInnerText(b.cells[IS.SORT_COLUMN_INDEX]).toLowerCase();
  var s1 = new String(aa);
  var s2 = new String(bb);
  aa = s1.replace(/,/g,"");
  bb = s2.replace(/,/g,"");
  if (!isNaN(aa) && !isNaN(bb)) {
    return aa-bb;
  }
  if (aa==bb) 
    return 0;
  if (aa<bb) 
    return -1;
  return 1;
}

/******************************************************************************\

  SortDefault()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.SortDefault = function(a,b) {
  var aa = IS.GetInnerText(a.cells[IS.SORT_COLUMN_INDEX]);
  var bb = IS.GetInnerText(b.cells[IS.SORT_COLUMN_INDEX]);
  if (aa==bb) 
    return 0;
  if (aa<bb) 
    return -1;
  return 1;
}


/******************************************************************************\

  DaysPerMonth()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.DaysPerMonth = function(m,y) {
  var days  = Array(31,28,31,30,31,30,31,31,30,31,30,31);
  
  if(this.IsLeapYear(y)) {
    days[1] = 29;
  }
  return days[m-1];
}


/******************************************************************************\

  IsLeapYear()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.IsLeapYear = function(year) {
    if ((year/4)   != Math.floor(year/4))   return false;
    if ((year/100) != Math.floor(year/100)) return true;
    if ((year/400) != Math.floor(year/400)) return false;
    return true;
}


/******************************************************************************\

  Navbox()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.Navbox = function(fld) {
  var uid             = (fld.getAttribute("v:id"))?fld.getAttribute("v:id"):IS.GetUniqueId();
  var tekst           = fld.innerHTML;
  var speed           = (fld.getAttribute("v:speed"))?fld.getAttribute("v:speed"):4;
  var navbox          = document.createElement('div');
  navbox.setAttribute('id',uid);
  navbox.setAttribute('class','navbox');
  navbox.className    = 'navbox';
  navbox.style.width  = (fld.getAttribute("v:width"))?fld.getAttribute("v:width"):this.navboxWidth;
  navbox.navset       = (fld.getAttribute("v:navset"))?fld.getAttribute("v:navset"):'';

  var navttl          = document.createElement('div');
  uid                 = IS.GetUniqueId();
  navttl.setAttribute('id',uid);
  navttl.setAttribute('class','navbox-title');
  navttl.className    = 'navbox-title';
  navttl.style.width  = navbox.style.width;
  navttl.innerHTML    = (fld.getAttribute("v:title"))?fld.getAttribute("v:title"):'&nbsp;';
  navbox.appendChild(navttl);

  var navbody         = document.createElement('div');
  uid                 = IS.GetUniqueId();
  navbody.setAttribute('id',uid);
  navbody.setAttribute('class','navbox-body');
  navbody.className  = 'navbox-body';
  navbody.style.width= navbox.style.width;
  navbody.innerHTML  = fld.innerHTML;
  navbox.appendChild(navbody);
  
  var parent         = fld.parentNode;
  parent.insertBefore(navbox,fld);
  parent.removeChild(fld);
 
  var opened    = (fld.getAttribute("v:opened"))?fld.getAttribute("v:opened"):'false';
  navbox.style.overflow = 'hidden';
  navbox.oldClientHeight= navbox.clientHeight;
  navbox.setAttribute('oldClientHeight',navbox.clientHeight);
  if(opened != 'true') {
    navbox.style.height   = navttl.clientHeight +'px';
    navttl.hidden         = true;
  } else {
    navttl.className = 'navbox-title-open';
    navttl.hidden          = false;
  }
  
  navttl.onclick         = function(evt,navbox) {
    if(this.hidden) {
      this.className = 'navbox-title-open';
      IS.ChangeHeight(this.parentNode.id,this.parentNode.clientHeight,this.parentNode.oldClientHeight,true,speed);
    } else {
      this.className  = 'navbox-title';
      IS.ChangeHeight(this.parentNode.id,this.parentNode.clientHeight,this.clientHeight,false,speed);
    }
    this.hidden = !this.hidden;
  }
  navbody.ondrag = function(evt) {}

}


/******************************************************************************\

  PanelSet()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.PanelSet = function(fld) {
	var uid     = this.GetUniqueId();	
	var pset	  = document.createElement('div');
	var first	  = true;
	var width	  = (fld.getAttribute("v:width"))?fld.getAttribute("v:width"):this.panelWidth;
	var next	  = (fld.getAttribute("v:next"))?fld.getAttribute("v:next"):this.panelNext;
	var prev	  = (fld.getAttribute("v:previous"))?fld.getAttribute("v:previous"):this.panelPrevious;
	var last	  = (fld.getAttribute("v:last"))?fld.getAttribute("v:last"):this.panelLast;
	var lastLink= (fld.getAttribute("v:lastLink"))?fld.getAttribute("v:lastLink"):this.panelLastLink;
  var lastType= (fld.getAttribute("v:lastType"))?fld.getAttribute("v:lastType"):this.panelLastType;
  var buttons= (fld.getAttribute("v:buttons"))?fld.getAttribute("v:buttons"):this.panelButtons;
	pset.setAttribute('id',uid);
	pset.setAttribute('class','panelset');
	pset.className	  = 'panelset';
	pset.style.width  = width;
	
	var panels = fld.getElementsByTagName("v:panel");
	if(panels.length==0)
    panels = fld.getElementsByTagName("panel"); 

	for(x=0;x<panels.length;x++) {
		var uidp		  = IS.GetUniqueId();
    panels[x].uid = uidp;
		var panel		  = null;
		panel			    = document.createElement('div');
		panel.setAttribute('class','panel');
		panel.className			= 'panel';
		panel.style.width		= width;
		panel.setAttribute('id',uidp);
		panel.id            = uidp;
		panel.style.visibility	= (first)?'visible':'hidden';
		panel.style.display		= (first)?'block':'none';

		var pbody             = document.createElement('div');
		pbody.setAttribute('class','panel-body');
		pbody.className       = 'panel-body';
		pbody.innerHTML = panels[x].innerHTML;
		panel.appendChild(pbody);

		var nav	= document.createElement('div');
		nav.style.width = width;
		nav.setAttribute('class','panel-nav');
		nav.className = 'panel-nav';

		if(!first) {
			var prevTxt		    = prev.replace(/{prev}/,x);
			var	btnPrev		    = document.createElement('input');
			btnPrev.setAttribute('type','button');
			btnPrev.setAttribute('value',prevTxt);
			btnPrev.onclick   = function () { 
        IS.ShowPrev(this.parentNode.parentNode.id);
        IS.HighlightButton(buttons,this.parentNode.parentNode.id,'prev');
      }
			nav.appendChild(btnPrev);
		}

		if(x==panels.length-1) {
			var	btnLast		= document.createElement('input');
      if(lastType=='submit') {
        btnLast.setAttribute('type','submit');
      } else {
			  btnLast.setAttribute('type','button');
        if(lastLink != '') {
			    btnLast.onclick = function() { eval(lastLink) }
        }
      }
			btnLast.setAttribute('value',last);
			nav.appendChild(btnLast);
		} else {
			nextTxt = next.replace(/{next}/,''+ (x+2));
			var	btnNext		= document.createElement('input');
			btnNext.setAttribute('type','button');
			btnNext.setAttribute('value',nextTxt);
			btnNext.onclick = function () { 
        IS.ShowNext(this.parentNode.parentNode.id);
        IS.HighlightButton(buttons,this.parentNode.parentNode.id,'next');
      }
			nav.appendChild(btnNext);
		}
		panel.appendChild(nav);

		first	= false;
		pset.appendChild(panel);
	}

  if(buttons && buttons != 'false') {
    var divBtn          = document.createElement('div');
	  divBtn.style.width  = width;
		divBtn.setAttribute('class','panel-buttons');
		divBtn.className    = 'panel-buttons';
    for(y=0;y < panels.length; y++) {
      var btn           = document.createElement('input');
      var ttl           = (panels[y].getAttribute("v:title"))?panels[y].getAttribute("v:title"):y+1;
      btn.setAttribute('type','button');
      btn.className     = (y==0)?'hover':'';
      btn.setAttribute('value',''+ ttl);
      btn.setAttribute('number',panels[y].uid);
      btn.onclick       = function () { 
         IS.ShowPanel(this.getAttribute('number'));
         for(var x=0;x<this.parentNode.childNodes.length;x++) {
           this.parentNode.childNodes[x].className = '';
         }
         this.className = 'hover';
         this.blur();
      }
      divBtn.appendChild(btn);
    }
    if(buttons=='before') {
      pset.insertBefore(divBtn,pset.childNodes[0]);
    } else {
      pset.appendChild(divBtn);
    }
  }

	var parent = fld.parentNode;
	parent.insertBefore(pset,fld);
	parent.removeChild(fld);
}

/******************************************************************************\

  HighlightButton()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.HighlightButton = function(buttons,panelId,follow) {
  var btns;
  var panel = document.getElementById(panelId).parentNode;
  if(buttons && buttons != 'false') {
    if(buttons == 'before') {
      btns = panel.childNodes[0];
    } else {
      btns = panel.childNodes[panel.childNodes.length-1];
    }
    for(var x=0;x<btns.childNodes.length;x++) {
      if(btns.childNodes[x].className == 'hover') {
        if(follow=='next' && x < btns.childNodes.length) {
          btns.childNodes[x].className = '';
          btns.childNodes[x+1].className = 'hover';
          return true;
        } else if(follow=='prev' && x > 0) {
          btns.childNodes[x].className = '';
          btns.childNodes[x-1].className = 'hover';
          return true;
        }
      }
    }
  }
}


/******************************************************************************\

  ShowPanel()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.ShowPanel = function(panelId) {
  
  var panel = document.getElementById(panelId);
  if(!panel) return false;
  
  var panels = panel.parentNode.getElementsByTagName('div');

  for(x = 0; x < panels.length; x++) {
    if(panels[x].getAttribute('class') == 'panel') {
      panels[x].style.visibility = 'hidden';
      panels[x].style.display = 'none';
    }
  }
  panel.style.visibility = 'visible';
  panel.style.display = 'block';
}

/******************************************************************************\

  ShowPrev()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.ShowPrev = function(fldId) {
	var fld = document.getElementById(fldId);
	fld.style.visibility = 'hidden';
	fld.style.display = 'none';
	var prev = fld.previousSibling;
	if(prev!= null) {
		prev.style.visibility = 'visible';
		prev.style.display		= 'block';
	}
}

/******************************************************************************\

  ShowNext()

  @Type:        Static Function
  @Use:         TODO
  @Parameters:  TODO
  @Returns:     TODO

  @Author:      Tom Erwich
  @Date:        21-11-2006

\******************************************************************************/
IS.ShowNext = function(fldId) {
	var fld = document.getElementById(fldId);
	fld.style.visibility = 'hidden';
	fld.style.display	 = 'none';
	var next = fld.nextSibling;
	if(next != null) {
		next.style.visibility = 'visible';
		next.style.display		= 'block';
	}
}

IS.FormValidation = function(frm,val) {
  frm.onsubmit = function() {
    IS.HandleForm(this);
    return false;
  }
  frm.formErrorBackColor = (frm.getAttributeNode("v:color"))?frm.getAttribute("v:color"):IS.formErrorBackColor;
  frm.formErrorBorderColor=(frm.getAttributeNode("v:border"))?frm.getAttribute("v:border"):IS.formErrorBorderColor;
  var els = frm.elements;

  for(var x = 0; x < els.length; x++) {
    els[x].onchange = function() {
      //alert(this.name);
      this.style.backgroundColor = "";
      this.style.borderColor = "";
    }
    els[x].onfocus = function() {
      this.style.backgroundColor = "";
      this.style.borderColor = "";
    }
  }
  if(!frm.id) frm.id = IS.GetUniqueId();
}

IS.HandleForm = function(frm) {
  var els = frm.elements;
  var err = Array();

  for(var x = 0; x < els.length; x++) {
    validations = (els[x].getAttributeNode("v:vals"))?els[x].getAttribute("v:vals"):false;
    if(validations) {
      arrVal  = validations.split(",");
      els[x].hasErrors = false;
      for(var y = 0; y < arrVal.length; y++) {
        err = IS.AddError(err,IS.FormValidate(els[x],arrVal[y]));
      }
    }
  }

  if(err.length > 0) {
    var startMessage = (frm.getAttributeNode("v:errBefore"))?frm.getAttribute("v:errBefore"):IS.formErrorBefore;
    var endMessage   = (frm.getAttributeNode("v:errAfter"))?frm.getAttribute("v:errAfter"):IS.formErrorAfter;

    str = startMessage + ':\n\n';
    for (var z = 0; z < err.length; z++) {
      str += '- '+ err[z] +'\n';
    }
    str += '\n\n'+ endMessage;
    alert(str);
    if(IS.firstErrorField) {
      IS.firstErrorField.focus();
      IS.firstErrorField = false;
    }
    return false;
  } else {
    frm.submit();
    return true;
  }
}

IS.AddError = function(err,str) {
  if(str != '') {
    err.push(str);
  }
  return err;
}

IS.FormValidate = function(field,validation) {
  var ret			= '';
	var ispos		= validation.search("=");
	var cmd			= '';
	var cmdv		= '';
	var length  = '';
	var value		= '';
  var fName   = (field.getAttributeNode("v:fname"))?field.getAttribute("v:fname"):field.name;

	if(ispos >= 0) { 
		cmd			= validation.substr(0,ispos);
		cmdv		= validation.substr(ispos+1);
	} else {
		cmd			= validation;
	}

  //alert(cmd);
  //alert(cmdv);

  switch(cmd) {
		case 'req':
			if(eval(field.value.length)==0) {
				ret		+= fName +' is niet ingevuld';
			}
			break;
		case 'maxlength':
    case 'max':
    case 'maxlen':
			length = (cmdv.length>0)?eval(cmdv):10;
			if(eval(field.value.length) > length) {
				ret		+= fName +' is langer dan '+length+' karakters';
			}
			break;
		case 'minlength':
		case 'min':
		case 'minlen':
			length = (cmdv.length>0)?eval(cmdv):10;
			if(field.value.length > 0 && eval(field.value.length) < length) {
				ret		+= fName +' is korter dan '+length+' karakters';
			}
			break;
		case 'alphanumeric':
		case 'alfanumeriek':
		case 'alnum':
			if(field.value.length > 0 && field.value.search('[^a-zA-z0-9]') >= 0) {
				ret		+= fName +' bevat niet-alfanumerieke karakters';
			}
			break;
		case 'num':
		case 'numeriek':
			if(field.value.length > 0 && field.value.search('[^0-9-]') >= 0) {
				ret		+= fName +' bevat niet alleen cijfers';
			}
			break;
    case 'double':
      if(field.value.length > 0 && field.value.search('[^0-9.,-]') >= 0) {
        ret   += fName +' bevat geen (decimaal) getal';
      }
      break;
		case 'alpha':
			if(field.value.length > 0 && field.value.search('[^a-zA-z]') >= 0) {
				ret		+= fName +' bevat niet alleen letters';
			}
			break;
		case 'alnumhyph':
			if(field.value.length > 0 && field.value.search('[^a-zA-z0-9\-_]') >= 0) {
				ret		+= fName +' mag alleen de karakters a-z,A-Z,0-9,- en _ bevatten';
			}
			break;
		case 'email':
			if(field.value.length > 0 && field.value.search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/)!=0) {
				ret		+= fName +' is geen geldig e-mailadres';
			}
			break;
    case 'emailmulti':
      value = (cmdv.length>0)?cmdv:';';
      if(field.value.length > 0) {
        var multipleEmails = field.value.split(value);
        for(x=0;x < multipleEmails.length;x++) {
          if(multipleEmails[x].length>0 && multipleEmails[x].search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/)!=0) {
            ret += fName +' bevat geen geldig e-mailadres: '+ multipleEmails[x];
          }
        }
      }
      break;
		case 'lt':
		case 'lessthan':
			value = (cmdv.length>0)?eval(cmdv):10;
			if(isNaN(field.value)) {
				ret		+= fName +' is geen nummer';
			} else {
				if(eval(field.value) >= value) {
					ret += fName +' moet kleiner zijn dan '+ value;
				}
			}
			break;
		case 'gt':
		case 'greaterthan':
			value	= (cmdv.length>0)?eval(cmdv):10;
			if(isNaN(field.value)) {
				ret		+= fName +' is geen nummer';
			} else {
				if(eval(field.value) <= value) {
					ret	+= fName +' moet groter zijn dan '+ value;
				}
			}
			break;
		case 'le':
		case 'lessequal':
			value	= (cmdv.length>0)?eval(cmdv.replace(",",".")):10;
      var valueDot  = field.value.replace(",",".");
			if(isNaN(valueDot)) {
				ret		+= fName +' is geen nummer';
			} else {
				if(eval(valueDot) > value) {
					ret += fName +' ('+ valueDot +') moet kleiner of gelijk zijn aan '+ value;
				}
			}
			break;
		case 'ge':
		case 'greaterequal':
			value	= (cmdv.length>0)?eval(cmdv):10;
			if(isNaN(field.value)) {
				ret		+= fName +' is geen nummer';
			} else {
				if(eval(field.value) < value) {
					ret	+= fName +' moet groter of gelijk zijn aan '+ value;
				}
			}
			break;
		case 'regexp':
			if(field.value.length > 0 && !field.value.match(cmdv)) {
				ret		+= fName +' voldoet niet aan de filter: '+ cmdv;
			}
			break;
		case 'dontselect':
			if(field.selectedIndex==null) {
				ret		+= 'Fout in validatie-omschrijving voor veld '+ field.name;
			} else {
				if(field.selectedIndex == eval(cmdv)) {
					ret	+= 'Geen optie gekozen in selectievak '+ field.name;
				}
			}
			break;
		case 'zip':
		case 'postal':
			switch(cmdv) {
				case 'nl':
				default:
					if(field.value.length>0 && field.value.search(/^[1-9][0-9][0-9][0-9] ?[a-zA-z][a-zA-z]$/) != 0) {
						ret += fName +' bevat geen geldige Nederlandse postcode';
					}
			}
			break;
		case 'date':
      //alert('gaan date checken');
			switch(cmdv) {
				case 'us':
				case 'en':
        case 'uk':
					if(field.value.length>0 && !IS.CheckDate(field.value)) {
						ret += fName +' bevat geen geldige Engelse datum (mm-dd-jjjj)';
					}
					break;
				case 'nl':
				default:
					if(field.value.length>0) {
						var correct = true;
						var datum	= field.value.split("-");
            //alert('lengte datum: '+ datum.length);
						if(datum.length != 3 || !IS.CheckDate(datum[1] +'-'+ datum[0] +'-'+ datum[2])) {
							ret	+= fName +' bevat geen geldige Nederlandse datum (dd-mm-jjjj)';
						}
					}
			}
			break;

		case 'cmp':
		case 'compare':
		case 'comp':
			var found	= false;
			for(var x=0;x<frm.elements.length;x++) {
				if(frm.elements[x].name==cmdv) {
					found = true;
					if(field.value!=frm.elements[x].value) {
						ret+=fName +' is niet gelijk aan '+ cmdv;
					}
				}
			}
			if(!found) {
				ret+=cmdv+' kan niet worden gevonden om te vergelijken met '+ field.name;
			}
			break;
	}

  if(ret!='') {
    field.style.backgroundColor = IS.GetParent(field,"form").formErrorBackColor;
    field.style.borderColor     = IS.GetParent(field,"form").formErrorBorderColor;
    field.hasErrors             = true;
    if(!IS.firstErrorField) {
      IS.firstErrorField = field;
    }
  } else {
    if(!field.hasErrors) {
      field.style.backgroundColor = "";
      field.style.borderColor     = "";
    }
  }
	return ret;
}

IS.CheckDate = function(dateStr) {
	var arrDate = dateStr.split("-");
	if(arrDate.length!=3) { return false; }
	var strYear		= arrDate[2];
	var numDay		= eval(arrDate[1]);
	var numMonth	= eval(arrDate[0]);
  //alert('jaar bekijken');
  var tmpStrYear = strYear;
  if(tmpStrYear != parseInt(tmpStrYear)) { return false; }
	var numYear		= eval(strYear);
  //alert('jaar bekeken');

	if(strYear.length!=2&&strYear.length!=4) { return false; }
	if(strYear.length==2&&numYear<=50) { numYear += 2000; }
	if(strYear.length==2&&numYear>50) { numYear += 1900; }
	if(numYear<0||numYear>9999) { return false; }

	if(numMonth<1||numMonth>12) { return false; }

	if(numDay>=32) { return false; }
	if(numDay>=31 && (numMonth==2||numMonth==4||numMonth==6||numMonth==9||numMonth==11)) { return false; }
	if(numDay>=30 && numMonth==2) { return false; }

	if(numMonth==2&&numDay==29) {
		var div4	= numYear % 4;
		var div100	= numYear % 100;
		var div400	= numYear % 400;
		if(div4!=0) { return false; }
		if(div100==0&&div400!=0) { return false; }
	}
	return true;
}


IS.Init();