var selected_days = [];
var cached_days = [];
calendarDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
calendarMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];

/* The price calculation function (shouldn't this be from PHP?) */
function calculate_price(type_of_break){
  if(typeof(type_of_break) != 'undefined'){
    price = -1;
    /* try to optain data from PHP config, which is passed using booking_prices variable */
    if(typeof booking_prices != 'undefined' && typeof booking_prices[type_of_break] != 'undefined' && typeof booking_prices[type_of_break]['price'] != 'undefined') {
      price = myParseInt(booking_prices[type_of_break]['price']);
    }
    if(price == -1) {
      if(type_of_break == '2')
        price = 420;
      if(type_of_break == '3')
        price = 610;
      if(type_of_break == 'week')
        price = 1150;
      if(type_of_break == 'weekend')
        price = 799;
      if(type_of_break == 'holiday_weekend')
        price = 975;
      if(type_of_break == 'season_week')
        price = 1250;
    }
    $('#price_info').html('<h2>Final price: &euro;'+price+'.00</h2>');
    $('input[name="price"]').val(price);
  }
}

(function ($) {$(document).ready(function () {
  //we need to start the datepicker
  $booking_container = $('#bookingCover');
  if($booking_container.length > 0) {
    InitializeBooking();
  }
  function InitializeBooking(params){
    var params = typeof(params) != 'undefined' ? params : '';
    $booking_container.fadeOut("fast", function(){
      var result = '';
      $.ajax({
        type: "GET",
        url: "site/ajax/booking.php?ajax=1",
        data: params,
        async: false,
        dataType: "html",
        success: function(response){
          result = response;
        },
        error: function(xhr, desc, exception){ result = 'An error occurred while getting the calendar..'; }
      });

      $booking_container.html(result).fadeIn("fast", function() {
        var $booking_container = $('#bookingCover');
        if(true || $booking_container.attr('class') != 'step_3'){
          $('select#type_of_break').change(function () {
            last_day = '';
            for(i in selected_days) {
              if(/^([0-9]+)$/.test(""+i) && typeof selected_days[i] == 'string') {
                last_day = selected_days[i];
              }
            }
            if(last_day.length > 0) {
              d = last_day.split('-');
              cached_days.suggested_days = suggest_days(selected_days, d[0], d[1], d[2]);
            }
            $("#calendarCover").datepicker("refresh");
          });
          /* we should pass the first selected day to the datepicker (step > 1) */
          first_day = null;
          for(i in selected_days) {
            if(/^([0-9]+)$/.test(""+i) && typeof selected_days[i] == 'string') {
              first_day = selected_days[i];
              break;
            }
          }
          $("#calendarCover").datepicker({nextText: '>', prevText: '&lt;', defaultDate: first_day, dayNamesMin: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], monthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], dateFormat: 'yy-mm-dd', beforeShowDay: function (date) {
            /* painting new cell */
            is_disabled = true;
            if(ereg = /step=([0-9]+)/.exec(params)) {
              if (ereg[1] > 1)
                is_disabled = false;
            }
            className = "";
            tooltip = "";
            text_date = date.getFullYear()+"-"+(date.getMonth()+1 < 10 ? "0"+(date.getMonth()+1) : date.getMonth()+1)+"-"+(date.getDate() < 10 ? "0"+date.getDate() : date.getDate());
            t = 0;

            /* is this cell selected? */
            if($.inArray(text_date, selected_days) != -1) {
              className += " selected-day";
            }

            /**
              * cached_days:
              *   0: Bank holiday
              *   1: Booked days
              *   2: High season days
              *   3: Days before today
              *   4: Suggested days (may not exist)
             */
            for(i in cached_days){
              if (typeof i == 'string' && typeof cached_days[i].length != "undefined") {
                opts = cached_days[i];
                if($.inArray(text_date, opts) != -1) {
                  text = "";
                  t = 4;
                  if(i == 'booked_days') t = 0;
                  if(i == 'bank_holidays_days') t = 1;
                  if(i == 'seasons') t = 2;
                  if(i == 'before_today') t = 3;
                  /* add propper class names */
                  if(t==0) {
                    className += ' date-used';
                    is_disabled = true;
                    text = 'Date allready used';
                  } else if (t==2) {
                    className += ' high-season';
                    text = 'In high season';
                  } else if (t==3) {
                    is_disabled = true;
                    className += ' before_current_day';
                  } else if (t==4) {
                    className += ' suggested';
                    text = 'Suggested day';
                  } else {
                    className += ' bank-holidays';
                    text = 'Bank holiday';
                  }
                  if(text.length > 0 && ("\n"+tooltip+"\n").indexOf("\n"+text+"\n") == -1) {
                    tooltip += (tooltip.length > 0 ? "\n" : '') + text;
                  }
                }
                t++;
              }
            }
            return [is_disabled, $.trim(className), tooltip];
          }, onChangeMonthYear: function (year, month) {

            /* month changed, load new data */
            $.get('visual_bookings.php', {ajax: 'json', getData: 1, months: 1, start_month: year+"-"+month+"-01"}, function (tjson) {
              cached_days = tjson;
              fill_calendar(tjson.booked_days, tjson.bank_holidays_days, tjson.seasons, tjson.before_today);
            }, 'json')
          }, onSelect: function (dateText, params) {

            /** prepare current date **/
            m = (params.selectedMonth+1);
            d = params.selectedDay;
            if(m < 10) m = "0"+m;
            if(d < 10) d = "0"+d;
            cur_date = params.selectedYear+'-'+m+'-'+d;

            /* is this date in the array allready? */
            is_adding = $.inArray(cur_date, selected_days) == -1;

            if($.inArray(cur_date, cached_days.before_today||[]) != -1) {
              // the day is before today
              return false;
            }

            /* count the selected dates */
            count_selected_days = 0;
            for(i in selected_days) {
              if(/^([0-9]+)$/.test(""+i) && typeof selected_days[i] == 'string') {
                count_selected_days++;
              }
            }

            /* check the selection */
            selected_type = $('select[name=type_of_break]').val();
            if((ret = check_day_validity(cur_date, count_selected_days, is_adding, selected_type, selected_days, false)).length > 0) {
              if(typeof ret != 'boolean' || ret.length > 0) {
                /* we have got an error, show the message */
                alert(ret.join("\n"));
                return false;
              }
            }

            /* add or remove the date from selection */
            if((pos = $.inArray(cur_date, selected_days)) == -1) {
              selected_days.push(cur_date);
            } else {
              delete selected_days[pos];
            }
            selected_days.sort();
            update_calendar_text();
            cached_days.suggested_days = suggest_days(selected_days, params.selectedYear, params.selectedMonth, params.selectedDay);

            /* count the selected dates */
            count_selected_days = 0;
            for(i in selected_days) {
              if(/^([0-9]+)$/.test(""+i) && typeof selected_days[i] == 'string') {
                count_selected_days++;
              }
            }

            /* check whether we can confirm the order */
            errors = check_day_validity(cur_date, count_selected_days, false, selected_type, selected_days, true);
            if(errors.length == 0) {
              $('a#booking_next').slideDown('slow');
            } else {
              $('a#booking_next').slideUp('slow');
            }

            // check_day_validity(date, count_selected_days, is_adding, type, allready_selected_days, is_submit)
            calculate_price(selected_type);
            // update the form data
            $('input#selected_days_input').val(selected_days.join('|'));
            return true;
          }});
        } //!step_3
        $.get('visual_bookings.php', {ajax: 'json', months: 1, getData: 1}, function (tjson) {
          /* load the main data */
          cached_days = tjson;
          fill_calendar(tjson.booked_days, tjson.bank_holidays_days, tjson.seasons, tjson.before_today);
        }, 'json');
        update_calendar_text();
        if(params != '')
          window.scrollTo(0, document.getElementById('booking_box').offsetTop + document.getElementById('middleCover').offsetTop);
        sliding_panels_init();

        /* show the next button if possible */
        if($('input#selected_days_input').length > 0){
          if($('input#selected_days_input').val().split('|').length > 1){
            $('#booking_next').slideDown("fast");
          }else{
            $('#booking_next').slideUp("fast");
          }
        }
        $('.booking_go_to').unbind('click');
        $('.booking_go_to').click(function(){
          step = $(this).attr('rel');
          if(step.indexOf('step_') >= 0){
            step = step.replace('step_', '');
            params = 'step='+step;
            $booking_container.attr('class', 'step_'+step);
            InitializeBooking(params);
          }
          return false;
        });
        /* recalculate the price */
        calculate_price($('select[name=type_of_break]').val());

        /* change the step */
        $('#booking_next, #booking_prev').unbind('click');
        $('#booking_next, #booking_prev').click(function(){
          if($(this).is('#booking_next'))
            /* count the selected dates */
            count_selected_days = 0;
            for(i in selected_days) {
              if(/^([0-9]+)$/.test(""+i) && typeof selected_days[i] == 'string') {
                count_selected_days++;
              }
            }
            if((out = check_day_validity('', count_selected_days, false, $('select[name=type_of_break]').val(), selected_days, true)).length != 0) {
              return false;
            }

            var params = '';
          $('form#booking_form').find("input:hidden, :text, :checked, :password, :selected, textarea")
          .each(function() {
            if($(this).attr('name'))
              params += $(this).attr('name')+'='+$(this).val()+'&';
            else if($(this).parent().attr('name'))
              params += $(this).parent().attr('name')+'='+$(this).val()+'&';
          });
          // !!! UPDATE when next step is added
          if($(this).attr('id') == 'booking_prev'){
            params = params.replace(/step=2/g, 'step=1');
            if(params.indexOf('step=3') >= 0){
              params = params.replace(/step=3/g, 'step=2');
              params = params.replace(/form_sent=yes/g, '');
            }
          }
          if($(this).attr('id') == 'booking_next'){
            params = params.replace(/step=3/g, 'step=4');
            params = params.replace(/step=1/g, 'step=2');
          }
          find_step = 'step=';
          step_pos = params.indexOf(find_step);
          step = params.substr(step_pos + find_step.length, 1);
          $booking_container.attr('class', 'step_'+step);
          InitializeBooking(params);
          return false;
        });
      });
    });
  }
})}) (jQuery);
function suggest_days(current_days, year, month, day) {

  // now lets try to add other days after this date
  date = new Date(year, month, day);
  count_selected_days = 0;
  selected = [];

  /* count the selected dates */
  for(i in current_days) {
    if(/^([0-9]+)$/.test(""+i) && typeof current_days[i] == 'string') {
      count_selected_days++;
      last_day = current_days[i];
      selected[selected.length] = current_days[i];
    }
  }
  /* We need to calculate this from the last date */
  if(last_day != '') {
    d = last_day.split('-');
    year = d[0]; month = d[1]; day = d[2];
    suggest_date = new Date(year, month-1, day);
  }
  current_date = new Date(suggest_date.getTime());
  selected_type = $('select[name=type_of_break]').val()
  last_day = '';
  $('#calendarCover td.suggested').removeClass('suggested');
  suggested_days = [];
  suggest_i = 0;
  way = 1;
  if(count_selected_days > 0) {
    while(true) {
      current_date.setDate(current_date.getDate() + way);
      curr_date_text = current_date.getFullYear()+"-"+(current_date.getMonth()+1 < 10 ? "0" + (current_date.getMonth()+1) : current_date.getMonth()+1)+"-"+(current_date.getDate() < 10 ? "0" + current_date.getDate() : current_date.getDate());
      if($.inArray(curr_date_text, suggest_days) != -1 || $.inArray(curr_date_text, selected_days) != -1)
        continue;
      errors = check_day_validity(curr_date_text, count_selected_days, true, selected_type, selected, suggest_i > 0 ? way : false, true);
      if(errors.length == 0) {

        /* we can suggest this cell as the user can add it */
        suggested_days[suggested_days.length] = curr_date_text;
        selected[selected.length] = curr_date_text;
      } else {
        if(way == 1) {

          /* ok, this is the last on this end, try the second one */
          way = -1;
          suggest_i = 0;
          current_date = suggest_date;
          continue;

        } else if(way == -1) {

          /* user cannot select any more, do not go any further */
          break;
        }
      }
      count_selected_days++;
      suggest_i ++;
    }
  }
  return suggested_days;
}
function update_calendar_text() {
  cont = $('div#selected_days_info');
  j = 0;
  /* gather the first and last day */
  first_day = last_day = ''
  for(i in selected_days) {
    if(j == 0) {
      first_day = selected_days[i];
    }
    last_day = selected_days[i];
    j++;
  }
  if(j < 2) {
    last_day = '';
    if(j < 1)
      first_day = '';
  }
  /* write propper message */
  if(typeof first_day != 'undefined' && (first_day.length > 0) && typeof last_day != 'undefined' && (last_day.length > 0)){
    d = first_day.split('-');
    date_from = new Date(d[0], d[1]-1, d[2]);
    d = last_day.split('-');
    date_to = new Date(d[0], d[1]-1, d[2]);
    info_html = "<p>You have selected the following nights:<br />From "+calendarDays[date_from.getDay()] + " " + date_from.getDate() + getSufix(date_from.getDate());
    if(date_from.getMonth() != date_to.getMonth())
      info_html += " "+calendarMonths[date_from.getMonth()];
    info_html += " to "+calendarDays[date_to.getDay()] + " " + date_to.getDate() + getSufix(date_to.getDate())+" "+calendarMonths[date_to.getMonth()];
    info_html += "</p>";
  } else if(typeof first_day != 'undefined' &&(first_day.length > 0) && (typeof last_day == 'undefined' || (last_day.length == 0))){
    d = first_day.split('-');
    date_from = new Date(d[0], d[1], d[2]);
    info_html = "<p>You have selected the following nights:<br />From "+calendarDays[date_from.getDay()] + " " + date_from.getDate() + getSufix(date_from.getDate());
    info_html += " "+calendarMonths[date_from.getMonth()];
    info_html += "</p>";
  } else {
    info_html = "<p>Please select your preferred nights.</p>";
  }
  cont.html(info_html);
}
function getSufix(num) {
  sufix = '';
  last_char = (""+num).substring((""+num).length - 1);
  tens = '0';
  if(num >= 10)
    tens = myParseInt((""+num).substring((""+num).length - 2));
  if(tens <= 13 && tens >= 10)  { sufix = 'th'; }
  else {
    if(last_char >= 4)          { sufix = 'th'; }
    else if (last_char == 3)    { sufix = 'rd'; }
    else if (last_char == 2)    { sufix = 'nd'; }
    else if (last_char == 1)    { sufix = 'st'; }
    else if (num != 0)          { sufix = 'th'; }
  }
  return sufix;
}
function fill_calendar() {
  args=arguments;
  // now lets find the cells
  $('table.ui-datepicker-calendar td').removeClass('date-used').removeClass('high-season').removeClass('before_current_day').removeClass('bank-holidays')
  for(i=0;i<args.length;i++){
    opts = args[i];
    for(j=0;j<opts.length;j++) {
      cells = $('td.ui-date-'+opts[j]+':not(.ui-datepicker-other-month)');
      if(cells.length > 0) {
        text = '';
        if(i==0) {
          cells.addClass('date-used');
          text = 'Date allready used';
        } else if (i==2) {
          cells.addClass('high-season');
          text = 'In high season';
        } else if (i==3) {
          cells.addClass('before_current_day');
        } else {
          cells.addClass('bank-holidays');
          text = 'Bank holiday';
        }
        if(("\n"+cells.attr('title')+"\n").indexOf("\n"+text+"\n") == -1) {
          cells.attr('title', (cells.attr('title').length > 0 ? cells.attr('title') + "\n" : '') + text);
        }
      }
    }
  }
  $('td.selected-day').removeClass('selected-day');
  for(i = 0; i< selected_days.length; i++) {
    $('.ui-date-'+selected_days[i]).addClass('selected-day');
  }
}
function check_day_validity(date, count_selected_days, is_adding, type, allready_selected_days, is_submit, is_suggesting) {
  out = [];
  d=date.split('-');
  date_obj = new Date(d[0], myParseInt(d[1]) - 1, d[2]);
  weekday = date_obj.getDay();
  is_more = false;
  if(is_suggesting) {
    is_more = is_submit;
    is_submit = false;
  }

  has_before = null;
  has_after = null;
  /* chech whether the date has neighbor */
  if(!is_submit) {
    /* check whether the date has neighbor */
    /* only valid question when we are not about to sumit the form */
    has_neighbor = 0;

    /* check if currently selected day is preceeding first one */
    before_d = myParseInt(d[2]) - 1; before_m = myParseInt(d[1]); before_y = myParseInt(d[0]);
    if(before_d <= 0) { before_d = ($.inArray(before_m-1, [1,3,5,7,8,10,12]) != -1 ? 31 : before_m-1 != 2 ? 30 : before_y % 4 == 0 ? 29 : 28) + before_d; before_m -= 1; }
    if(before_m <= 0) { before_m = 12 + before_m; before_y -= 1; }
    if(before_d < 10) before_d = "0"+myParseInt(before_d);
    if(before_m < 10) before_m = "0"+myParseInt(before_m);
    before_day = before_y + '-' + before_m + '-' + before_d;
    if($.inArray(before_day, allready_selected_days) != -1) {
      has_neighbor++;
      has_before = true;
    } else {
      has_before = false;
    }

    /* check if currently selected day is folowing last one */
    after_d = myParseInt(d[2])+1; after_m = myParseInt(d[1]); after_y = myParseInt(d[0]);
    if(after_d <= 0) { after_d = 1 + (after_d - ($.inArray(after_m, [1,3,5,7,8,10,12]) != -1 ? 31 : after_m-1 != 2 ? 30 : after_y % 4 == 0 ? 29 : 28)); after_m += 1; }
    if(after_m <= 0) { after_m = 12 + after_m; after_y += 1; }
    if(after_d < 10) after_d = "0"+myParseInt(after_d);
    if(after_m < 10) after_m = "0"+myParseInt(after_m);
    after_day = after_y + '-' + after_m + '-' + after_d;
    if($.inArray(after_day, allready_selected_days) != -1) {
      has_neighbor++;
      has_after = true;
    } else {
      has_after = false;
    }

    /* check whether the date is folowing the selection */
    if(has_neighbor == 0 && is_adding && count_selected_days > 0) {

      /* the date is separated from others, deny */
      out[out.length] = 'Selected nights must be in row.';
    } else if(!is_adding && has_neighbor == 2) {

      /* the date is beeing removed from middle if the selection, deny */
      out[out.length] = 'Selected nights must be in row.';
    }
  }

  force_season_check = false; // request checking of season days
  require_season = 0; // whether the days have to 0: not be season, 1: be season
  /* set up the comparing */
  allow_bank_holiday = false;
  allow_first_day = allow_weekdays = [];
  if(myParseInt(type) != 0 && !isNaN(myParseInt(type))) {
    allow_weekdays = [1,2,3,4];
    allow_first_day = [1,2];
    force_season_check=true;
    max_days = 3;
    if(myParseInt(type) == 2) {
      allow_first_day = [1,2,3];
      max_days = 2;
    }
  }
  if(type == 'week') {
    force_season_check = true;
    allow_bank_holiday = true;
    force_season_check=true;
    max_days = 7;
    if(is_more > 0 && max_days && (weekday == 6 || weekday == 1)) {
      out[out.length] = 'Suggestion end';
    }
  } else if (type == 'weekend') {
    allow_first_day = [5];
    allow_weekdays = [5,6];
    force_season_check=true;
    max_days = 2;
  } else if (type == 'holiday_weekend') {
    allow_weekdays = [0,5,6];
    allow_bank_holiday = true;
    force_season_check=true;
    if(weekday == 1 && $.inArray(date, cached_days.bank_holidays_days) == -1) {
      out[out.length] = 'Monday should be bank holiday or change type of break';
    }
    max_days = 3;
  } else if (type == 'season_week') {
    force_season_check = true;
    require_season = 1;
    allow_first_day = [6];
    allow_bank_holiday = true;
    max_days = 7;
    if(date.length > 0 && !is_submit) {
      if(out.length == 0 && count_selected_days == 0) {
        if(is_adding && !is_submit && !is_suggesting && date_obj.getDay() == 6) {
          /* we want to select whole suggestion */
          suggested_dates = suggest_days([date], date_obj.getFullYear(), date_obj.getMonth(), date_obj.getDate());
          out = [];
          selected_days = suggested_dates;
        }
      }
    }
  }

  /* check if inserted day is high season */
  if(is_adding && force_season_check == 1) {
    if(require_season == 1 && $.inArray(date, cached_days.seasons) == -1) {
      out[out.length] = 'Only high season days allowed for current type of break';
    }
    if(require_season != 1 && $.inArray(date, cached_days.seasons) != -1) {
      out[out.length] = 'High season days are not allowed for current type of break';
    }
  }

  /* check date count */
  number = max_days == 1 ? 'one' : (max_days == 2 ? 'two' : (max_days == 3 ? 'three' : (max_days == 4 ? 'four' : (max_days == 5 ? 'five' : (max_days == 6 ? 'six' : (max_days == 7 ? 'seven' : (max_days)))))));
  //if(!is_suggesting) {
    if(count_selected_days >= max_days && is_adding) {
      out[out.length] = 'Please pick only '+number+' nights you want to book.';
    } else if (count_selected_days < max_days && is_submit) {
      out[out.length] = 'Please pick '+number+' nights you want to book or change your type of break.';
    }
  //}

  /* check the start day */
  if(is_submit) {
    second_day = '';
    j = 0;
    for(i in allready_selected_days) {
      if(j == 0) {
        first_day = allready_selected_days[i];
      }
      last_day = allready_selected_days[i];
      j++;
    }
    if(second_day.length > 0) {
      d = first_day.split('-');
      date_obj = new Date(d[0], myParseInt(d[1]) - 1, d[2]);
      if($.inArray(date_obj.getDay(), allow_first_day) == -1){
        start_days = [];
        for(i in calendarDays) {
          for(j in allow_first_day) {
            if(i == allow_first_day[j]) {
              start_days[start_days.length] = calendarDays[i];
            }
          }
        }
        out[out.length] = 'Starting day can be one of '+(start_days.join(', '));
      }
    }
  }
  if($.inArray(date, cached_days.booked_days) != -1) {
    out[out.length] = 'This day is allready booked';
  }
  if($.inArray(date, cached_days.before_today) != -1) {
    out[out.length] = 'This day is in the past';
  }
  if(is_suggesting && allow_first_day.length == 1) {
    /* we should stop when we reach selected start_day if there is only one start day */
    if(way == 1 && $.inArray(weekday, allow_first_day) != -1 || way == -1 && $.inArray((weekday+1)%7, allow_first_day) != -1) {
      out[out.length] = 'This date is the start one';
    }
  }

  /* bank holiday */
  if(!is_submit && is_adding && !allow_bank_holiday) {
    if($.inArray(date, cached_days.bank_holidays_days) != -1) {
      out[out.length] = 'You are not allowed to pick bank holiday with your chosen type of break.';
    }
  }

  /* allowed weekdays */
  if(!is_submit && is_adding && allow_weekdays.length > 0) {
    weekday = date_obj.getDay();
    if($.inArray(weekday, allow_weekdays) == -1) {
      out[out.length] = 'You are not allowed to pick '+calendarDays[weekday]+' with your chosen type of break.';
    }
  }
  return out;
}
function myParseInt(num) {
  if(typeof num == 'string')
    return parseInt(num.replace(/^0+/g, ''));
  return parseInt(num);
}
