﻿var padStrings = []
padStrings[0] = ''
padStrings[1] = '0'
padStrings[2] = '00'
padStrings[3] = '000'
padStrings[4] = '0000'
padStrings[5] = '00000'
padStrings[6] = '000000'
padStrings[7] = '0000000'

//Utility functions

// generate a "unique" id for filenames, etc
function getID()  
{
  var d = new Date()
  return d.getTime()
}

///////////////// browser environment stuff /////////////////

// add event listener
  function addEvent(id, eventName, callback)
  {
    if (typeof id == 'string')
      d = document.getElementById(id);
    else
      d = id

    if (!d) 
      return
    if (d.addEventListener)
      d.addEventListener (eventName, callback, true)
    else
      d.attachEvent('on'+eventName, callback)
  }

// remove event listener
  function removeEvent(id, eventName, callback)
  {
    if (typeof id == 'string')
      d = document.getElementById(id);
    else
      d = id

    if (!d) 
      return
    if (d.removeEventListener)
      d.removeEventListener (eventName, callback, true)
    else
      d.detachEvent('on'+eventName, callback)
  }

// find what key was pressed



function keyPressed(e)
{
  var characterCode // literal character code will be stored in this variable

  if(e && e.which) //if which property of event object is supported (NN4)
  {
    characterCode = e.which //character code is contained in NN4's which property
  }
  else
  {
    if (!window.event)
      return true
    e = event
    characterCode = e.keyCode //character code is contained in IE's keyCode property
  }
  return characterCode
}

// call f if the keypressed was a CR
function kp(e, f){ //e is event object
  var characterCode = keyPressed(e)
  if (characterCode == 13) //if generated character code is equal to ascii 13 (if enter key)
  {
    f()
    return false
  }
  else
  {
    return true
  }
}


// stop drags being mistaken for selections
function disableSelection(element) {
  element.onselectstart = function() {
      return false;
  };
  element.unselectable = "on";
  element.style.MozUserSelect = "none";
//  element.style.cursor = "default"; // want it to appear as a hand
}

function _setFocus(id)
{
  try
  {
    document.getElementById(id).focus()
  }
  catch(ex)
  {
  }
}

function setFocus(id)
{
  setTimeout ("_setFocus('" + id + "')", 0)
}

// browser sledgehammer for opacity on DIVs, etc
function setOpacity (div, o)
{
  div.style.opacity = o
  div.style.filter = 'alpha(opacity='+100*o+')'
}

// browser-neutral way of getting size of useable window

    function getViewportSize()
    {
      var size = {width:0, height:0}
      if (typeof window.innerWidth != 'undefined')
      {
        size.width = window.innerWidth
        size.height = window.innerHeight
      }
      else if (typeof document.documentElement != 'undefined' &&
               typeof document.documentElement.clientWidth != 'undefined' &&
               document.documentElement.clientWidth != 0)
      {
        size.width = document.documentElement.clientWidth
        size.height = document.documentElement.clientHeight
      }
      else
      {
        size.width = document.getElementsByTagName('body')[0].clientWidth
        size.height = document.getElementsByTagName('body')[0].clientHeight
      }

      return size
    }

// get element position (left, top)
// when positioning elements on a page you want includeScroll false (or absent)
// when dealing with mouse positions you want includeScroll true
getTop = function(o, includeScroll){
  var nTop = null;
  if(o)
  {
    do{
    nTop += o.offsetTop;
    o = o.offsetParent;
    } while(o)
  }
	if (includeScroll)
	  nTop -= getScrollPosition().y
  return nTop
}

getLeft = function(o, includeScroll){
  var nLeft = null;
  if(o)
  {
    do{
    nLeft += o.offsetLeft;
    o = o.offsetParent;
    } while(o)
  }
	if (includeScroll)
	  nLeft -= getScrollPosition().x
  return nLeft
}

/** This is high-level function; REPLACE IT WITH YOUR CODE.
 * It must react to delta being more/less than zero.
 */
/*
function handle(delta) {
	if (delta < 0)
		// something
	else
		// something
}

function wheel(event){
	var delta = 0;
	if (!event) event = window.event;
	if (event.wheelDelta) {
		delta = event.wheelDelta/120; 
		if (window.opera) delta = -delta;
	} else if (event.detail) {
		delta = -event.detail/3;
	}
	if (delta)
		handle(delta);
        if (event.preventDefault)
                event.preventDefault();
        event.returnValue = false;
}

// Initialization code.
if (window.addEventListener)
	window.addEventListener('DOMMouseScroll', wheel, false);
window.onmousewheel = document.onmousewheel = wheel;
*/

///////////////// STRING functions /////////////////////

function isDigit(s)
{
  return (s.charAt(0) >= '0' && s.charAt(0) <= '9')
}

function toTitleCase(str)
{
  if (str.length == 0) 
    return str
  
  function word(txt)
  {
// begins with digit? (probably a postcode)    
    if (isDigit(txt))
      return txt.toUpperCase()
    else
      return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
  }

  return str.replace(/\w\S*/g, word);
}

function stripSpaces(s)
{
  return s.replace (/ /g, '')
}

// extend a string s to length n using character char (default is space)
function rightPad (s, n, char)
{
  if (char == '0')// does this really speed it up?
  {
    var nPad = n-s.length
    return padStrings[nPad] + s
  }
	var a = Array(n-s.length+1)
	char = char | ' '
	return a.join(char)+s
}


/////////////////////// MATHs functions //////////////////////////

// do mod (avoiding %, which doesn't handle negative numbers well)
function mod(a, b) // copes with -ve a unlike %
{
	return Math.round(a-Math.floor(a/b)*b)
}


/////////////////////// Array extender ////////////////////////////

// make a map function if not native to JavaScript implementation
if (!Array.prototype.map)
{
  Array.prototype.map = function(f)
  {
    var a=[]
    for (var i=0; i<this.length; i++)
      a[i]=f(this[i])
    return a
  }
}

if (!Array.prototype.filter)
{
  Array.prototype.filter = function(fun /*, thisp*/)
  {
    var len = this.length;
    if (typeof fun != "function")
      throw new TypeError();

    var res = new Array();
    var thisp = arguments[1];
    for (var i = 0; i < len; i++)
    {
      if (i in this)
      {
        var val = this[i]; // in case fun mutates this
        if (fun.call(thisp, val, i, this))
          res.push(val);
      }
    }

    return res;
  };
}
//////////////////////// Object extender ///////////////////////////
// copy an object and its subobjects
function clone(obj){
  if(!obj || 'object' !== typeof obj){
    return obj;
  }
  var c = new obj.constructor();
  var p,v;
  for(p in obj){
    if(obj.hasOwnProperty(p)){
      v = obj[p];
      c[p] = clone(v);
    }
  }
  return c;
}


/////////////////////////////// DIAGNOSTICS ///////////////////////////

// diagnostic functions for the two status lines

function setStatus (s)
{
  var d = document.getElementById('status')
  if (d)
    d.innerHTML = s
}

function setStatus2 (s)
{
  var d = document.getElementById('status2')
  if (d)
    d.innerHTML = s
}


/////////////////////////////// HTML BUILDERS ///////////////////

//Create DOM elements

function makeTextNode(s){
  return document.createTextNode(s);
}

function makeHTML(type){
  return document.createElement(type);
}

function makeSpanNode(s,classname){
  var sp = makeHTML('span');
  sp.className = classname;
  sp.appendChild(makeTextNode(s));
  return sp;
}

function makeNamedElement(tag, name) {
  var ele = (document.all && name) ? document.createElement('<' + tag + ' name="' + name + '">') : document.createElement(tag);
  if (!document.all && name) {
    ele.name = name;
  }
  return ele;
}

function createRef(href,title,legend){
  var a = document.createElement('a');
  a.setAttribute('href',href);
  a.setAttribute('title',title);
  
  var tn = makeTextNode(legend);
  a.appendChild(tn);
  return a;
}

function makeColElement(width){
  var c = makeHTML('col');
  c.setAttribute('width',width);
  return c;
}