/*
* jQuery clockdate - Clock plugin
*  Copyright (2) 2011 Mewsoft <http://www.mewsoft.com>. All right reserved.
* Licensed under the MIT License.
* 
* Based on Doug Sparling jclock code <http://www.dougsparling.com> Copyright (c) 2007-2011 
* Licensed under the MIT License:
* http://www.opensource.org/licenses/mit-license.php
*/
(function($) {
  //---------------------------------------------------------------------------     
  //---------------------------------------------------------------------------     
  $.fn.clockdate = function(options) {
    var version = '3.0.0';
 
    // options
    var opts = $.extend({}, $.fn.clockdate.defaults, options);
         
    return this.each(function() {
      $this = $(this);
      $this.timerID = null;
      $this.running = false;
 
      // Record keeping for seeded clock
      $this.increment = 0;
      $this.lastCalled = new Date().getTime();
 
      var o = $.meta ? $.extend({}, opts, $this.data()) : opts;
 
      $this.format = o.format;
      $this.utc = o.utc;
      $this.utcOffset = (o.utc_offset != null) ? o.utc_offset : o.utcOffset;
      $this.timestamp = (o.timestamp != null) ? o.timestamp*1000: undefined; // timestamp in millseconds
      $this.timeout = (o.timeout != null) ? o.timeout : 1000;
 
      $this.css({
        fontFamily: o.fontFamily,
        fontSize: o.fontSize,
        backgroundColor: o.background,
        color: o.foreground
      });

	  $this.daysabbr = o.daysabbr;
      $this.days = o.days;
      $this.monthsabbr = o.monthsabbr;
	  $this.months = o.months;
	  $this.ampm =o.ampm;

	  $.fn.clockdate.startClock($this);
     });
  };
  //---------------------------------------------------------------------------     
  //---------------------------------------------------------------------------     
  $.fn.clockdate.startClock = function(el) {
    $.fn.clockdate.stopClock(el);
    $.fn.clockdate.displayTime(el);
  }
 
  $.fn.clockdate.stopClock = function(el) {
    if(el.running) {
      clearTimeout(el.timerID);
    }
    el.running = false;
  }
 
  $.fn.clockdate.displayTime = function(el) {
    var time = $.fn.clockdate.getTime(el);
    el.html(time);
    el.timerID = setTimeout(function(){$.fn.clockdate.displayTime(el)},el.timeout);
  }
 
  $.fn.clockdate.getTime = function(el) {
    if(typeof(el.timestamp) == 'undefined' || el.timestamp < 0) {
      // Seed time not being used, use current time
      var now = new Date();
    } else {
      // Otherwise, use seed time with increment
      el.increment += new Date().getTime() - el.lastCalled;
      var now = new Date(el.timestamp + el.increment);
      el.lastCalled = new Date().getTime();
    }
 
    if(el.utc == true) {
      var localTime = now.getTime();
	  //The getTimezoneOffset() method returns the time difference between Greenwich Mean Time (GMT) and local time, in minutes
      var localOffset = now.getTimezoneOffset() * 60000; //offset in ms
      var utc = localTime + localOffset;
      var utcTime = utc + (3600000 * el.utcOffset);
      now = new Date(utcTime);
    }
 
    var timeNow = "";
    var i = 0;
    var index = 0;
    while ((index = el.format.indexOf("%", i)) != -1) {
      timeNow += el.format.substring(i, index);
      index++;
 
      // modifier flag
      //switch (el.format.charAt(index++)) {
      //}
      
      var property = $.fn.clockdate.getProperty(now, el, el.format.charAt(index));
      index++;
      
      //switch (switchCase) {
      //}
 
      timeNow += property;
      i = index
    }
 
    timeNow += el.format.substring(i);
    return timeNow;
  };
 
  $.fn.clockdate.getProperty = function(dtDate, el, property) {
	var sElement = "";

    switch (property) {
      
	  case "a": // abbrv day names, Sun, Mon,...
          return (el.daysabbr[dtDate.getDay()]);
      
	  case "A": // full day names, Sunday, Monday,...
          return (el.days[dtDate.getDay()]);
      
	  case "b": // abbrv month names, Jan, Feb,...
          return (el.monthsabbr[dtDate.getMonth()]);
      
	  case "B": // full month names, January,...
          return (el.months[dtDate.getMonth()]);
      
	  case "d": // day 01-31
          return $.fn.clockdate.AddLeadingZero(dtDate.getDate());

	  case "D": // day 1-31, without leading zero
          return (dtDate.getDate());
	  
	  case "H": // hour as a decimal number using a 24-hour clock with leading zero (range 00 to 23)
          return $.fn.clockdate.AddLeadingZero(dtDate.getHours());

	  case "h": // hour as a decimal number using a 24-hour clock without leading zero (range 0 to 23)
          return (dtDate.getHours());
	  
	  case "I": // hour as a decimal number using a 12-hour clock (range 01 to 12)
          var hours = (dtDate.getHours() % 12 || 12);
          return $.fn.clockdate.AddLeadingZero(hours);
      
	  case "l": // hour as a decimal number using a 12-hour clock (range 1 to 12)
          var hours = (dtDate.getHours() % 12 || 12);
          return hours;
      
	  case "m": // month number 1..12
          return $.fn.clockdate.AddLeadingZero(dtDate.getMonth() + 1);
      
	  case "M": // minute as a decimal number 00..59
          return $.fn.clockdate.AddLeadingZero(dtDate.getMinutes());
      
	  case "p": // either `am' or `pm' according to the given time value,
          // or the corresponding strings for the current locale
          return (dtDate.getHours() < 12 ? el.ampm[0] : el.ampm[1] ); //"am" : "pm"
      
	  case "P": // either `AM' or `PM' according to the given time value,
          return (dtDate.getHours() < 12 ? el.ampm[2] : el.ampm[3]); //"AM" : "PM"
      
	  case "S": // second as a decimal number 00..59
          return $.fn.clockdate.AddLeadingZero(dtDate.getSeconds());

	  case "s": // second as a decimal number 0..59, without leading zeros
          return (dtDate.getSeconds());

      case "y": // two-digit year 00..99
          return dtDate.getFullYear().toString().substring(2);

      case "Y": // full year 2011..2099
          return (dtDate.getFullYear());

        case "t": // Number of days in the given month eg. 28 through 31
          var dtTemp = new Date(dtDate.valueOf());
          dtDate.setMonth(dtDate.getMonth() + 1)
          dtDate.setDate(0);
          return (dtDate.getDate());

        case "z": // The day of the year (starting from 0) eg. 0 through 365
          var dtFirst = new Date(dtDate.getFullYear(), 0, 1, 0, 0, 0, 0);
          var dtLast = new Date(dtDate.getFullYear(), dtDate.getMonth(), dtDate.getDate(), 0, 0, 0, 0);
          return (Math.round((dtLast.valueOf() - dtFirst.valueOf()) / 1000 / 60 / 60/ 24));

		
        case "g": //Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise.
          var dtTempFirst = new Date(dtDate.getFullYear(), 0, 1);
          var dtTempLast = new Date(dtDate.getFullYear(), dtDate.getMonth(), dtDate.getDate());
          var iDaysDiff = (dtTempLast.valueOf() - dtTempFirst.valueOf()) / 1000 / 60 / 60 / 24;
          if (iDaysDiff == Math.round(iDaysDiff)) {return (0);} else {return (1);}

        case "L": // Whether it's a leap year 1 if it is a leap year, 0 otherwise.
			 if ((new Date(dtDate.getFullYear(), 2, 0)).getDate() == 29)  { return (1);} else { return  (0);}

        case "N": // ISO-8601 numeric representation of the day of the week eg. 1 (for Monday) through 7 (for Sunday)
			if (dtDate.getDay() == 0) { return (7);} else {return (dtDate.getDay())};

		case "O": // Difference to Greenwich time (GMT) in hours eg. +0200
			(dtDate.getTimezoneOffset() < 0) ? sElement = Math.abs(dtDate.getTimezoneOffset()) : sElement = (0 - (dtDate.getTimezoneOffset()));
			var sgn = "";
			if (sElement<0) {sgn = '-';}else {sgn='+';}
			sElement = Math.abs(sElement);
			var hrs = Math.floor(sElement / 60);
			var mnts = sElement - hrs *60;
			var hrs = $.fn.clockdate.AddLeadingZero(hrs);
			var mnts = $.fn.clockdate.AddLeadingZero(mnts);
			sElement = sgn+hrs+''+mnts;
			return (sElement);

        case "o": // Difference to Greenwich time (GMT) with colon between hours and minutes eg. +02:00
			
		  (dtDate.getTimezoneOffset() < 0) ? sElement = Math.abs(dtDate.getTimezoneOffset()) : sElement = (0 - (dtDate.getTimezoneOffset()));
		  if (sElement<0) {sgn = '-';}else {sgn='+';}
		  sElement = Math.abs(sElement);
		  hrs = Math.floor(sElement / 60);
		  mnts = sElement - hrs *60;
		  hrs = $.fn.clockdate.AddLeadingZero(hrs);
		  mnts = $.fn.clockdate.AddLeadingZero(mnts);
		  sElement = sgn+hrs+':'+mnts;
          return (sElement);

        case "U": // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) eg. a big integer
			return (Math.floor(dtDate.getTime() / 1000));

        case "W": // ISO-8601 week number of year, weeks starting on Monday eg. Example: 42 (the 42nd week in the year)
			var dtTempFirst = new Date($.fn.clockdate.FirstMonday(dtDate.getFullYear()));
			var dtTempLast = new Date(dtDate.getFullYear(), dtDate.getMonth(), dtDate.getDate());
			sElement = Math.ceil(Math.round((dtTempLast.valueOf() - dtTempFirst.valueOf()) / 1000 / 60 / 60/ 24) / 7);
			return (sElement);

        case "Z": // Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. eg. -43200 through 43200
			(dtDate.getTimezoneOffset() < 0) ? sElement = Math.abs(dtDate.getTimezoneOffset() * 60) : sElement = (0 - (dtDate.getTimezoneOffset() * 60));
			return (sElement);
		
        case "r": //  Swatch Internet time eg. 000 through 999
			sElement = Math.floor(((dtDate.getHours() * 60 * 60 * 1000) + (dtDate.getMinutes() * 60 * 1000) + (dtDate.getSeconds() * 1000) + (dtDate.getMilliseconds())) / 86400);
			return (sElement);

      case "%":
          return "%";
    }
 
  }

  // find the first Monday in a given year (for ISO 8601 dates)
  $.fn.clockdate.FirstMonday = function (iYear) {
    var dtTemp = new Date(iYear, 0, 1);
    while (dtTemp.getDay() != 1) {
      dtTemp.setDate(dtTemp.getDate() + 1);
    }
    return dtTemp.valueOf();
  }


  // add leading zero
  $.fn.clockdate.AddLeadingZero = function (iValue) {
    if (iValue < 10) {
      iValue = ("0" + iValue);
    }
    return iValue;
  }
       
  // plugin defaults (24-hour)
  $.fn.clockdate.defaults = {
    format: '%H:%M:%S',
    utcOffset: 0,
    utc: false,
    fontFamily: '',
    fontSize: '',
    foreground: '',
    background: '',
    timestamp: undefined,
	timeout: 1000, // 1000 = one second, 60000 = one minute
	daysabbr : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
	days : ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
	monthsabbr : ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
	months  : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
	ampm : ["am", "pm", "AM", "PM"]
  };
 
})(jQuery);

