//====================================================
/***
// PASTE INTO HEAD:
<script type="text/javascript" src="includes/ajax/needitfast.js" >< /script>
//
// EXAMPLE:
//    <span id="fred" class="needitfast" ></span>
//
***/
//====================================================
(function ($) {

$.fn.needitfast = function(settings){

    var m = jQuery.extend(
        {
        id                 : 'needitfast',
        container          : this,
        title              : 'Need It Fast?',
        title_desc         : 'Order within:',
        needitfast_text    : 'For delivery on: ',
        saturday_delivery  : false,
        saturday_working   : false,
        show_date          : 'delivery',
        set_hours          : 14,
        set_minutes        : 0,
        set_seconds        : 0,
        add_dates          : "",
        add_zeros          : true,
        message            : "Too Late For Next Delivery",
        date_format        : 'dddd dth',
        latest_text        : '', // Today
        delivery_text      : '', // Tomorrow
        guid               : parseInt(Math.random()*1000000)
        }, 
        settings || {}
    );
    
    function sync_attr(name){
        if (undefined == m.container.attr(name)) return; // nothing to set
        if (''        == m.container.attr(name)) return; // nothing to set
        if(m[name]    == m.container.attr(name)) return; // already created
        if ('saturday_working' == name) {
            m[name] = ('false' == m.container.attr(name)) ? false : true;
            return;
        }
        if ('*' == m.container.attr(name)){
            m[name] = '';
        } else {
            m[name] = m.container.attr(name);
        }
        
    }
    
    function init(){
        m.container = $('#'+m.id);
        sync_attr('title');
        sync_attr('title_desc');
        sync_attr('needitfast_text');
        sync_attr('set_hours');
        sync_attr('set_minutes');
        sync_attr('set_seconds');
        sync_attr('add_dates');
        sync_attr('add_zeros');
        sync_attr('message');
        sync_attr('date_format');
        sync_attr('saturday_delivery');
        sync_attr('saturday_working');
        sync_attr('show_date');

        m.holidays = setup_holidays();
        add_dates(m.holidays);
        m.holidays.sort(sortDate);

        var x = '';
        if ('' != m.title){
            x = '<span class="needitfast_title"     id="needitfast_title'     +m.guid+'" >'+m.title     +'</span>';
        }
        if ('' != m.title_desc){
            x += '<span class="needitfast_title_desc" id="needitfast_title_desc'+m.guid+'" >'+m.title_desc+'</span>';
        }
                
        var y = '<table>'+
                '<tr>'+
                '<td class="needitfast_hrs" id="needitfast_hrs'+m.guid+'" >00</td>'+
                '<td class="needitfast_min" id="needitfast_min'+m.guid+'" >00</td>'+
                '<td class="needitfast_sec" id="needitfast_sec'+m.guid+'" >00</td>'+
                '</tr>'+
                '</table>';
        var z = '<span class="needitfast_text" id="needitfast_text'+m.guid+'">'+m.needitfast_text+'</span>'+
                '<span class="needitfast_countdown" id="needitfast_countdown'+m.guid+'"></span>';
        m.container.html(x+y+z);
        
        var now      = new Date();
        var latest   = new Date();

        var delivery_text = m.delivery_text; //'Tomorrow';
        var latest_text   = m.latest_text;   // 'Today';
        
        latest.setHours(  m.set_hours  );
        latest.setMinutes(m.set_minutes);
        latest.setSeconds(m.set_seconds);
        
        if (now  > latest) {
            latest.setDate(latest.getDate()+1);
            latest_text = m.delivery_text; //'Tomorrow';
        }
        while(is_weekend(latest, m.saturday_working)){
            latest.setDate(latest.getDate()+1);
            latest_text   = '';
            delivery_text = '';
        }

        var delivery = new Date( latest.getTime()+24*60*60*1000 );
        delivery.setHours(          12  );
        delivery.setMinutes(        00  );
        delivery.setSeconds(        00  );
        delivery.setMilliseconds(   00  );

        while(is_weekend(delivery, m.saturday_delivery)){
            delivery.setDate(delivery.getDate()+1);
            delivery_text = '';
        }
        
        switch(m.show_date){
        case 'despatch':
            if ('' == latest_text) {
                $("#needitfast_countdown"+m.guid).html( date_format(latest) );
            } else {
                $("#needitfast_countdown"+m.guid).html( date_format(latest, latest_text) );
            }
            
            break;
        default:
            if ('' == delivery_text) {
                $("#needitfast_countdown"+m.guid).html( date_format(delivery) );
            } else {
                $("#needitfast_countdown"+m.guid).html( date_format(delivery, delivery_text) );
            }
            
        }


        //Creates a timer with an overriden tick event
        $("#needitfast_countdown"+m.guid).countdown({
            addZeros : m.add_zeros,
            message  : m.message, //"Too Late For Next Delivery",
            date     : latest,    //"2008/12/10 14:00:00",
            delayStart:false,
            
            onTick:function(control, day, hrs, min, sec) {
              hrs = hrs+(day*24);
              if(m.add_zeros){
                  if('' == hrs) hrs = '00';
              }
              if (  ('' != hrs) && ('' == min)  ) min = '00';
              if('' == sec){sec = '00';}
              
              $('#needitfast_hrs'+m.guid).html(hrs);
              $('#needitfast_min'+m.guid).html(min);
              $('#needitfast_sec'+m.guid).html(sec);
              
              return false;
            }
            
        });

    }
  //-------------------------------------
  function is_weekend(d, saturday_working){
      switch( d.getDay() ){
      case 0:
          return true;
      case 6:
          if ( ! saturday_working) return true; // 
      default:
          // SKIP;
      }

      var dt = new Date(d.getFullYear(), d.getMonth(), d.getDate());
      for(var i = 0; i < m.holidays.length; i++){
          if(m.holidays[i]  > dt) return false;
          if(m.holidays[i].valueOf() == dt.valueOf()) return true;
      }
      return false;
  }
  //-------------------------------------
  function setup_holidays(){
    var result  = new Array();
    var dow     = 0;
    var holiday = new Date();
    
    holiday = new Date(holiday.getFullYear(), 00, 01);
    result.push(  holiday  ); // new years day
  
    holiday = new Date(holiday.getFullYear(), 00, 02);
    result.push(  holiday  ); // new years day 2012
  
    holiday = new Date(holiday.getFullYear(), 02, 01);
    holiday.setDate(  holiday.getDate()+jrsEaster( holiday.getFullYear() )  );
    result.push(  holiday  ); // easter monday
  
    holiday = new Date(holiday.getFullYear(), holiday.getMonth(), holiday.getDate());
    holiday.setDate(  holiday.getDate()-3  );
    result.push(  holiday  ); // good friday
  
    holiday = new Date(holiday.getFullYear(), 04, 01);
    dow = holiday.getDay();
    holiday.setDate(  holiday.getDate()+((8-dow)%7)  );
    result.push(  holiday  );// may day
  
    holiday = new Date(holiday.getFullYear(), 04, 25);
    dow = holiday.getDay();
    holiday.setDate(  holiday.getDate()+((8-dow)%7)  );
    result.push(holiday);// last mon in may 
  
    holiday = new Date(holiday.getFullYear(), 07, 25);
    dow = holiday.getDay();
    holiday.setDate(holiday.getDate()+((8-dow)%7));
    result.push(  holiday  );  // august bank holiday
    
    holiday = new Date(holiday.getFullYear(), 11, 25);
    result.push(  holiday  );// christmass day 
  
    holiday = new Date(holiday.getFullYear(), 11, 26);
    result.push(  holiday  ); // boxing day
  
    holiday = new Date(holiday.getFullYear(), 11, 27);
    result.push(  holiday  ); // 2010
    holiday = new Date(holiday.getFullYear(), 11, 28);
    result.push(  holiday  ); // 2010
  
    holiday = new Date(holiday.getFullYear()+1, 00, 01);
    result.push(  holiday  ); // next year new years day
    
    holiday = new Date(2011, 03, 29);
    result.push(  holiday  ); // Royal Wedding
    return result;
  
  }
  //-------------------------------------
  function jrsEaster(YR) { // Fast JRSEaster, unsigned 32-bit year
    //     JAVASCRIPT INCLUDE FILE - (c) J R Stockton  >= 2009-04-19
    //             http://www.merlyn.demon.co.uk/estr-inc.js
    //                  Easter Routines, except Zeller
    //                See estrcalc.htm and estr-bcp.htm
    //       Routines may be copied, but URL must not be linked to.
    //                 Uses Div & Mod from include1.js
    var gn, xx, cy, DM
    gn = YR % 19					// gn ~ GoldenNumber
    xx = (YR/100)|0
    cy = ((3*(xx+1)/4)|0) - (((13+xx*8)/25)|0)	// cy ~ BCPcypher
    xx = ( 6 + YR + ((YR/4)|0) - xx + ((YR/400)|0) ) % 7
    DM = 21 + (gn*19 + cy + 15)%30 ; DM -= ((gn>10) + DM > 49) // PFM
    return DM + 1 + (66-xx-DM)%7 /* Day-of-March */ 
  }
  //-------------------------------------
  function date_format( date, format ) {

    	var monthNames = [
           'January','February','March',
           'April',  'May',     'June',
    		   'July',   'August',  'September',
           'October','November','December']; // Names of months for drop-down and formatting
    	var dayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']; // For formatting

      //var format = m.date_format;

      if(undefined == format) return date.toLocaleDateString();
      if(null      == format) return date.toLocaleDateString();
      if(''        == format) format = m.date_format;
      if(''        == format) return date.toLocaleDateString();
      
      var yy  = date.getFullYear();
      var mm  = date.getMonth()+1;
      var dd  = date.getDate();
      
      var hr = date.getHours();
      var mn = date.getMinutes();
      var sc = date.getSeconds();
      
      var month_name = monthNames[mm-1];
      var dow        = date.getDay();
      var day_name   = dayNames[dow];
      
      var st = '';
      switch(String(dd).substr(-1)){
      case "1":
        st = (String(dd)=='11') ? 'th' : 'st';
        break;
      case "2":
        st = (String(dd)=='12') ? 'th' : 'nd';
        break;
      case "3":
        st = (String(dd)=='13') ? 'th' : 'rd';
        break;
      default:
        st = 'th';
      }

      var result = format;

      result = result.replace(/st/gi,   '\t');
      result = result.replace(/nd/gi,   '\t');
      result = result.replace(/rd/gi,   '\t');
      result = result.replace(/th/gi,   '\t');

      result = result.replace(/d{4,}/gi,  '\0');
      result = result.replace(/d{3,3}/gi, '\f');
      result = result.replace(/d{2,2}/gi, (dd>9)?dd:'0'+dd);
      result = result.replace(/d{1,1}/gi, dd);
      
      result = result.replace(/m{4,}/gi,  '\r');
      result = result.replace(/m{3,3}/gi, '\n');
      result = result.replace(/m{2,2}/gi, (mm>9)?mm:'0'+mm);
      result = result.replace(/m{1,1}/gi, mm);

      result = result.replace(/y{4,}/gi,   yy);
      result = result.replace(/y{3,3}/gi,  yy.toString().substr(1, 3));
      result = result.replace(/y{2,2}/gi,  yy.toString().substr(2, 2));
      result = result.replace(/y{1,1}/gi,  yy.toString().substr(3, 1));
      
      result = result.replace(/h{2,}/gi,   (hr>9)?hr:'0'+hr);
      result = result.replace(/h{1,}/gi,   hr);

      result = result.replace(/n{2,}/gi,   (mn>9)?mn:'0'+mn);
      result = result.replace(/n{1,}/gi,   mn);

      result = result.replace(/s{2,}/gi,   (sc>9)?sc:'0'+sc);
      result = result.replace(/s{1,}/gi,   sc);

      result = result.replace(/\0/gi,  day_name);
      result = result.replace(/\f/gi, day_name.substr(0, 3));

      result = result.replace(/\r/gi,  month_name);
      result = result.replace(/\n/gi,  month_name.substr(0, 3));

      result = result.replace(/\t/gi,   st);

      return result;

  }
  //-------------------------------------
  function add_dates(holidays){
      if('' == m.add_dates) return;
      
      var holiday = new Date();

      var tmp  = m.add_dates.split(' ');
      for( var i=0; i < tmp.length ; i++ ){
          if(  tmp[i].length != 8 ) continue;
          
          holiday = new Date(
              tmp[i].substr(0, 4),
              tmp[i].substr(4, 2)-1,
              tmp[i].substr(6, 2)
          );

          holidays.push(holiday);
      }

  }
  //-------------------------------------
  function sortDate(left, right) {
      return left.valueOf() - right.valueOf();
  }
  //-------------------------------------
  init();

  return m.container;
  //-------------------------------------
} // function

})(jQuery);

//====================================================
  
$(document).ready(function() {
    $('.needitfast').each( 
        function(dummy) {
            var set_hours   = 14;
            var set_minutes = 0;
            var set_seconds = 0;
            
            try{
                set_hours = this.attributes['set_hours'].value;
            } catch(err) {
                hour = 14;
            }

            try{
                set_minutes = this.attributes['set_minutes'].value;
            } catch(err) {
                set_minutes = 0;
            }

            try{
                set_seconds = this.attributes['set_seconds'].value;
            } catch(err) {
                set_seconds = 0;
            }

            try{
                add_dates = this.attributes['add_dates'].value;
            }catch(err){
                add_dates="";
            }

            try{
                latest_text = this.attributes['latest_text'].value;
            }catch(err){
                latest_text="";
            }

            try{
                delivery_text = this.attributes['delivery_text'].value;
            }catch(err){
                delivery_text="";
            }

            $('#'+this.id).needitfast( { id:this.id, add_dates:add_dates, set_hours:set_hours, set_minutes:set_minutes, set_seconds:set_seconds, delivery_text:delivery_text, latest_text:latest_text } );
        }
    );
} );

