var Cookie = {
	set: function(name, value, daysToExpire) {
		var expire = '';
		if (daysToExpire != undefined) {
		var d = new Date();
		d.setTime(d.getTime() + (86400000 * parseFloat(daysToExpire)));expire = '; expires=' + d.toGMTString();
		}
		return (document.cookie = escape(name) + '=' + escape(value || '') + expire +"; path=/");
	},
	get: function(name) {
		var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(name) + '=([^;\\s]*)'));
		return (cookie ? unescape(cookie[2]) : null);
	},
	erase: function(name) {
		var cookie = Cookie.get(name) || true;
		Cookie.set(name, '', -1);
		return cookie;
	}
}

if (typeof fleegix == 'undefined') { var fleegix = {}; }
if (typeof fleegix.color == 'undefined') { fleegix.color = {}; }
fleegix.color.convert = {};

fleegix.color.convert.hexPat = /^[#]{0,1}([\w]{1,2})([\w]{1,2})([\w]{1,2})$/;
fleegix.color.convert.hex2rgb = function (str) {
  var rgb = [];
  var h = str.match(fleegix.color.convert.hexPat);
  if (h) {
    for (var i = 1; i < h.length; i++) {
      var s = h[i];
      s = s.length == 1 ? s + s : s;
      rgb.push(parseInt(s, 16));
    }
    return rgb;
  }
  else {
    throw('"' + str + '" not a valid hex value.');
  }
};

fleegix.color.convert.rgb2hex = function(rP, gP, bP) {
  var conv = function (x) {
    x = new Number(x);
    var s = x.toString(16);
    while(s.length < 2) { s = "0" + s; }
    return s;
  };
  if (rP instanceof Array) {
    var rgb = rP;
  }
  else { var rgb = [rP, gP, bP]; }
  var hex = [];
  for (var i = 0; i < rgb.length; i++) {
    hex.push(conv(rgb[i]));
  }
  hex.unshift("#");
  return hex.join('');
};

// Credits: Based on C Code in "Computer Graphics --
// Principles and Practice," Foley et al, 1996, p. 593.
// Input is h (0-360), s (0-100), v (0-100),
//    or [h,s,v] with same ranges
// Output is 0-255 range for each of [r,g,b]
fleegix.color.convert.hsv2rgb = function (hP, sP, vP) {
  var h = null; var s = null; var v = null;
  if (hP instanceof Array) {
    h = hP[0] || 0;
    s = hP[1] || 0;
    v = hP[2] || 0;
  }
  else { h = hP; s = sP; v = vP; }
  if (h == 360) { h = 0; }
  s /= 100; v /= 100;
  var r = null; var g = null; var b = null;

  if (s == 0) {
    // Color is on black-and-white center line
    // achromatic: shades of gray
    r = v; g = v; b = v;
  }
  else {
    // Chromatic color
    var hTemp = h / 60;    // h is now IN [0,6]
    var i = Math.floor(hTemp);  // largest integer <= h
    var f = hTemp - i;    // fractional part of h
    var p = v * (1 - s);
    var q = v * (1 - (s * f));
    var t = v * (1 - (s * (1 - f)));

    switch(i) {
      case 0: r = v; g = t; b = p; break;
      case 1: r = q; g = v; b = p; break;
      case 2: r = p; g = v; b = t; break;
      case 3: r = p; g = q; b = v; break;
      case 4: r = t; g = p; b = v; break;
      case 5: r = v; g = p; b = q; break;
    }
  }

  r = Math.round(r * 255);
  g = Math.round(g * 255);
  b = Math.round(b * 255);
  return [r, g, b];
};

// Credits: Based on C Code in "Computer Graphics --
// Principles and Practice," Foley et al, 1996, p. 593.
// Input is 0-255 for each of r,g,b or [r,g,b]
// Output is [h (0-360), s (0-100), v (0-100)]
fleegix.color.convert.rgb2hsv = function(rP, gP, bP) {
  var r = null; var g = null; var b = null;
  if (rP instanceof Array) {
    r = rP[0] || 0;
    g = rP[1] || 0;
    b = rP[2] || 0;
  }
  else { r = rP; g = gP; b = bP; }

  var h = null; var s = null; var v = null;
  var min = Math.min(r, g, b);

  v = Math.max(r, g, b);
  var delta = v - min;
  // Calculate saturation (0 if r, g and b are all 0)
  s = (v == 0) ? 0 : delta/v;
  if (s == 0) {
    // Achromatic: when saturation is, hue is undefined
    h = 0;
  }
  else {
    // Chromatic
    if (r == v) {
      // Between yellow and magenta
      h = 60 * (g - b) / delta;
    }
    else {
      if (g == v) {
        // Between cyan and yellow
        h = 120 + 60 * (b - r) / delta;
      }
      else {
        if (b == v) {
          // Between magenta and cyan
          h = 240 + 60 * (r - g) / delta;
        }
      }
    }
    if (h <= 0) { h += 360; }
  }
  s = s * 100;
  v = (v / 255) * 100;

  h = Math.round(h);
  s = Math.round(s);
  v = Math.round(v);

  return [h, s, v];
};

///////////////////////////////////////////////////////////////////////////
//
function alphaOf( s) {
    var i = s.search( /[^A-Za-zÄÖÜäöüß]/); /* /[^\w]/ */
    if (i < 0) {
        return (s);
    } else {
        return (s.substring( 0, i));
    }  
}

///////////////////////////////////////////////////////////////////////////
//
function digitsOf( s) {
    var i = s.search( /[^0-9]/);
    if (i < 0) {
        return (s);
    }
    else {
        return (s.substring (0, i));
    }
}

///////////////////////////////////////////////////////////////////////////
//
function digitsStripLd0( s)
{
    var i = s.search( /[1-9]|[0]$/);
    if (i < 0) {
        return ("");
    }
    else {
        return (digitsOf( s.substring( i, s.length)));
    }
}

///////////////////////////////////////////////////////////////////////////
//
function trimString( s)
{
    var i = 0;
    var l = s.length;
    while(
          i < l
          &&
          s.charAt( i) == ' '
          ||
          s.charAt( i) == '\n'
          ||
          s.charAt( i) == '\r'
          ||
          s.charAt( i) == '\t'
          ||
          s.charAt( i) == '\f'
          ) {
        i++;
    }
    if (i >= l) {
        return ("");
    }
    do {
        l--;
    }
    while(
          s.charAt( l) == ' '
          ||
          s.charAt( l) == '\n'
          ||
          s.charAt( l) == '\r'
          ||
          s.charAt( l) == '\t'
          ||
          s.charAt( l) == '\f'
          );
    return (s.substring( i, l + 1));
}

///////////////////////////////////////////////////////////////////////////
//
function todayMillis()
{
    var d = new Date();
    d.setHours( 0);
    d.setMinutes( 0);
    d.setSeconds( 0);
    d.setMilliseconds( 0);
    return (d.getTime());
}

///////////////////////////////////////////////////////////////////////////
//
function parseMonth( s)
{
    var m = -1;
    var ms = alphaOf( trimString( s)).toLowerCase();
    if (ms.length > 0) {
        if (ms.indexOf( "ja") == 0) { m = 0; }
        else if (ms.indexOf( "f") == 0) { m = 1;}
        else if (ms.indexOf( "m") == 0 && (ms.indexOf( "ä") > 0 || ms.indexOf( "r") > 0)) { m = 2; }
        else if (ms.indexOf( "a") == 0 && (ms.indexOf( "p") > 0 || ms.indexOf( "r") > 0)) { m = 3; }
        else if (ms.indexOf( "mai") == 0 || ms.indexOf( "may") == 0) { m = 4; }
        else if (ms.indexOf( "ju") == 0 && ms.indexOf( "n") > 0) { m = 5; }
        else if (ms.indexOf( "ju") == 0 && ms.indexOf( "l") > 0) { m = 6; }
        else if (ms.indexOf( "au") == 0) { m = 7; }
        else if (ms.indexOf( "s") == 0) { m = 8; }
        else if (ms.indexOf( "o") == 0) { m = 9; }
        else if (ms.indexOf( "n") == 0) { m = 10; }
        else if (ms.indexOf( "d") == 0) { m = 11; }
    }
    else {
        ms = digitsOf( trimString( s));
        if (ms.length > 0)
            m = parseInt( digitsStripLd0( ms));
    }
    return (m);
}

///////////////////////////////////////////////////////////////////////////
//
function dateStringToMillis(s, txto) {
    var val;
    var dmy = new Array(3);
    var i;
    var j;
    var dmys = s.split( /[^0-9]+/);
    var dmysl = dmys.length;
    if (dmysl < 3) {
        if (dmysl == 2) {
            var month = -1;
            var matches = s.match( /[\s][^0-9]+[\s]/);
            if (matches != null) {
                month = parseMonth( matches[0]);
            }
            if (month >= 0) {
                dmys = new Array( dmys[0], "" + (month + 1), dmys[1]);
                dmysl = 3;
            }
            else {
                return (Number.NaN);
            }
        }
        else {
            return (Number.NaN);
        }
    }
    j = 0;
    for (i = 0; i < dmysl; i++) {
        if (dmys[i].length > 0) {
            dmy[j++] = parseInt( digitsStripLd0( dmys[i]));
            if (j == 3)
                break;
        }
    }
    if (dmy[2] < 25)
        dmy[2] += 2000;
    else if (dmy[2] < 100)
        dmy[2] += 1900;
    if (
        dmy[1] >= 1 && dmy[1] <= 12 && dmy[0] >= 1
        &&
        dmy[0] <=
        (
         (dmy[1] == 2)
         ?
         (((dmy[2] %4 == 0) && ((dmy[2] % 100 != 0) || (dmy[2] % 400 == 0))) ? 29 : 28)
         :
         (30 + (((dmy[1] < 8) ? dmy[1] : (dmy[1] + 1)) % 2))
         )
        ) {
        val = (new Date( dmy[2], dmy[1] - 1, dmy[0])).getTime();
        if (txto != null)
            txto.value = ((dmy[0] < 10) ? ("0" + dmy[0]) : dmy[0]) + ((dmy[1] < 10) ? ".0" : ".") + dmy[1] + "." + dmy[2];
    }
    else {
        val = Number.NaN;
    }
    return (val);
}

///////////////////////////////////////////////////////////////////////////
//
function validDate(date) {
    if (!date.match(/^\d{1,2}\.\d{1,2}.\d{4}$/)) {
        return Number.NaN;
    }
    return dateStringToMillis(date);
}