
function common_clock_timer(var_name)
{
  this.var_name = var_name;
  this.stdTimer = new Date();

  this.day = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
  this.month = ["January", "February", "March", "April", "May",
                "June", "July", "August", "September", "October", "November", "December"];

  this.fake_msg = "??";

  this.null_year = 1970;
  this.help_list = {counter: 1};

  this.c_timer = new Array();

  this.isTimer = isTimer;
  this.getValueAsString = getValueAsString;

  this.setDay = setDay;
  this.setMonth = setMonth;
  
  // start internal function

	this.getCW = getCW;
  
  // end internal function

  this.addTimer = addTimer;
  this.delTimer = delTimer;

  this.runTimer = runTimer;
  this.genTimerCache = genTimerCache;

  return this;
}

function addTimer(cur_time, tz, offset_ms, offset_tz, fields, functions, check_after)
{
  if(cur_time < 0 || offset_ms == 0) return -1;

  if(typeof check_after != "number" || check_after == 0) check_after = -1;

  if(typeof fields != "object" ||
     typeof functions != "object" ||
     fields.length == 0 ||
     fields.length != functions.length) return -1;

  var run_all = (offset_ms > 0 ? offset_ms : (-1) * offset_ms);
  var cur_pos = this.c_timer.length;
  var to_call = this.var_name + ".runTimer(" + cur_pos + ")";

  var to_check = (check_after == -1 ? [-1] : [check_after, check_after, cur_time + offset_tz, new Date(), new Date()]);

  // [current check, max check, cur_time from server, current timestamp, startet at]

  this.c_timer[cur_pos] = [cur_time + offset_tz, new Date(), tz, offset_ms,
                           fields, functions, null /*cached fields*/,
                           window.setInterval(to_call, run_all),
                           to_check];

  return cur_pos;
}

function isTimer(cur_timer)
{
  return (cur_timer >= 0 &&
          cur_timer < this.c_timer.length &&
          this.c_timer[cur_timer] != null
          );
}

function delTimer(cur_timer, overwrite_char)
{
  if(!this.isTimer(cur_timer)) return false;

  window.clearInterval(this.c_timer[cur_timer][7]);

  if(typeof overwrite_char != "undefined")
  {
    var int_timer = this.c_timer[cur_timer];
    var len = int_timer[4].length;
    var obj = null;

    for(var i = 0; i < len; i++)
    {
      if((obj = int_timer[6][i]) == null) continue;

      if(obj.textContent) obj.textContent = overwrite_char;
      else obj.innerHTML = overwrite_char; // fix for ie7
    }
  }

  this.c_timer[cur_timer] = null;

  return true;
}

function runTimer(cur_timer)
{
  if(!this.isTimer(cur_timer)) return false;

  var int_timer = this.c_timer[cur_timer];

  if(int_timer[3] < 0 && (-1*int_timer[3] > int_timer[0]))
  {
    this.delTimer(cur_timer);

    return true;
  }

  if(int_timer[6] == null) this.genTimerCache(cur_timer);

  if(int_timer[6] == null || int_timer[6].length == 0)
  {
    this.delTimer(cur_timer);

    return false;
  }

  if(int_timer[8][0] == -1) int_timer[0] += int_timer[3];
  else
  {
    --int_timer[8][0];

    if(int_timer[8][0] == 0)
    {
      int_timer[8][0] = int_timer[8][1];

      var tmp_time = new Date();

      if(tmp_time.getTime() < int_timer[8][3].getTime())
      {
        this.delTimer(cur_timer, this.fake_msg);

        return false;
      }

      // bla bla, make it save!

      var diff = tmp_time.getTime() - int_timer[8][4].getTime();

      if(int_timer[3] < 0 && (diff > int_timer[8][2]))
      {
        this.delTimer(cur_timer, "00");

        return true;
      }

      int_timer[0] = int_timer[8][2] + (int_timer[3] >= 0 ? 1 : -1) * diff;

      int_timer[8][3] = tmp_time;

      //alert("valid ok");
    }
    else int_timer[0] += int_timer[3];
  }
  
  int_timer[1].setTime(int_timer[0]);

  var len = int_timer[4].length;
  var obj = null;
  var obj_text = null;
  var tmp = null;

  for(var i = 0; i < len; i++)
  {
    if((obj = int_timer[6][i]) == null) continue;
    
    obj_text = '';
    //(typeof obj.textContent !== 'undefined' ? int_timer[6][i].textContent : int_timer[6][i].innerText);

    switch(int_timer[5][i])
    {
      case "getDate": obj_text = this.getValueAsString(int_timer[1].getUTCDate(), 2);
                      break;
      case "getDateFull": obj_text = this.getValueAsString((int_timer[1].getUTCDate()-1) +
                                                                 (int_timer[1].getUTCMonth())*30+
                                                                 (int_timer[1].getUTCFullYear()-this.null_year)*360
                                           , 2);//?????????
                      break;
      case "getDay":  obj_text = this.day[int_timer[1].getUTCDay()];
                      break;
      case "getCW": obj_text = this.getCW(int_timer[1].getUTCFullYear(),
                                          int_timer[1].getUTCMonth()+1,
                                          int_timer[1].getUTCDate()
      																	 );
      					    break;
      case "getDayShort":  tmp = this.day[int_timer[1].getUTCDay()];
                      if(tmp.length > 3) tmp = tmp.substr(0, 3) + ".";
                      obj_text = tmp;
                      break;
      case "getYear": obj_text = this.getValueAsString(int_timer[1].getUTCFullYear(), 4);
                      break;
      case "getHours": obj_text = this.getValueAsString(int_timer[1].getUTCHours(), 2);
                      break;
      case "getHoursFull": obj_text = this.getValueAsString(int_timer[1].getUTCHours() +
                                                                 (int_timer[1].getUTCDate()-1)*24 +
                                                                 (int_timer[1].getUTCMonth())*24*30+
                                                                 (int_timer[1].getUTCFullYear()-this.null_year)*24*360
                                           , 2);//?????????
                      break;
      case "getMilliseconds": obj_text = this.getValueAsString(int_timer[1].getUTCMilliseconds(), 4);
                      break;
      case "getMinutes": obj_text = this.getValueAsString(int_timer[1].getUTCMinutes(), 2);
                      break;
      case "getMonth":  obj_text = this.getValueAsString(int_timer[1].getUTCMonth()+1, 2);
                      break;
      case "getMonthNamed":  obj_text = this.month[int_timer[1].getUTCMonth()];
                      break;
      case "getMonthNamedShort":  tmp = this.month[int_timer[1].getUTCMonth()];
                      if(tmp.length > 3) tmp = tmp.substr(0, 3) + ".";
                      obj_text = tmp;
                      break;
      case "getSeconds": obj_text = this.getValueAsString(int_timer[1].getUTCSeconds(), 2);
                      break;
      case "getTz": obj_text = int_timer[2];
                      break;

      default: break;
    }
    
    /*if(this.help_list.counter-- >= 0) {
    	if(obj.textContent) alert('textContent');
    	
    	
    } else return true;*/
    
    
    if(obj.textContent) obj.textContent = obj_text;
    else obj.innerHTML = obj_text;  // fix for ie7
  }

  return true;
}

function genTimerCache(cur_timer)
{
  if(!this.isTimer(cur_timer)) return false;

  var int_timer = this.c_timer[cur_timer];
  var len = int_timer[4].length;

  int_timer[6] = new Array();

  for(var i = 0; i < len; i++)
    int_timer[6][i] = document.getElementById(int_timer[4][i]);

  return true;
}

function getValueAsString(value, len)
{
  var rc = "" + value;

  if(rc.length >= len) return rc;

  var diff = len - rc.length;

  for(; diff; diff--) rc = "0" + rc;

  return rc;
}

function setDay(day)
{
  if(typeof day != "object" || day.length != 7) return false;

  this.day = day;

  return true;
}

function setMonth(month)
{
  if(typeof month != "object" || month.length != 12) return false;

  this.month = month;

  return true;
}

function getCW(j, m, t)
{
	//alert(j + '-' + m + '-' + t);
	
  var targetTime = new Date();
 
  if(!t) 
  {
    j = targetTime.getYear(); if(1900 > j) j +=1900;
    m = targetTime.getMonth(); t = targetTime.getDate();
  }
  else m--;
  	
  targetTime = new Date(j,m,t,0,0,1);
  		
  var day = targetTime.getDay();
  var org = targetTime;
   
  if (day == 0) day = 7;
  
  var d = new Date(2004,0,1).getTimezoneOffset();
  var summertime = (Date.UTC(j,m,t,0,d,1) - Number(targetTime)) /3600000;
  targetTime.setTime(Number(targetTime) + summertime*3600000 - (day-1)*86400000);
  var year = targetTime.getYear(); if (1900 > year) year +=1900;
  var cw = 1;
  
  if(new Date(year,11,29) > targetTime) 
  {
    var Start = new Date(year,0,1);
    Start = new Date(Number(Start) + 86400000*(8-Start.getDay()));
    if(Start.getDate() > 4) Start.setTime(Number(Start) - 604800000);
    cw = Math.ceil((targetTime.getTime() - Start) /604800000);
  }
  
  return cw;
}
