var LTM = {};
var LTA = {};
var needSync = true;
document.observe("localTime:needSync", localTimeSync);
if(Prototype.Browser.Opera){history.navigationMode = "compatible";}
if(Prototype.Browser.WebKit){
  Event.observe(window, "beforeunload", function(){needSync = true;});
}
if(Prototype.Browser.Gecko){
  Event.observe(window, "pageshow", function(){document.fire("localTime:needSync");});
}else{
  Event.observe(window, "load", function(){document.fire("localTime:needSync");});
}
/*
function activateFlash(){
	if(!document.body.outerHTML){return false;}
  if (document.getElementsByTagName) {
		if(arguments && arguments.length){
			$A(arguments).each(function(container){
				updateFlash(container);
			});
		}else{
			updateFlash(document);
		}
	}
}
function updateFlash(container){
	if(!document.body.outerHTML){return false;}
  if(!$(container)){return false;}
	
  $A($(container).getElementsByTagName("object")).each(function(obj){
    if(obj.getAttribute("type")=="application/x-shockwave-flash" || obj.getAttribute("classid")=="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"){
      var children = obj.childNodes;
      var inner = '';
			if (children.length && !(/<param/i.test(obj.innerHTML))){
				$A(children).each(function(child){
					if(child.tagName && child.tagName.toLowerCase()=="param"){
						inner += child.outerHTML;
					}
				});
			}
			obj.outerHTML = obj.outerHTML.replace('>', '>' + inner);
		}
	});
	return true;
} 
*/
function localTimeSync(){
  if(!(swfobject && swfobject.hasFlashPlayerVersion("9.0.0")) && "localTimeSyncPath" in window){
    new Ajax.Request(localTimeSyncPath, {onSuccess: localTimeInit, evalJSON:	true});
  }
}
function localTimeInit(xhr){
  var response = xhr.responseJSON;
  if(!response){return;}
  if(LTM.secondsUpdater){
    clearInterval(LTM.secondsUpdater);
    LTM.secondsUpdater = null;
  }
  LTM = new LocalTimeManager(response.seconds, {leapYear: response.leapYear});
  
  needSync = false;
  var coef = response.areas.size() > 5 ? 1 : 7-response.areas.size();
  response.areas.each(function(area){
    LTA[area.id] = new LocalTimeIn({area: "area"+area.id, manager: LTM, time: area, coefficient: coef, electronic: response.electronic, mechanical: response.mechanical});
  });
  needSync = false;
}
var LocalTimeManager = Class.create({
  initialize: function(seconds, options){
    this.seconds = seconds;
    this.secondsUpdater = setInterval(this.updateSeconds.bind(this), 1000);
    this.options = Object.extend({
      h12: true,
      months : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
      days : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
    }, options);  
    this.daysInMonths = [31, this.options.leapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
    this.objects = [];  
  },
  updateSeconds: function(){
    this.seconds ++;
    if(this.seconds == 60){
      this.seconds = 0;
      this.objects.invoke("updateMinutes");
    }
    
    this.objects.invoke("updateSeconds", to2Length(this.seconds));
    if(needSync){document.fire("localTime:needSync");}
  }
});
var JsClockFeatFlash = Class.create({
  initialize: function(area, flashObj, options){
    this.area = $(area);
    this.flashObj = $(flashObj);
    if(!(this.area && this.flashObj)){return;}
    this.elements = {
      hours: this.area.down("span.hours").firstChild,
      minutes: this.area.down("span.minutes").firstChild,
      seconds: this.area.down("span.seconds").firstChild,
      date: this.area.down("span.date").firstChild,
      day: this.area.down("span.day").firstChild,
      month: this.area.down("span.month").firstChild,
      meridiem: this.area.down("span.meridiem").firstChild
    };
    this.area.observe("localTime:sync", this.update.bind(this));
    this.options = Object.extend({
      h12: true,
      months : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
      days : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
    }, options);  
  },
  update: function(event){
    var dateObj = new Date(event.memo);
    this.elements.seconds.nodeValue = to2Length(dateObj.getUTCSeconds());
    this.elements.minutes.nodeValue = to2Length(dateObj.getUTCMinutes());
    var hours = dateObj.getUTCHours();
    if(this.options.h12){
      this.elements.meridiem.nodeValue = hours > 12 ? "PM" : "AM";
      this.elements.hours.nodeValue = hours > 12 ? to2Length(hours-12) : to2Length(hours);
    }else{
      this.elements.hours.nodeValue = to2Length(hours);
    }
    this.elements.date.nodeValue = to2Length(dateObj.getUTCDate());
    this.elements.day.nodeValue = to2Length(this.options.days[dateObj.getUTCDay()]);
    this.elements.month.nodeValue = to2Length(this.options.months[dateObj.getUTCMonth()]);
  }
});
var ElectronicClock = Class.create({
  initialize: function(elements, manager, time){
    this.elements = elements;
    this.manager = manager;
    this.time = time;
    this.updateSeconds(this.manager.seconds);
    ["minutes", "hours", "date", "day", "month"].each(function(item){
      this["update"+item.capitalize()](this.time[item]);
    }.bind(this));
/*    
    if(this.elements.seconds){this.elements.seconds.nodeValue = to2Length(this.manager.seconds);}
    ["minutes", "date"].each(function(item){
      if(this.elements[item]){this.elements[item].nodeValue = to2Length(this.time[item]);}
    }.bind(this));
    if(this.manager.options.h12){
      if(this.elements.meridiem){this.elements.meridiem.nodeValue = this.time.hours > 12 ? "PM" : "AM";}
      if(this.elements.hours){this.elements.hours.nodeValue = this.time.hours > 12 ? to2Length(this.time.hours-12) : to2Length(this.time.hours);}
    }else{
      if(this.elements.hours){this.elements.hours.nodeValue = to2Length(this.time.hours);}
    }
    if(this.elements.day){this.elements.day.nodeValue = this.manager.options.days[this.time.day];}
    if(this.elements.month){this.elements.month.nodeValue = this.manager.options.months[this.time.month];}
    */
  },
  updateSeconds: function(value){
    if(this.elements.seconds){this.elements.seconds.nodeValue = value;}
  },
  updateMinutes: function(minutes){
    if(this.elements.minutes){this.elements.minutes.nodeValue = to2Length(minutes);}
  },
  updateHours: function(hours){
    if(this.manager.options.h12){
      if(hours == 0){
        if(this.elements.meridiem){this.elements.meridiem.nodeValue = "AM";}
      }else if(hours == 12){
        if(this.elements.meridiem){this.elements.meridiem.nodeValue = "PM";}
      }
      if(this.elements.hours){this.elements.hours.nodeValue = hours > 12 ? to2Length(hours-12) : to2Length(hours);}
    }else{
      if(this.elements.hours){this.elements.hours.nodeValue = to2Length(hours);}
    }
  },
  updateDay: function(day){
    if(this.elements.day){this.elements.day.nodeValue = this.manager.options.days[day];}
  },
  updateDate: function(date){
    if(this.elements.date){this.elements.date.nodeValue = to2Length(date);}
  },
  updateMonth: function(month){
    if(this.elements.month){this.elements.month.nodeValue = this.manager.options.months[month];}
  }
});

var LocalTimeIn = Class.create({
  initialize: function(params){ 
    this.area = $(params.area);
    if(!this.area){return;}
    this.time = params.time;
    this.manager = params.manager;
    this.visual = {};
    this.elements = {
      hours: this.area.down("span.hours").firstChild,
      minutes: this.area.down("span.minutes").firstChild,
      seconds: this.area.down("span.seconds").firstChild,
      date: this.area.down("span.date").firstChild,
      day: this.area.down("span.day").firstChild,
      month: this.area.down("span.month").firstChild,
      meridiem: this.area.down("span.meridiem").firstChild
    };
    if(params.mechanical && !swfobject.hasFlashPlayerVersion("9.0.0")){ 
      this.area.down("div.action").hide();
      this.visual.mechanical = new MechanicalClock("canvas"+this.area.id, params.coefficient); 
    }
    if(params.electronic){
      this.area.down("div.time").show();
      this.visual.electronic = new ElectronicClock(this.elements, this.manager, this.time); 
    }
    this.manager.objects.push(this);
  },
  updateSeconds: function(value){ 
    if(this.visual.electronic){ this.visual.electronic.updateSeconds(value); }
    if(this.visual.mechanical){ this.visual.mechanical.update(this.time.hours, this.time.minutes, value-0); }
  },
  updateMinutes: function(){ 
    this.time.minutes ++; 
    if(this.time.minutes == 60){
      this.time.minutes = 0;
      this.updateHours();
    }
    if(this.visual.electronic){ this.visual.electronic.updateMinutes(this.time.minutes); }
  },
  updateHours: function(){
    this.time.hours ++; 
    if(this.time.hours == 24){
      this.time.hours = 0;
      this.updateDay();
    }
    if(this.visual.electronic){ this.visual.electronic.updateHours(this.time.hours); }
  },
  updateDay: function(){
    this.time.date ++; 
    this.time.day ++;
    if(this.time.date > this.manager.daysInMonths[this.time.month]){
      this.time.date = 1;
      this.updateMonth();
    }
    if(this.time.day == 7){
      this.time.day = 0;
    }
    if(this.visual.electronic){ 
      this.visual.electronic.updateDay(this.time.day); 
      this.visual.electronic.updateDate(this.time.date);
    }
  },
  updateMonth: function(){
    this.time.month ++; 
    if(this.time.month == 12){
      this.time.month = 0;
    }
    if(this.visual.electronic){ this.visual.electronic.updateDay(this.time.month); }
  }
});
var MechanicalClock = Class.create({
  initialize: function(canvas, coefficient){
    this.ctx = $(canvas).getContext('2d');
    this.coefficient = coefficient; 
    this.thickness = (Prototype.Browser.IE ? 0.3 : 1)*this.coefficient;
    this.secondsSweepbackAnimateInterval = 35;
    this.secondsSweepbackMax = 0.15;
    this.secondsSweepbackAmounts = new Array( -2*this.secondsSweepbackMax, 1.5*this.secondsSweepbackMax,
    										 -this.secondsSweepbackMax, 0.75*this.secondsSweepbackMax,
    										 -0.5*this.secondsSweepbackMax, 0.25*this.secondsSweepbackMax );
    this.secondSweepbackAnimation = {step:0, timer:null, originalSeconds:0};
    this.imgLoaded = false;
    this.img1Loaded = false;
    this.img1 = new Image();
    this.img1.src = "/images/clock/day-clock-face_c"+this.coefficient+".png";
    this.img1.onload= function (){this.img1Loaded = true;}.bind(this);
    this.img = new Image();
    this.img.src = "/images/clock/day-clock-glass_c"+this.coefficient+".png"; 
    this.img.onload= function (){this.imgLoaded = true;}.bind(this);
  },
  update: function(hr, min, sec){
    this.hoursAngle = hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec;
    this.minutesAngle = (Math.PI/30)*min + (Math.PI/1800)*sec;
    this.secondsAngle = sec * Math.PI/30;
	  this.drawHands();
    this.secondSweepbackAnimation.originalSeconds = sec+this.secondsSweepbackMax;
		if (this.secondSweepbackAnimation.timer != null)
		{
			clearInterval(this.secondSweepbackAnimation.timer);
			this.secondSweepbackAnimation.timer = null;
		}
		this.secondSweepbackAnimation.step = 0;
		this.secondSweepbackAnimation.timer = setInterval(this.secondSweepbackAnimate.bind(this), this.secondsSweepbackAnimateInterval);
  },
  drawHands: function(){
    this.ctx.save();
    this.ctx.clearRect(0,0,60*this.coefficient,60*this.coefficient);
    this.ctx.drawImage(this.img1, 1, 1);   
    this.ctx.restore();
    this.ctx.save();
    this.ctx.translate(30*this.coefficient,30*this.coefficient);
    this.ctx.scale(0.4,0.4);
    this.ctx.rotate(-Math.PI/2);
    this.ctx.lineCap = "round";
    this.ctx.fillStyle = "black";
    this.ctx.save();
    this.ctx.rotate(this.hoursAngle);
    this.ctx.lineWidth = 5*this.thickness;
    this.ctx.beginPath();
    this.ctx.moveTo(-10*this.coefficient,0);
    this.ctx.lineTo(35*this.coefficient,0);
    this.ctx.stroke();
    this.ctx.restore();
    this.ctx.fillStyle = "black";
    this.ctx.save();
    this.ctx.rotate(this.minutesAngle);
    this.ctx.lineWidth = 3*this.thickness;
    this.ctx.beginPath();
    this.ctx.moveTo(-14*this.coefficient,0);
    this.ctx.lineTo(45*this.coefficient,0);
    this.ctx.stroke();
    this.ctx.restore();
    this.ctx.save();
    this.ctx.rotate(this.secondsAngle);
    this.ctx.strokeStyle = "#D40000";
    this.ctx.fillStyle = "#D40000";
    this.ctx.lineWidth = 2*this.thickness;
    this.ctx.beginPath();
    this.ctx.moveTo(-15*this.coefficient,0);
    this.ctx.lineTo(42*this.coefficient,0);
    this.ctx.stroke();
    this.ctx.beginPath();
    this.ctx.arc(0,0,10*this.coefficient/2,0,Math.PI*2,true);
    this.ctx.fill();
    this.ctx.restore();
    this.ctx.restore();
    this.ctx.drawImage(this.img, 1, 1);   
  },
  secondSweepbackAnimate: function(){
  	if (this.secondSweepbackAnimation.step >= this.secondsSweepbackAmounts.length)
  	{
  		clearInterval(this.secondSweepbackAnimation.timer);
  		this.secondSweepbackAnimation.timer = null;
  		this.secondSweepbackAnimation.step = 0;
  	}
  	else
  	{
      this.secondSweepbackAnimation.originalSeconds = this.secondSweepbackAnimation.originalSeconds + this.secondsSweepbackAmounts[this.secondSweepbackAnimation.step];
      this.secondsAngle = this.secondSweepbackAnimation.originalSeconds * 0.10471975511965977; // all angles computed in radians
  		this.drawHands ();
  		this.secondSweepbackAnimation.step++;
  	}
  }

});
function to2Length(number){
  return (Object.isNumber(number) && number < 10 ? "0" : "")+number;
}
Object.extend(Array.prototype, {
  loopNext: function(value) { //For Arrays with unique elements
		return (this.indexOf(value) != -1) ? (this[this.indexOf(value)+1 ] || this[0]) : null;
  }
});
function onFlashTimeChanged(flashObjId, timestamp){
  if($(flashObjId)){
		$(flashObjId).fire("localTime:sync", timestamp);
	}
}