
function set_cursor (c) {
  document.getElementsByTagName("body")[0].style.cursor=c;
}

function get_resource_url(res) {
    var resource_url = document.feedback_url ? (document.feedback_url + (document.feedback_url.indexOf('?') == -1 ? "?" : "&") + "resource_id="+res.id) : "about-resource.php?resource_id="+res.id;
    if (document.feedback_url && res.url)
        resource_url = res.url;
    if (document.current_language)
        resource_url = resource_url + (resource_url.indexOf('?') == -1 ? "?" : "&") + (document.feedback_url ? "lang" : "custom-language") + '=' + document.current_language;
    return resource_url;
}

function js_get_single_month_nav_code (month, year, is_first) {
  var day_info = planyo_get_day_info_for_month (month, year);
  var month_specs = planyo_get_month_specs (month, year);
  var res = document.resources [document.resource_id];
  var mark_arrival_days = document.start_day_restrictions_active;
  var prev_day_status = null;

  var div_code = "";
  if (is_first)
    div_code += "<a class='earlier' href='javascript:js_nav(\"prev\")'>&laquo;"+document.s_prev+"</a> &nbsp; <a class='later' href='javascript:js_nav(\"next\")'>"+document.s_next+"&raquo;</a><br/>";
  div_code += "<table class='calpicker' style='"+(is_first ? "" : "clear:none")+";float:left;margin-top:6px;margin-right:15px' cellpadding='0' cellspacing='0'><thead><tr class='days'><th colspan='7'>"+planyo_get_month_name(month)+' '+year+"</th></tr>\n<tr class='hours2'>";

  for (var d = 0; d <= 6; d++) {
    div_code += "<th>" + planyo_get_day_name (d, true) + "</th>";
  }
  div_code += "</tr></thead><tfoot></tfoot><tbody>";

  for (var y = 0; y < 6; y++) {
    div_code += "<tr>";
    for (var x = 0; x < 7; x++) {
      var year = day_info [y][x]['year'];
      var month = day_info [y][x]['month'];
      var day = day_info [y][x]['day'];
      var status_arr = js_get_period_status (year, month, day, 'ad', 'none', res, false);
      var status = status_arr [0];
      var start_day_status = status_arr [3];
      var div_type = day_info [y][x]['type'];
      var div_day = day;
      var onclick_code = '';
      if (document.is_night_icon_mode && !prev_day_status) {
        var prev_day = planyo_get_prev_day (day, month, year, 1);
        var prev_day_status = js_get_period_status (prev_day[2], prev_day[1], prev_day[0], 'ad', 'none', res, false);
      }

      if (document.empty_item_reserve_link && res.access_type != 3 && start_day_status != 2) {
          onclick_code = "onclick=\"" + (document.open_frame=='_blank' ? "window.open('" : (document.open_frame=='_top' ? "window.top.location.href='" : (document.open_frame=='_parent' ? "window.parent.location.href='" : "window.location.href='"))) + document.empty_item_reserve_link + (document.empty_item_reserve_link.indexOf('?') == -1 ? "?" : "&") + "prefill=true&" + "time_mode=full_day&one_date="+encodeURIComponent(planyo_output_date(year, month, day))+"&start_date="+encodeURIComponent(planyo_output_date(year, month, day)) + "&resource_id=" + res.id + (document.open_frame=='_blank' ? "')" : "'") + "\"";
      }
      if (status == resource_usage_full) {
	      div_day = "&times;";
	      div_type = "reserved";
	      onclick_code = "";
        if (document.is_night_icon_mode && prev_day_status && (prev_day_status[0] == resource_usage_none || prev_day_status[0] == null))
          div_type += " morning_av";
      }
      else if (status == resource_usage_vacation) {
        div_day = "&times;";
	      div_type = "reserved";
	      onclick_code = "";
      }
      else if (status == resource_usage_unknown) {
	      div_day = "&nbsp;&nbsp;";
      }
      else if (start_day_status == 2) {
        div_type += " no_start";
      }
      else if(mark_arrival_days) {
        div_type += " arrival_day";
      }
      if (document.is_night_icon_mode && prev_day_status && prev_day_status[0] == resource_usage_full && (status == resource_usage_none || status == null)) {
        div_type += " morning_occ";
      }
      div_code += "<td class='" + div_type + "' "+onclick_code+">";
      div_code += div_day;
      div_code += "</td>";
      if (document.is_night_icon_mode) {
        prev_day_status = status_arr;
      }
    }
    div_code += "</tr>";
  }
  div_code += "</tr>";
  div_code += "</tbody></table>";
  return div_code;
}

function js_show_calendar_nav (month, year) {
  if (!document.getElementById ('calendar_nav') || !document.resource_id)
    return;

  var now = new Date();
  if (month == null && year == null) {
    month = now.getMonth() + 1;
    year = now.getFullYear();
  }

  if (!document.nav_month_count)
    document.nav_month_count = 1;
  var div_code = '';
  for (var i = 0; i < document.nav_month_count; i++) {
    if (!planyo_isset (document.fetched_data, year, month)) {
      js_fetch_calendar_data (month, year);
      return '';
    }
    div_code += js_get_single_month_nav_code (month, year, i==0);
    var next_month = planyo_get_next_month (month, year);
    month = next_month [0];
    year = next_month [1];
  }
  document.getElementById ('calendar_nav').innerHTML = div_code;
}

function js_show_upcoming_hours(day, month, year, resource, granulation) {
  if (!document.getElementById ('horizontal_calendar') || document.active_view_mode != view_mode_day)
    return;
  if (!document.fetched_data [year] || !document.fetched_data [year][month]) {
    js_fetch_calendar_data (month, year);
    return;
  }
  if (!granulation)
    granulation = document.min_granulation;
  if (granulation > 60) {
    document.active_view_mode = view_mode_month;
    return js_show_upcoming_days(day, month, year, resource);
  }

  var now = new Date();
  if (day == null && month == null && year == null) {
    day = now.getDate();
    month = now.getMonth() + 1;
    year = now.getFullYear();
  }
  var first_hour = js_get_resources_min_max_hour('first_hour', true);
  var last_hour = js_get_resources_min_max_hour('last_hour', false);
  var cols_per_hour = 60 / granulation;
  var col_count = (last_hour - first_hour) * cols_per_hour;
  var day_count = 3;
  if (document.upcoming_day_count)
    day_count = document.upcoming_day_count;
  var this_day = new Array (day, month, year);
  var code = "<div class='upcoming'>";
  code += "<div class='av_nav'><a class='earlier' "+(year == now.getFullYear() && month == now.getMonth() + 1 && day == now.getDate() ? "style='display:none'" : "")+" href='javascript:js_nav(\"prev"+day_count+"\")'>&laquo;"+document.s_prev+"</a><a class='later' href='javascript:js_nav(\"next"+day_count+"\")'>"+document.s_next+"&raquo;</a></div>";
  var first_weekday = planyo_isset(document.first_weekday) ? document.first_weekday : 1;

  var resources = document.resources;
  for (var nd = 0; nd < day_count; nd++) {
    var js_date = new Date();
    js_date.setFullYear (this_day[2], this_day[1] - 1, this_day[0]);
    var day_name = planyo_get_day_name ((7 - first_weekday + js_date.getDay()) % 7, false);
    code += "<div class='av_day_group'><div class='av_date'>"+day_name+" "+planyo_output_date(this_day[2], this_day[1], this_day[0])+"</div>";
    var av_found = false;
	  for (var rr in document.sorted_resources) {
			var r = parseInt(document.sorted_resources [rr]['id']);
		if (!document.resources[r]) continue;				
      var resource_printed = resource ? true : false;
      var h = first_hour;
      var min = 0;
      var prev_av = document.resources[r].quantity;
      var prev_av_start = new Array(first_hour, 0);
      for (var c = 0; c <= col_count; c++) {
        if (c>0 && (c % cols_per_hour) == 0) {
          h++;min=0;
        }
        else if (c>0) {
          min+=granulation;
        }
        var status_arr = js_get_period_status (this_day[2], this_day[1], this_day[0], h, cols_per_hour == 1 ? 'none' : min, document.resources [r], true);
        var status = status_arr [0];
        var av = (status == resource_usage_partial ? status_arr[1] - status_arr[2] : document.resources[r].quantity);
        if (status == resource_usage_daily_full || status == resource_usage_vacation || status == resource_usage_full)
          av = 0;
        if (av != prev_av || c == col_count || document.no_range==1) {
          if (prev_av > 0 && (prev_av_start[0] != h || prev_av_start[1] != min)) {
            var onclick_code = "";
            if (document.empty_item_reserve_link)
                onclick_code = "onclick=\"" + (document.open_frame=='_blank' ? "window.open('" : (document.open_frame=='_top' ? "window.top.location.href='" : (document.open_frame=='_parent' ? "window.parent.location.href='" : "window.location.href='"))) + document.empty_item_reserve_link + (document.empty_item_reserve_link.indexOf('?') == -1 ? "?" : "&") + "prefill=true&" + (js_is_using_hour_granulation (document.resources[r]) ? "one_date="+encodeURIComponent(planyo_output_date(this_day[2], this_day[1], this_day[0]))+"&start_date="+encodeURIComponent(planyo_output_date(this_day[2], this_day[1], this_day[0]))+"&start_time="+prev_av_start[0]+"&end_time="+prev_av_start[0] : "time_mode=full_day&start_date="+encodeURIComponent(planyo_output_date(this_day[2], this_day[1], this_day[0]))) + "&resource_id=" + document.resources[r].id + (document.open_frame=='_blank' ? "')" : "'") + "\"";
            if (!resource_printed) {
              code += "<div class='av_res'>"+document.resources[r].name+"</div>";
              resource_printed = true;
            }
            av_found = true;
            code += "<div class='av_time' "+onclick_code+">"+planyo_output_time(prev_av_start[0], prev_av_start[1]);
            if (document.no_range != 1)
              code += " - "+planyo_output_time(h, min);
            if (document.resources[r].quantity > 1 && document.resources[r].quantity < 1000)
              code += " ("+prev_av+")";
            code += "</div>";
          }
          prev_av = av;
          prev_av_start = new Array(h, min);
        }
      }
    }
    if (!av_found)
      code += " "+document.s_unav;
    code += "</div>";
    this_day = planyo_get_next_day (this_day[0], this_day[1], this_day[2]);
  }

  code += "</div>";
  document.getElementById ('horizontal_calendar').innerHTML = code;
}

function js_show_week_grid (day, month, year, resource, granulation) {
  if (!document.getElementById ('horizontal_calendar') || document.active_view_mode != view_mode_day)
    return;
  if (!granulation)
    granulation = document.min_granulation;
  if (granulation > 60 || !resource) {
    document.active_view_mode = view_mode_month;
    return js_show_horizontal_calendar (day, month, year, resource);
  }
  if (granulation == 15 && document.mode_30_min)
    granulation = 30; // 30-min mode
  var now = new Date();
  if (day == null && month == null && year == null) {
    day = now.getDate();
    month = now.getMonth() + 1;
    year = now.getFullYear();
  }
  var first_hour = js_get_resources_min_max_hour('first_hour', true);
  var last_hour = js_get_resources_min_max_hour('last_hour', false);
  var cols_per_hour = 60 / granulation;
  var col_count = (last_hour - first_hour) * cols_per_hour;
  var is_reversed = (document.preview_style == preview_style_week_grid_2);
  var day_count = is_reversed ? 7 : document.days_in_grid;
  if (!day_count)
    day_count = 7;
  var month_specs = planyo_get_month_specs (month, year);
  var this_day = new Array (day, month, year);
  var code = "<table id='cal' cellpadding='0' cellspacing='0'><caption><a class='earlier' href='javascript:js_nav(\"prev"+day_count+"\")'>&laquo;"+document.s_prev+"</a><a class='later' href='javascript:js_nav(\"next"+day_count+"\")'>"+document.s_next+"&raquo;</a></caption><thead><tr class='hours'><th style='border:none'>"+(is_reversed ? document.s_weekday+"<br/>"+document.s_month+"<br/>"+document.s_day : "")+"</th>";

  if (!document.fetched_data [year] || !document.fetched_data [year][month]) {
    js_fetch_calendar_data (month, year);
    return;
  }

  if (is_reversed) {
    var day_iterator = (month_specs [0] + day - 1) % 7;
    var cur_day = this_day;
    for (var d = 0; d < day_count; d++) {
      if (!planyo_isset (document.resource_usage, cur_day[2], cur_day[1]) &&
          !planyo_isset (document.vacations, cur_day[2], cur_day[1])) {
        js_fetch_calendar_data (cur_day[1], cur_day[2]);
        break;
      }
      code += "<th>"+planyo_get_day_name(day_iterator, true) + "<br/>" + (cur_day[1] < 10 ? "0"+cur_day[1] : cur_day[1]) + "<br/>" + cur_day[0] +"<br/>"+"</th>";
      cur_day = planyo_get_next_day (cur_day[0], cur_day[1], cur_day[2]);
      day_iterator++;
      if (day_iterator == 7)
        day_iterator = 0;
    }
    code += "</tr></thead><tfoot></tfoot><tbody>";
    var h = first_hour;
    var min = 0;
    for (var c = 0; c < col_count; c++) {
      if (c>0 && (c % cols_per_hour) == 0) {
        h++;min=0;
      }
      else if (c>0) {
        min+=granulation;
      }

      if (!document.no_range || !planyo_isset (document.resource_start_times, document.resources [resource].id) || planyo_isset (document.resource_start_times, document.resources [resource].id, h+":"+((min && min != 'none') ? min : '00'))) {
        code += "<tr><td class='day'>"+planyo_output_time(h,min)+"</td>";
        day_iterator = (month_specs [0] + day - 1) % 7;
        cur_day = this_day;
        for (var d = 0; d < day_count; d++) {
          var hour_code = '';
          if (h < first_hour || h >= last_hour)
            hour_code = js_get_unavailable_cell_code();
          else
            hour_code = js_get_grouped_code (cur_day [2], cur_day [1], cur_day [0], h, cols_per_hour == 1 ? 'none' : min, document.resources [resource].id, item_code_long, true);
          code += hour_code;
          cur_day = planyo_get_next_day (cur_day[0], cur_day[1], cur_day[2]);
          day_iterator++;
          if (day_iterator == 7)
            day_iterator = 0;
        }
        code += "</tr>";
      }
    }
  }
  else {
    var second_row_code = (cols_per_hour == 1 ? "" : "<tr class='hours' style='color:#555555'><th></th>");
    var h = first_hour;
    var min = 0;
    for (var c = 0; c < col_count; c++) {
      if (c>0 && (c % cols_per_hour) == 0) {
        h++;min=0;
      }
      else if (c>0) {
        min+=granulation;
      }
      if (cols_per_hour > 1) {
        if (min==0) {
          code += "<th style='text-align:left;border:none' colspan='"+cols_per_hour+"'>"+planyo_output_hour_only(h,"h")+"</th>";
          second_row_code += "<th>" + "00" + "</th>";
        }
        else {
          second_row_code += "<th>" + min + "</th>";
        }
      }
      else {
        code += "<th>"+planyo_output_hour_only(h,"h")+"</th>";
      }
    }
    if (cols_per_hour > 1) code += "</tr>" + second_row_code;
    code += "</tr></thead><tfoot></tfoot><tbody>";
    
    var day_iterator = (month_specs [0] + day - 1) % 7;
    var cur_day = this_day;
    for (var d = 0; d < day_count; d++) {
      if (!planyo_isset (document.resource_usage, cur_day[2], cur_day[1]) &&
          !planyo_isset (document.vacations, cur_day[2], cur_day[1])) {
        js_fetch_calendar_data (cur_day[1], cur_day[2]);
        break;
      }
      code += "<tr><td class='day'>";
      code += planyo_get_day_name(day_iterator, false) + ", " + planyo_output_date(cur_day[2], cur_day[1], cur_day[0]);
      code += "</td>";
      var h = first_hour;
      var min = 0;
      for (var c = 0; c < col_count; c++) {
        if (c>0 && (c % cols_per_hour) == 0) {
          h++;min=0;
        }
        else if (c>0) {
          min+=granulation;
        }
        var hour_code = '';
        if (h < first_hour || h >= last_hour)
          hour_code = js_get_unavailable_cell_code();
        else
          hour_code = js_get_grouped_code (cur_day [2], cur_day [1], cur_day [0], h, cols_per_hour == 1 ? 'none' : min, document.resources [resource].id, item_code_long, true);
        code += hour_code;
      }
      code += "</tr>";
      cur_day = planyo_get_next_day (cur_day[0], cur_day[1], cur_day[2]);
      day_iterator++;
      if (day_iterator == 7)
        day_iterator = 0;
    }
  }
  code += "</tbody></table>";
  document.getElementById ('horizontal_calendar').innerHTML = code;
}

// if resource is null, all resources are displayed
function js_show_horizontal_day_view (day, month, year, resource, granulation, no_empty_hours) {
  if (!document.getElementById ('horizontal_calendar') || document.active_view_mode != view_mode_day)
    return;
  if (resource && (document.preview_style == preview_style_week_grid || document.preview_style == preview_style_week_grid_2))
    return js_show_week_grid(day, month, year, resource, granulation);
  if (document.is_mobile || document.preview_style == preview_style_upcoming)
    return js_show_upcoming_hours(day, month, year, resource, granulation);
  var now = new Date();
  if (day == null && month == null && year == null) {
    day = now.getDate();
    month = now.getMonth() + 1;
    year = now.getFullYear();
  }
  if (!granulation) {
    granulation = document.min_granulation;
    no_empty_hours = granulation < 60 || document.feedback_url;
  }
  if (granulation == 15 && document.mode_30_min)
    granulation = 30; // 30-min mode
  var first_hour = js_get_resources_min_max_hour('first_hour', true);
  var last_hour = js_get_resources_min_max_hour('last_hour', false);
  var cols_per_hour = 60 / granulation;
  var col_count = (no_empty_hours ? (last_hour - first_hour) : 24) * cols_per_hour;
  var day_count = (col_count <= 24 ? 2 : 1);
  var month_specs = planyo_get_month_specs (month, year);
  var day_iterator = (month_specs [0] + day - 1) % 7;
  var this_day = new Array (day, month, year);
  var next_day = planyo_get_next_day (day, month, year);
  var code = "<table id='cal' cellpadding='0' cellspacing='0'><caption><a class='earlier' href='javascript:js_nav(\"prev\")'>&laquo;"+document.s_prev+"</a><a class='later' href='javascript:js_nav(\"next\")'>"+document.s_next+"&raquo;</a>";
  code += "<a class='nav_today' href='javascript:js_nav(\"now\")'>"+document.s_today+"</a>";
  if (!document.non_switchable_cal_view)
    code += "<a class='switch_mode' href='javascript:js_nav(null,"+month+","+year+")'>"+document.s_month_view+"</a>";
  code += "</caption><thead><tr class='days'><th></th><th colspan='"+col_count+"'>"+planyo_get_day_name(day_iterator, false)+", "+day+" ";
  if (!document.non_switchable_cal_view)
    code += "<a href='javascript:js_nav(null,"+month+","+year+")'>";
  code += planyo_get_month_name(month)+' '+year;
  if (!document.non_switchable_cal_view)
    code += "</a>";
  code += "</th>";
  if (day_count == 2) {
    day_iterator++;
    if (day_iterator == 7)
      day_iterator = 0;
    code += "<th colspan='"+col_count+"'>"+planyo_get_day_name(day_iterator, false)+", "+next_day [0]+" ";
    if (!document.non_switchable_cal_view)
      code += "<a href='javascript:js_nav(null,"+next_day [1]+","+next_day [2]+")'>";
    code += planyo_get_month_name(next_day [1])+' '+next_day[2];
    if (!document.non_switchable_cal_view)
      code += "</a>";
    code += "</th>";
  }
  code += "</tr><tr class='hours'><th style='border:none'></th>";

  if (!document.fetched_data [year] || !document.fetched_data [year][month]) {
    js_fetch_calendar_data (month, year);
    return;
  }

  var second_row_code = (cols_per_hour == 1 ? "" : "<tr class='hours' style='color:#555555'><th></th>");
  for (var i = 0; i < day_count; i++) {
    var h = no_empty_hours ? first_hour : 0;
    var min = 0;
    for (var c = 0; c < col_count; c++) {
      if (c>0 && (c % cols_per_hour) == 0) {
	h++;min=0;
      }
      else if (c>0) {
	min+=granulation;
      }
      if (cols_per_hour > 1) {
	if (min==0) {
	  code += "<th style='text-align:left;border:none' colspan='"+cols_per_hour+"'>"+planyo_output_hour_only(h,"h")+"</th>";
	  second_row_code += "<th>" + "00" + "</th>";
	}
	else {
	  second_row_code += "<th>" + min + "</th>";
	}
      }
      else {
	code += "<th>"+planyo_output_hour_only(h)+"</th>";
      }
    }
  }
  if (cols_per_hour > 1) code += "</tr>" + second_row_code;
  code += "</tr></thead><tfoot></tfoot><tbody>";

  var resources = document.resources;
  for (var rr in document.sorted_resources) {
    var r = parseInt(document.sorted_resources [rr]['id']);
		if (!document.resources[r]) continue;				
    var resource_url = get_resource_url(document.resources[r]);
		if (document.empty_item_reserve_link)
      code += "<tr><td class='resource'><a href='"+resource_url+"'"+(document.open_frame ? " target='"+document.open_frame+"'" : "")+"><nobr>" + document.resources [r].name + "</nobr></a></td>";
    else
      code += "<tr><td><nobr>" + document.resources[r].name + "</nobr></td>";	
    for (var i = 0; i < day_count; i++) {
      var h = no_empty_hours ? first_hour : 0;
      var min = 0;
      for (var c = 0; c < col_count; c++) {
	if (c>0 && (c % cols_per_hour) == 0) {
	  h++;min=0;
	}
	else if (c>0) {
	  min+=granulation;
	}
	var cur_day = ((i == 1) ? next_day : this_day);
	var hour_code = '';
	if (h < first_hour || h >= last_hour)
	  hour_code = js_get_unavailable_cell_code();
	else
	  hour_code = js_get_grouped_code (cur_day [2], cur_day [1], cur_day [0], h, cols_per_hour == 1 ? 'none' : min, document.resources [r].id, item_code_long, true);
	code += hour_code;
      }
    }
    code += "</tr>";
  }
  code += "</tbody></table>";
  document.getElementById ('horizontal_calendar').innerHTML = code;
}

function js_show_upcoming_days(day, month, year, resource) {
  if (!document.getElementById ('horizontal_calendar'))
    return;
  if (!document.fetched_data [year] || !document.fetched_data [year][month]) {
    js_fetch_calendar_data (month, year);
    return;
  }

  var now = new Date();
  if (day == null && month == null && year == null) {
    day = now.getDate();
    month = now.getMonth() + 1;
    year = now.getFullYear();
  }
  else if (month != now.getMonth() + 1) {
    day = 1;
  }
  var code = "<div class='upcoming'>";
  code += "<div class='av_nav'><a class='earlier' "+(year == now.getFullYear() && month == now.getMonth() + 1 ? "style='display:none'" : "")+" href='javascript:js_nav(\"prev\")'>&laquo;"+document.s_prev+"</a><a class='later' href='javascript:js_nav(\"next\")'>"+document.s_next+"&raquo;</a><span class='av_month'>"+planyo_get_month_name(month, false)+" "+year+"</span></div>";

  code += "<div class='av_day_group'>";
  var av_found = false;
  var resources = document.resources;
  for (var rr in document.sorted_resources) {
    var r = parseInt(document.sorted_resources [rr]['id']);
		if (!document.resources[r]) continue;				
    var resource_printed = resource ? true : false;
    var prev_av = document.resources[r].quantity;
    var this_day = new Array (day, month, year);
    var prev_av_start = this_day;
    var yesterday = null;
    while (true) {
      var status_arr = js_get_period_status (this_day[2], this_day[1], this_day[0], 'ad', 'none', document.resources [r], true);
      var status = status_arr [0];
      var av = (status == resource_usage_partial ? status_arr[1] - status_arr[2] : document.resources[r].quantity);
      if (status == resource_usage_daily_full || status == resource_usage_vacation || status == resource_usage_full)
        av = 0;
      if (av != prev_av || this_day[1] != month || this_day[2] != year) {
        if (prev_av > 0 && (prev_av_start[0] != this_day[0] || prev_av_start[1] != this_day[1] || prev_av_start[2] != this_day[2])) {
          var onclick_code = "";
          if (document.empty_item_reserve_link)
              onclick_code = "onclick=\"" + (document.open_frame=='_blank' ? "window.open('" : (document.open_frame=='_top' ? "window.top.location.href='" : (document.open_frame=='_parent' ? "window.parent.location.href='" : "window.location.href='"))) + document.empty_item_reserve_link + (document.empty_item_reserve_link.indexOf('?') == -1 ? "?" : "&") + "prefill=true&" + "time_mode=full_day&start_date="+encodeURIComponent(planyo_output_date(prev_av_start[2], prev_av_start[1], prev_av_start[0])) + "&resource_id=" + document.resources[r].id + (document.open_frame=='_blank' ? "')" : "'") + "\"";
          if (!resource_printed) {
            code += "<div class='av_res'>"+document.resources[r].name+"</div>";
            resource_printed = true;
          }
          if (document.is_night)
            code += "<div class='av_time' "+onclick_code+">"+planyo_output_date(prev_av_start[2], prev_av_start[1], prev_av_start[0])+" - "+planyo_output_date(this_day[2], this_day[1], this_day[0]);
          else if (yesterday && (prev_av_start[0] != yesterday[0] || prev_av_start[1] != yesterday[1] || prev_av_start[2] != yesterday[2]))
            code += "<div class='av_time' "+onclick_code+">"+planyo_output_date(prev_av_start[2], prev_av_start[1], prev_av_start[0])+" - "+planyo_output_date(yesterday[2], yesterday[1], yesterday[0]);
          else
            code += "<div class='av_time' "+onclick_code+">"+planyo_output_date(prev_av_start[2], prev_av_start[1], prev_av_start[0]);
          if (document.resources[r].quantity > 1 && document.resources[r].quantity < 1000)
            code += " ("+prev_av+")";
          code += "</div>";
          av_found = true;
        }
        prev_av = av;
        prev_av_start = this_day;
      }
      if (year != this_day[2] || month != this_day[1]) {
        break;
      }
      yesterday = this_day;
      this_day = planyo_get_next_day (this_day[0], this_day[1], this_day[2]);
    }
  }
  if (!av_found)
    code += " "+document.s_unav;
  code += "</div>";
  code += "</div>";
  document.getElementById ('horizontal_calendar').innerHTML = code;
}

// if resource is null, all resources are shown, else given resource only.
// day is only needed in week mode
function js_show_horizontal_calendar (day, month, year, resource) {
  if (!document.getElementById ('horizontal_calendar') || document.active_view_mode == view_mode_day)
    return;
  if (document.is_mobile || document.preview_style == preview_style_upcoming)
    return js_show_upcoming_days(day, month, year, resource);

  var now = new Date();
  if (month == null && year == null) {
    day = now.getDate();
    month = now.getMonth() + 1;
    year = now.getFullYear();
  }

  var month_specs = planyo_get_month_specs (month, year);
  var next_month = planyo_get_next_month (month, year);
  var next_month_specs = planyo_get_month_specs (next_month [0], next_month [1]);
  
  var div_code = "<table id='cal' cellpadding='0' cellspacing='0'><caption><a class='earlier' href='javascript:js_nav(\"prev\")'>&laquo;"+document.s_prev+"</a><a class='later' href='javascript:js_nav(\"next\")'>"+document.s_next+"&raquo;</a>";
  div_code += "<a class='nav_today' href='javascript:js_nav(\"now\")'>"+document.s_today+"</a>";
  if (!document.non_switchable_cal_view)
    div_code += "<a class='switch_mode' href='javascript:js_nav("+day+","+month+","+year+")'>"+document.s_day_view+"</a>";
  div_code += "</caption><thead>";
  if (!document.hor_cal_week_mode) {
    div_code += "<tr class='days'><th></th><th colspan='"+month_specs[2]+"'>"+planyo_get_month_name(month)+' '+year+"</th><th colspan='"+(15/*next_month_specs [2]*/)+"'>"+planyo_get_month_name(next_month [0])+' '+next_month[1]+"</th></tr>\n";
    day = 1;
  }
  else {
    var cur_month_cols = month_specs[2] - day + 1;
    var next_month_cols = document.hor_cal_week_mode - cur_month_cols;
    div_code += "<tr class='days'><th></th><th colspan='" + cur_month_cols + "'>";
    if (cur_month_cols >= 5)
      div_code += planyo_get_month_name(month)+' '+year;
    div_code += "</th>";
    if (next_month_cols > 0) {
      div_code += "<th colspan='" + next_month_cols+ "'>";
      if (next_month_cols >= 5)
      div_code += planyo_get_month_name(next_month [0])+' '+next_month[1];
      div_code += "</th>";
    }
    div_code += "</tr>\n";
  }
  div_code += "<tr class='hours2'><th></th>";

  var total_day_count = document.hor_cal_week_mode ? document.hor_cal_week_mode : month_specs [2] + 15;
  var day_iterator = (month_specs [0] + day - 1) % 7;
  for (var d = 1; d <= total_day_count; d++) {
    div_code += "<th>" + planyo_get_day_name (day_iterator, true) + "</th>";
    day_iterator++;
    if (day_iterator == 7)
      day_iterator = 0;
  }
  div_code += "</tr>\n<tr class='hours'><th></th>";

  var d = day;
  var specs = month_specs;
  for (var i = 1; i <= total_day_count; i++) {
    div_code += "<th>";
    if (!document.non_switchable_cal_view)
      div_code += "<a href='javascript:js_nav("+d+","+specs[3]+","+specs[4]+")'>";
    div_code += d;
    if (!document.non_switchable_cal_view)
      div_code += "</a>";
    div_code += "</th>";
    d++;
    if (d > month_specs [2]) {specs=next_month_specs; d = 1;}
  }
  div_code += "</tr></thead><tfoot></tfoot><tbody>";

  var resource_collection;
  var listing_assignments;
  if (document.assignments && document.resource_id && document.separate_units) {
      resource_collection = document.assignments[document.resource_id];
      listing_assignments = true;
  }
  else {
      resource_collection = document.sorted_resources;
      listing_assignments = false;
  }
  for (var rr in resource_collection) {
    var r;
    var resname;
    if (listing_assignments)
        r = document.resource_id;
    else
        r = parseInt(document.sorted_resources [rr]['id']);
    var res = document.resources [r];
		if (!res) continue;
    if (listing_assignments) {
        if (!resource_collection[rr]['id']) continue;
        resname = resource_collection[rr]['name'];
        document.current_assignment = rr;
    }
    else {
        resname = res.name;
    }
    var resource_url = get_resource_url(res);
		if (document.empty_item_reserve_link)
		  div_code += "<tr><td class='resource'><a href='"+resource_url+"'"+(document.open_frame ? " target='"+document.open_frame+"'" : "")+"><nobr>" + resname + "</nobr></a></td>";
    else
			div_code += "<tr><td><nobr>" + resname + "</nobr></td>";

    var current_month = month;
    var current_year = year;
    var current_day = day;
    for (var i = 1; i <= total_day_count; i++) {
      if (!planyo_isset (document.resource_usage, current_year, current_month) &&
	        !planyo_isset (document.vacations, current_year, current_month)) {
        js_fetch_calendar_data (current_month, current_year);
	        break;
      }
      var day_code = '';
      day_code = js_get_grouped_code (current_year, current_month, current_day, 'ad', 'none', res.id, null, true);
      div_code += day_code;
      current_day++;
      if (current_day > month_specs [2]) {
        current_month = next_month [0];
        current_year = next_month [1];
        current_day = 1;
      }
    }
    div_code += "</tr>";
  }
  div_code += "</tbody></table>";
  document.getElementById ('horizontal_calendar').innerHTML = div_code;
  document.current_assignment = null;
}

function js_get_hour_info_from_fetched_data (day, month, year, month_data, day_items) {
  // check in cache
  if (planyo_isset (document.time_data_day, year, month, day))
    return document.time_data_day [year][month][day];
  return null;
}

function js_get_day_info_from_fetched_data (month, year) {
  if (planyo_isset (document.time_data_month, year, month)) {
    return document.time_data_month [year][month];
  }
  return null;
}

function js_get_vacation_single_text (start_hour, end_hour, resource, vacation_info) {
  var code = "";
  var count = vacation_info ['v'];
  if (count > 0) {
    if (start_hour && end_hour && start_hour != 'ad' && end_hour != 'ad')
      code += planyo_output_time(start_hour,0) + " - " + planyo_output_time(parseInt(end_hour) + 1,0);
    code += ' '+resource.name;
    if (resource.quantity > 1 && resource.quantity < 1000)
      code += " (" + count + ")";
  }
  if (planyo_isset (vacation_info, 'c'))
    code += " <i>"+vacation_info ['c'] +"</i>";
  code += " <br/>";
  return code.replace("\"", "\'");
}

function js_get_vacation_text (year, month, day, resource_id, period) {
    var code = '';
    if (period) {
        if (planyo_isset (document.vacations, year, month, day, resource_id, period)) {
            code += js_get_vacation_single_text (null, null, document.resources [resource_id], document.vacations [year][month][day][resource_id][period]);
        }
    }
    else if (planyo_isset (document.vacations, year, month, day, resource_id)) {
        var resource = document.resources [resource_id];
        var prev_count = null;
        var prev_start = 0;
        var prev_hour = 0;
        var prev_code;
        for (var p in document.vacations [year][month][day][resource_id]) {
            if ((p >= 0 && p <= 23) || p == 'ad') {
	              var count = document.vacations [year][month][day][resource_id][p];
	              if (!prev_count || count['v'] != prev_count['v'] || count['c'] != prev_count['c'] || p == 'ad') {
	                  if (prev_count) {
	                      code += js_get_vacation_single_text(prev_start, prev_hour, resource, prev_code);
	                  }
	                  if (count['v'] > 0) {
	                      prev_code = count;
	                      prev_start = p;
                        prev_count = count;
	                  }
	              }
	              prev_hour = p;
            }
        }
        if (prev_count) {
            code += js_get_vacation_single_text(prev_start, prev_hour, resource, prev_code);
        }
    }
    return code;
}

// period: hour or 'ad' (full-day info only) or null (mixed)
// is_long: true for full info, false for tooltip
function js_print_vacation_info (is_long, year, month, day, period, resource_id) {
  var long_code = '';
  var short_code = '';
  if (planyo_isset (document.vacations, year, month, day)) {
    if (resource_id) {
      long_code += js_get_vacation_text (year, month, day, resource_id, period);
    }
    else {
      for (var r in document.resources) {
	var res = document.resources [r].id;
	long_code += js_get_vacation_text (year, month, day, res, period);
      }
    }
  }
  if (long_code.length > 0)
    short_code = "<div class='vacation' title=\"" + long_code + "\"><a style='color:black' href='resource-vacations.php?resource_id="+resource_id+"'>"+document.texts ['vacation']+"</a></div>";
  return is_long ? long_code : short_code;
}

// t is now a string that needs to be parsed
function js_set_from_gmt_time (t, offset) {
  var new_time = new Date();
  new_time.setTime (Date.parse (t) + offset * 1000);
  return new_time;
}

function js_get_item_code (data, mode) {
  var code = '';
  var first_weekday = planyo_isset(document.first_weekday) ? document.first_weekday : 1;
  if (document.fetched_data [data.year][data.month]) {
    var item = document.fetched_data [data.year][data.month][data.index];
    var resource = document.resources [item.resource_id];
    var item_id = "rnt"+item ['rental_id']+"_"+(document.next_uid++);
    code += "<div class='item_code'";
    if (item ['color'])
      code += " style='background-color:"+item['color']+"'";
    code += ">";
    if ((mode & item_code_time) && (data.duration == event_duration_part_day || data.duration == event_duration_part_hour)) {
      var start_time = js_set_from_gmt_time (item ['start_time'], 0);
      var end_time = js_set_from_gmt_time (item ['end_time'], 60);
      code += "<span class='item_code_time'>";
      if (start_time.getDate() != end_time.getDate() || start_time.getMonth() != end_time.getMonth())
	code += planyo_get_day_name ((7 - first_weekday + start_time.getDay()) % 7, false) + " "+planyo_output_time(start_time.getHours(),start_time.getMinutes())+"-"+planyo_get_day_name ((7 - first_weekday + end_time.getDay()) % 7, false) + " "+planyo_output_time(end_time.getHours(),end_time.getMinutes());
      else
	code += planyo_output_time(start_time.getHours(),start_time.getMinutes())+"-"+planyo_output_time(end_time.getHours(),end_time.getMinutes());
      code += "</span> ";
    }
    if (mode & item_code_resource)
      code += "<span class='item_code_res'><a href='rental.php?id=" + item ['rental_id'] + "'>" + resource.name + "</a></span> ";
    if ((mode & item_code_quantity) && (item.cnt > 1 || item ['postfix']))
      code += "<span class='item_code_cnt'>"+((item.cnt > 1 && item.cnt < 1000) ? "(" + item.cnt + ")" : "")+(item ['postfix'] ? " ["+item['postfix']+"]" : "")+"</span> ";
    if (mode & item_code_user)
      code += "<span class='item_code_user'><a href='rental.php?id=" + item ['rental_id'] + "'>" + item ['user_name'] + "</a></span> ";
    if (mode & item_code_initials)
      code += "<span class='item_code_initials'>" + item ['initials'] + "</span> ";
    if (mode & item_code_draggable)
      code += "<span id='"+item_id+"' class='draggable' title='"+document.s_draginfo+"'><img src='images/empty.gif' width='6' height='7' style='vertical-align:middle'></span>";
    code += "</div>";
  }
  return code;
}

// min is 'none' or defines quarter requested
function js_get_period_status (year, month, day, period, min, resource, group_periods) {
  var usage_data = null;
  var resource_id = resource.id;
  if (planyo_isset (document.resource_usage, year, month))
    usage_data = document.resource_usage [year][month][day];
  var vacations = null;
  if (planyo_isset (document.vacations, year, month))
    vacations = document.vacations [year][month][day];
  var status = null;
  var date_obj = new Date();
  if (period != 'ad')
    date_obj = new Date(year, month - 1, day, period, min && min != 'none' ? min : 0, 0, 0);
  else
    date_obj.setFullYear (year, month - 1, day);
  if (period != 'ad' && resource.first_hour && resource.last_hour && resource.last_hour > 0 && (period < resource.first_hour || period >= resource.last_hour)) {
    status = resource_usage_vacation;
  }
  var vacation_count = 0;
  var vacations_set = planyo_isset (vacations, resource_id, period);
  if (vacations_set) {
    if (planyo_isset (vacations, resource_id, period, min))
      vacation_count = parseInt(vacations [resource_id][period][min]['v']);
    if (vacations [resource_id][period]['v'] != null)
      vacation_count += parseInt(vacations [resource_id][period]['v']);
  }
  if (period != 'ad' && planyo_isset (vacations, resource_id, 'ad'))
    vacation_count += Math.max (vacation_count, parseInt (vacations [resource_id]['ad']['v']));
  if (vacation_count < 0) // negative vacation scenarios possible via manual override
    vacation_count = 0;

  if (!status && (vacation_count > 0 || planyo_isset (usage_data, period, resource_id) || (period == 'ad' && planyo_isset (usage_data, 'pd', resource_id)) || (period != 'ad' && group_periods && planyo_isset (usage_data, 'ad', resource_id)) || (period != 'ad' && planyo_isset (usage_data, period, 'qs', 'ph', resource_id)) || (min != 'none' && planyo_isset (usage_data, period, 'qs', min, resource_id)))) {
    var full_usage = 0;
    if (planyo_isset (usage_data, period, resource_id))
      full_usage = usage_data [period][resource_id];
    var diff = resource.quantity - full_usage - vacation_count;
    if (period != 'ad' && group_periods && planyo_isset (usage_data, 'ad', resource_id)) { // for hourly usage, count full day-items as well
      diff -= usage_data ['ad'][resource_id];
    }
    if (min != 'none' && planyo_isset (usage_data, period, 'qs', min, resource_id))
      diff -= usage_data [period]['qs'][min][resource_id];
    if (diff == resource.quantity)
      status = resource_usage_none;
    else if (diff > 0 && status != resource_usage_vacation)
      status = resource_usage_partial;
    else if (vacation_count >= resource.quantity)
      status = resource_usage_vacation;
    else
      status = resource_usage_full;
    var partcnt = 0;
    if (status != resource_usage_full && status != resource_usage_vacation && period == 'ad' && planyo_isset (usage_data, 'pd', resource_id)) {
      if (usage_data ['pd'][resource_id] >= diff) // during at least one hour all resources are used
	status = resource_usage_daily_full;
      if (group_periods) {
	partcnt = usage_data ['pd'][resource_id];
	if (partcnt > 0 && status == resource_usage_none)
	  status = resource_usage_partial;
      }
    }
    if (status != resource_usage_full && status != resource_usage_vacation && period != 'ad' && min == 'none' && planyo_isset (usage_data, period, 'qs', 'ph', resource_id)) {
      if (usage_data [period]['qs']['ph'][resource_id] >= diff) // during at least one quarter all resources are used
	status = resource_usage_partial;
      if (group_periods) {
	partcnt = usage_data [period]['qs']['ph'][resource_id];
	if (partcnt > 0 && status == resource_usage_none)
	  status = resource_usage_partial;
      }
    }
    if (status == resource_usage_daily_full && period == 'ad' && planyo_isset (usage_data, 'md', resource_id)) {
      if (usage_data ['md'][resource_id] == resource.quantity) // all hours are taken during the day
	status = resource_usage_full;
    }
  }
  if (status != resource_usage_vacation && status != resource_usage_full) {
    if (document.now_obj) {
      if (!document.now_time)
        document.now_time = new Date(document.now_obj[0], document.now_obj[1] - 1, document.now_obj[2], document.now_obj[3], document.now_obj[4], 0, 0);
      var first_rental_time = document.now_time;
      if (planyo_isset(resource, 'rental_min_ahead_hours') && resource['rental_min_ahead_hours'] > 0)
        first_rental_time = new Date(document.now_time.getTime() + 1000*3600*resource['rental_min_ahead_hours']);
      if (date_obj < first_rental_time)
          status = resource_usage_vacation;
    }
    else {
      var now_obj = new Date();
      now_obj.setFullYear(now_obj.getFullYear(),now_obj.getMonth(),now_obj.getDate());
      if (date_obj < now_obj-(3600*1000))
          status = resource_usage_vacation;
    }
  }
  if ((!status || status == resource_usage_none) && document.deps && planyo_isset(document.deps, resource_id) && group_periods && group_periods != 'norec') {
      for (var i = 0; i < document.deps[resource_id].length; i++) {
          var dep_id = parseInt(document.deps[resource_id][i]);
          var dep_res = null;
          if (planyo_isset(document.resources,dep_id)) {
              dep_res = document.resources[dep_id];
          }
          else {
              dep_res = new Object();
              dep_res.id = dep_id;
              dep_res.first_hour=null;
              dep_res.last_hour=null;
              dep_res.quantity=1;
          }
          var dep_status = js_get_period_status (year, month, day, period, min, dep_res, 'norec');
          if (dep_status && (dep_status[0] == resource_usage_full || dep_status[0] == resource_usage_vacation)) {
              status = resource_usage_vacation;
              break;
          }
      }
  }
  if (period == 'ad' && status == resource_usage_partial && document.assignments && document.resource_id && document.separate_units) {
      var day_items = js_get_day_info_from_fetched_data (month, year);
      if (day_items != null) {
          var found_ass = false;
	        for (var i = 0; i < day_items [day].length; i++) {
	            var item = day_items [day][i];
              if (js_check_assignment (item, document.current_assignment, resource_id, document.assignments.length)) {
                  status = resource_usage_full;
                  found_ass = true;
                  break;
              }
          }
          if (!found_ass)
              status = resource_usage_none;
      }
  }
  if (!status && !planyo_isset (document.fetched_data, year, month))
    status = resource_usage_unknown;
  var start_day_status = 0;
  if (period == 'ad' && document.start_day_restrictions_active && planyo_isset(document.start_day_restrictions, year, month, resource_id, day)) {
    start_day_status = document.start_day_restrictions[year][month][resource_id][day];
  }
  return new Array(status, diff, partcnt, start_day_status);
}

function js_get_unavailable_cell_code() {
  return "<td class='reserved' >&nbsp;&nbsp;</td>";
}

// period is either hour (0-23) or 'ad'
// mode is one or more of item_code_xxx flags
// set group_periods to true to count part-day usage (always) and day usage for hours
// min is 'none' or defines quarter requested
function js_get_grouped_code (year, month, day, period, min, resource_id, mode, group_periods) {
  var resource = document.resources [resource_id];
  var code = '';

  var status_arr = js_get_period_status (year, month, day, period, min, resource, group_periods);
  var status = status_arr [0];
  var diff = status_arr [1];
  var partcnt = status_arr [2];
  var mark_start_hours = (period != 'ad' && planyo_isset (document.resource_start_times, resource_id));
  var start_hour_valid = (mark_start_hours && planyo_isset (document.resource_start_times, resource_id, period+":"+((min && min != 'none') ? min : '00')));
  var mark_arrival_days = (period == 'ad' && document.start_day_restrictions_active);
  var start_day_status = status_arr [3];
  var is_nonstart_time = ((mark_arrival_days && start_day_status == 2) || (mark_start_hours && !start_hour_valid));
  if (status && status != resource_usage_vacation && (mode & item_code_resource))
    code += "<span class='item_code_res'>" + resource.name + "</span>";
  var onclick_code = '';
  if (document.empty_item_reserve_link && resource.access_type != 3) {
    var hour = '';
    if (period != 'ad')
	hour = period + (min == 'none' ? 0 : min/60);
      onclick_code = "onclick=\"" + (document.open_frame=='_blank' ? "window.open('" : (document.open_frame=='_top' ? "window.top.location.href='" : (document.open_frame=='_parent' ? "window.parent.location.href='" : "window.location.href='"))) + document.empty_item_reserve_link + (document.empty_item_reserve_link.indexOf('?') == -1 ? "?" : "&") + "prefill=true&" + (js_is_using_hour_granulation (resource) ? "one_date="+encodeURIComponent(planyo_output_date(year, month, day))+"&start_date="+encodeURIComponent(planyo_output_date(year, month, day))+"&start_time="+hour+"&end_time="+hour : "time_mode=full_day&start_date="+encodeURIComponent(planyo_output_date(year, month, day))) + "&resource_id=" + resource_id + (document.open_frame=='_blank' ? "')" : "'") + "\"";
  }
  var add_class = '';
  if (document.is_night_icon_mode && resource.quantity == 1 && (status == resource_usage_full || status == resource_usage_none || status == null) && period == 'ad') {
    var prev_day = planyo_get_prev_day (day, month, year, 1);
    var prev_day_status = js_get_period_status (prev_day[2], prev_day[1], prev_day[0], 'ad', 'none', resource, null);
    if (prev_day_status && prev_day_status[0] == resource_usage_full && (status == resource_usage_none || status == null)) {
      add_class = ' morning_occ';
    }
    else if (prev_day_status && (prev_day_status[0] == null || prev_day_status[0] == resource_usage_none) && status == resource_usage_full) {
      add_class = ' morning_av';
    }
  }

  var s_all = document.s_all;
  var s_areav = document.s_areav;
  var s_click = document.s_clickres;
  var s_partav = document.s_partav;
  var s_outof = document.s_outof;
  switch (status) {
  case resource_usage_partial:
    if (is_nonstart_time)
      code += "<td class='partial no_start'>" + (document.always_show_count ? (diff-partcnt) : "&middot;");
    else
      code += "<td class='partial"+((mark_arrival_days||mark_start_hours) ? " arrival_day" : "")+"' "+onclick_code+(onclick_code ? " title=\""+(diff-partcnt)+' '+s_outof+' '+resource.quantity+' '+s_areav+s_click+"\"" : "")+">" + (document.always_show_count ? (diff-partcnt) : "&middot;") /*(resource.quantity - diff + partcnt)*/ + "</td>";
    break;
  case resource_usage_daily_full:
    code += "<td class='partial' "+onclick_code+(onclick_code ? " title=\""+s_partav+"\"" : "") + ">" + "&middot;" /*(resource.quantity - diff + partcnt)*/ + "</td>";
    break;
  case resource_usage_vacation:
    code += js_get_unavailable_cell_code();
    break;
  case resource_usage_full:
    code += "<td class='reserved"+add_class+"' >" + "&times;" /*resource.quantity*/ + "</td>";
    break;
  default:
    if (is_nonstart_time)
      code += "<td class='available no_start"+add_class+"'>" + (document.always_show_count ? resource.quantity : "&nbsp;&nbsp;") + "</td>";
    else
      code += "<td class='available"+((mark_arrival_days||mark_start_hours) ? " arrival_day" : "")+add_class+"' "+onclick_code+" "+(onclick_code ? (resource.quantity > 1 ? "title=\""+(resource.quantity==1000 ? '' : s_all+' '+resource.quantity+' '+s_areav)+s_click+"\"" :"title=\""+s_click+"\"") : "")+">" + (document.always_show_count ? resource.quantity : "&nbsp;&nbsp;") + "</td>";
    break;
  }

  return code;
}

function js_get_caption (title, sel) {
  var code = '';
  code += "<a class='nav' href='javascript:js_nav(\"prev\")'>&laquo;"+document.s_prev+"</a><a class='nav' href='javascript:js_nav(\"next\")'>"+document.s_next+"&raquo;</a><a class='nav' href='javascript:js_nav(\"now\")'>"+document.s_today+"</a>";
  code += "<span class='mid'>" + title + "</span>";
  code += "<a class='scope' href='javascript:js_set_view_mode(view_mode_month)'>"+(sel=='month' ? "<b>"+document.s_month+"</b>":document.s_month)+"</a><a class='scope' href='javascript:js_set_view_mode(view_mode_week)'>"+(sel=='week'?"<b>"+document.s_week+"</b>":document.s_week)+"</a>";
  if (!document.no_day_details)
    code += "<a class='scope' href='javascript:js_set_view_mode(view_mode_day)'>" + (sel=='day' ? "<b>"+document.s_day+"</b>" : document.s_day) + "</a>";
  return code;
}

function js_get_month_view (month, year) {
  var code = '';
  code += "<table cellpadding='0' cellspacing='0' id='calendarbig'>";
  code += "<caption>" + js_get_caption (planyo_get_month_name (month) +" " + year, 'month') + "</caption>";
  code += "<thead><tr>";
  for (var i = 0; i < 7; i++) {
    code += "<th>" + planyo_get_day_name (i, false) + "</th>";
  }
  code += "</tr></thead><tfoot></tfoot><tbody>";
  var day_items = new Array();
  var day_info = planyo_get_day_info_for_month (month, year);
  for (var y = 0; y < 6; y++) {
    code += "<tr>";
    for (var x = 0; x < 7; x++) {
      var current_day = day_info [y][x]['day'];
      var current_month = day_info [y][x]['month'];
      var current_year = day_info [y][x]['year'];
      if (!planyo_isset (day_items, current_month))
	  day_items [current_month] = js_get_day_info_from_fetched_data (current_month, current_year);
      var day_type = day_info [y][x]['type'];
     code += "<td><div class='mv_head_"+day_type+"'><a href='javascript:js_nav ("+day_info [y][x]['day']+", "+current_month+", "+current_year+");'>" + current_day + "</a></div>";
     var next_level = 0;
     if (document.calendar_type == calendar_type_all_resources_details) {
       if (planyo_isset (day_items, current_month, current_day)) {
	  for (var i = 0; i < day_items [current_month][current_day].length; i++) {
	    var item = day_items [current_month][current_day][i];
	    if (document.month_view_max_items &&
		item.pos >= document.month_view_max_items - 1 &&
		i + 1 < day_items [current_month][current_day].length) {
	      code += "<div class='mv_cnt'><a href='javascript:js_nav("+current_day+","+current_month+","+current_year+");'>" + (day_items [current_month][current_day].length - i) + " more items...</a></div>";
	      break;
	    }
	    if (!document.month_view_max_items || item.pos < document.month_view_max_items) {
	      for (var j = next_level; j < item.pos; j++) {
		code += "<div>&nbsp;</div>";
	      }
	    }
	    code += js_get_item_code (item, item_code_short);
	    next_level = item.pos + 1;
	  }
       }
       code += js_print_vacation_info (false, current_year, current_month, current_day, null);
     }
     else if (document.calendar_type == calendar_type_all_resources_grouped) {
       for (var r in document.resources) {
	 code += js_get_grouped_code (current_year, current_month, current_day, 'ad', 'none', document.resources [r].id, item_code_short, true);
       }
     }
     code += "</td>";
    }
    code += "</tr>";
  }
  code += "</tbody></table>";
  return code;
}

function js_check_assignment (data, assignment, resource, assignment_count) {
  if (data ['resource_id'] == document.resources [resource].id) {
    if (assignment == -1 && (!data ['admin_assignment'] || assignment_count <= 1))
      return true;
    if (assignment != -1 && typeof (data['admin_assignment']) == 'string') {
      var re = new RegExp ("(,|^)"+document.assignments [resource][assignment]['name']+"(,|$)");
      if (data ['admin_assignment'].match(re))
        return true;
    }
  }
  return false;
}

function js_get_week_view (day, month, year) {
  var max_day = 6;
  var first_day_number = 0;
  var code = '';
  var param_day = new Date();
  param_day.setFullYear (year, month - 1, day);
  var first_weekday = planyo_isset(document.first_weekday) ? document.first_weekday : 1;
  var param_day_of_week = (7 - first_weekday + param_day.getDay()) % 7;
  if (document.days_in_week_view) {
    max_day = document.days_in_week_view - 1;
    param_day_of_week += max_day - 6;
    first_day_number = 7 + (6 - max_day);
  }
  var first_day_data = param_day_of_week == 0 ? new Array(day, month, year) : planyo_get_prev_day (day, month, year, param_day_of_week);
  var last_day_data = planyo_get_next_day (first_day_data [0], first_day_data [1], first_day_data [2], max_day);

  var day_items = new Array();
  var day_info = planyo_get_day_info_for_month (month, year);
  code += "<table cellpadding='0' cellspacing='0' id='calendarbig'>";
  code += "<caption>" + js_get_caption (first_day_data [0] + " " + planyo_get_month_name (first_day_data [1], false) + " " + first_day_data [2] + " - " +last_day_data [0] + " " + planyo_get_month_name (last_day_data [1], false) + " " + last_day_data [2], 'week') + "</caption>";
  code += "<thead><tr><th></th>";
  for (var d = 0; d<=max_day; d++) {
    var cur_day_data = (d == 0) ? first_day_data : planyo_get_next_day (first_day_data [0], first_day_data [1], first_day_data [2], d);
    code += "<th>" + planyo_get_day_name (d + first_day_number, false) + ", " + cur_day_data [0] + " " + planyo_get_month_name (cur_day_data [1], true) + "</th>";
  }
  code += "</tr></thead><tfoot></tfoot><tbody>";
  var month_data = null;

  for (var rr in document.sorted_resources) {
    var r = parseInt(document.sorted_resources [rr]['id']);
		if (!document.resources[r]) continue;				
    var alen = 0;
    if (document.calendar_type == calendar_type_all_resources_details)
      alen = document.assignments [r].length;
    for (var a = -1; a < alen; a++) {
      if (a == 0 && (!document.assignments [r][a]['name'] || alen == 1))
        break;
      code += "<tr>";
      code += "<td class='resource week_td'>" + document.resources [r].name;
      if (a != -1)
        code += "<br/>" + document.assignments [r][a]['name'];
      else if (alen > 1)
	code += "<br/>" + "["+document.s_unassigned+"]";
      code += "</td>";
      for (var d = 0; d <= max_day; d++) {
        var cur_day_data = (d == 0) ? first_day_data : planyo_get_next_day (first_day_data [0], first_day_data [1], first_day_data [2], d);
        var current_day = cur_day_data [0];
	var current_month = cur_day_data [1];
	var current_year = cur_day_data [2];
	var cell_id = "cell"+(document.next_uid++);
        code += "<td class='droppable week_td' id='"+cell_id+"'>";
	code += "<span class='invisible'>"+cur_day_data[2]+"/"+cur_day_data[1]+"/"+cur_day_data[0]+"</span>";
	code += "<span class='invisible'>"+document.resources[r].id+"</span>";
	code += "<span class='invisible'>"+(a != -1 ? document.assignments [r][a]['name'] : '')+"</span>";

        try {
	  if (document.calendar_type == calendar_type_all_resources_details) {
	    if (document.fetched_data [current_year] && document.fetched_data [current_year][current_month]) {
	      month_data = document.fetched_data [current_year][current_month];
	    }
	    else {
	      js_fetch_calendar_data (current_month, current_year);
	      return '';
	    }
	    if (!planyo_isset (day_items, current_month)) {
	      day_items [current_month] = js_get_day_info_from_fetched_data (current_month, current_year);
	    }
	    if (planyo_isset (day_items, current_month, current_day) && planyo_isset (month_data)) {
	      for (var i = 0; i < day_items [current_month][current_day].length; i++) {
	        var item = day_items [current_month][current_day][i];
  	        var data = month_data [item.index];
                if (js_check_assignment (data, a, r, alen)) {
		  code += js_get_item_code (item, item_code_long);
	        }
  	      }
	    }
            if (a == -1)
              code += js_print_vacation_info (false, cur_day_data [2], cur_day_data [1], cur_day_data [0], null, document.resources [r].id);
	  }
	  else if (document.calendar_type == calendar_type_all_resources_grouped && planyo_isset (document.resource_usage, current_year, current_month, current_day)) {
	    code += js_get_grouped_code (current_year, current_month, current_day, 'ad', 'none', document.resources [r].id, item_code_long, true);
	  }
        }
        catch (err) {if (document.debug_mode) document.debug_log += "[js_get_week_view] " + err.message + " || ";}
        code += "</td>";
      }
      code += "</tr>";
    }
  }
  code += "</tbody></table>";
  return code;
}

function js_is_using_hour_granulation (resource) {
  return (resource ['category'] == 5000 || resource ['min_rental_time'] < 24);
}

function js_get_resources_min_max_hour(property, is_min) {
  var extr = (is_min ? 0 : 24);
  var n = 0;
  for (var it in document.resources) {
    var val = parseInt (document.resources [it] [property]);
    if (!val) val = (is_min ? 0 : 24);
    if (js_is_using_hour_granulation (document.resources [it])) {
      if (is_min) {
	if (n == 0 || val < extr)
	  extr = val;
      }
      else {
	if (n == 0 || val > extr)
	  extr = val;
      }
      n++;
    }
  }
  return parseInt(extr);
}

function js_get_day_view (day, month, year) {
  var code = '';

  var day_info = null;
  var hour_items = null;

  if (document.fetched_data [year] && document.fetched_data [year][month]) {
    day_info = js_get_day_info_from_fetched_data (month, year);
    hour_items = day_info [day] ? js_get_hour_info_from_fetched_data (day, month, year, document.fetched_data [year][month],
								      day_info [day]) : null;
  }
  else {
    js_fetch_calendar_data (month, year);
    return '';
  }
  code += "<table cellpadding='0' cellspacing='0' id='calendarbig'>";
  code += "<caption>" + js_get_caption(day + " " + planyo_get_month_name (month, false) + " " + year, 'day')+"</caption>";
  code += "<thead><tr><th></th>";

  var first_hour = js_get_resources_min_max_hour('first_hour', true);
  var last_hour = js_get_resources_min_max_hour('last_hour', false);
  for (var h = first_hour; h < last_hour; h++) {
    if (last_hour > first_hour)
      code += "<th>" + planyo_output_time(h,0) + "</th>";
    else
      code += "<th>" + document.texts ['all_day'] + "</th>";
  }
  code += "</tr></thead><tfoot></tfoot><tbody>";
  var all_day_code = new Array();
  for (var r in document.resources) {
    all_day_code [r] = new Array();
    var alen = 0;
    if (document.calendar_type == calendar_type_all_resources_details)
      alen = document.assignments [r].length;
    for (var a = -1; a < alen; a++) {
      if (a == 0 && (!document.assignments [r][a]['name'] || alen == 1))
        break;
      all_day_code [r][a] = '';
      try {
	if (document.calendar_type == calendar_type_all_resources_details) {
	  if (day_info && day_info [day]) {
	    for (var i = 0; i < day_info [day].length; i++) {
	      var item = day_info [day][i];
	      var data = document.fetched_data [year][month][item.index];
	      if (item.duration != event_duration_part_day && item.duration != event_duration_part_hour && js_check_assignment (data, a, r, alen)) {
		all_day_code [r][a] += js_get_item_code (item, item_code_long);
	      }
	    }
	  }
	  all_day_code [r][a] += js_print_vacation_info (false, year, month, day, 'ad', document.resources [r].id);
	}
	else if (document.calendar_type == calendar_type_all_resources_grouped && (planyo_isset (document.resource_usage, year, month, day) ||
										   planyo_isset (document.vacations, year, month, day))) {
	  all_day_code [r][a] += js_get_grouped_code (year, month, day, 'ad', 'none', document.resources [r].id, item_code_long, false);
	}
      }
      catch (err) {if (document.debug_mode) document.debug_log += "[js_get_day_view]" + err.message + " || ";}
    }
  }
  
  for (var rr in document.sorted_resources) {
    var r = parseInt(document.sorted_resources [rr]['id']);
		if (!document.resources[r]) continue;				
    var alen = 0;
    if (document.calendar_type == calendar_type_all_resources_details)
      alen = document.assignments [r].length;
    for (var a = -1; a < alen; a++) {
      if (a == 0 && (!document.assignments [r][a]['name'] || alen == 1))
        break;
      code += "<tr>";
      code += "<td class='day_td'>" + document.resources [r].name;
      if (a != -1)
        code += "<br/>" + document.assignments [r][a]['name'];
      else if (alen > 1)
	code += "<br/>" + "["+document.s_unassigned+"]";
      code += "</td>";
      for (var h = first_hour; h < last_hour; h++) {
	var cell_id = "cell"+(document.next_uid++);
	code += "<td class='droppable day_td' id='"+cell_id+"'>";
	code += "<span class='invisible'>"+year+"/"+month+"/"+day+' '+h+':00'+"</span>";
	code += "<span class='invisible'>"+document.resources[r].id+"</span>";
	code += "<span class='invisible'>"+(a != -1 ? document.assignments [r][a]['name'] : '')+"</span>";
	code += all_day_code [r][a];
	if (document.calendar_type == calendar_type_all_resources_details) {
	  if (planyo_isset (hour_items, h, document.resources [r].id)) {
	    var items = hour_items [h][document.resources [r].id];
	    for (var i = 0; i < items.length; i++) {
	      var data = document.fetched_data [year][month][items[i].index];
              if (js_check_assignment (data, a, r, alen)) {
		code += js_get_item_code (items [i], item_code_long);
	      }
	    }
	  }
          if (a == -1)
            code += js_print_vacation_info (false, year, month, day, h, document.resources [r].id);
	}
	else if (document.calendar_type == calendar_type_all_resources_grouped && (planyo_isset (document.resource_usage, year, month, day) ||
										   planyo_isset (document.vacations, year, month, day))) {
	  code += js_get_grouped_code (year, month, day, h, 'none', document.resources [r].id, item_code_long, false);
	}
	code += "</td>";
      }
      code += "</tr>";
    }
  }
  code += "</tbody></table>";
  return code;
}

function js_update_month () {
  if (document.getElementById ('month_contents')) {
    var div_code = js_get_month_view (document.contents_month, document.contents_year);
    document.getElementById ('month_contents').innerHTML = div_code;
  }
  js_show_horizontal_calendar (document.contents_day, document.contents_month, document.contents_year, document.resource_id);
  js_show_calendar_nav(document.contents_month, document.contents_year);
}

function js_get_protocol() {
  if (document.location.protocol == 'https:')
    return 'https://';
  return "http://";
}

function js_get_root () {
  if (document.location.host=='localhost')
    return 'localhost/planyo';
  return document.location.host;
}

function js_update_week () {
  if (document.getElementById ('week_contents')) {
    var div_code = js_get_week_view (document.contents_day, document.contents_month, document.contents_year);
    document.getElementById ('week_contents').innerHTML = div_code;
  }
}

function js_update_day () {
  if (document.getElementById ('day_contents')) {
    var div_code = js_get_day_view (document.contents_day, document.contents_month, document.contents_year);
    document.getElementById ('day_contents').innerHTML = div_code;
  }
  js_show_horizontal_day_view (document.contents_day, document.contents_month, document.contents_year, document.resource_id);
}

function js_set_view_mode (mode, is_internal) {
  if (document.getElementById ('week_contents')) {
    if (mode == view_mode_day && !document.getElementById ('day_contents'))
      mode = view_mode_week;
    switch (mode) {
    case view_mode_day:
      document.getElementById ('month_contents').style.display = 'none';
      document.getElementById ('week_contents').style.display = 'none';
      if (document.getElementById ('day_contents'))
	document.getElementById ('day_contents').style.display = '';
      break;
    case view_mode_week:
      document.getElementById ('month_contents').style.display = 'none';
      document.getElementById ('week_contents').style.display = '';
      if (document.getElementById ('day_contents'))
	document.getElementById ('day_contents').style.display = 'none';
      break;
    case view_mode_month:
      document.getElementById ('month_contents').style.display = '';
      document.getElementById ('week_contents').style.display = 'none';
      if (document.getElementById ('day_contents'))
	document.getElementById ('day_contents').style.display = 'none';
      break;
    }
  }
  document.active_view_mode = mode;
  if (!is_internal) {
    js_update_views();
    Cookie.write('mode', mode, {duration: 60});
  }
}

function js_nav (day, month, year) {
  if (!month || !year) {
    month = document.contents_month;
    year = document.contents_year;
  }
  var view_mode = document.active_view_mode;
  if (document.hor_cal_week_mode && view_mode == view_mode_month) view_mode = view_mode_week;
  var is_day_set = false;
  if (day == 'prev' || (day && typeof(day) == 'string' && day.substring(0,4) == 'prev')) {
    switch (view_mode) {
    case view_mode_day:
      var offset = parseInt(day.substring(4));
      if (!offset)
        offset = 1;
      var prev_day = planyo_get_prev_day (document.contents_day, document.contents_month, document.contents_year, offset);
      document.contents_day = prev_day [0];
      document.contents_month = prev_day [1];
      document.contents_year = prev_day [2];
      break;
    case view_mode_week:
      var prev_day = planyo_get_prev_day (document.contents_day, document.contents_month, document.contents_year, 7);
      document.contents_day = prev_day [0];
      document.contents_month = prev_day [1];
      document.contents_year = prev_day [2];
      break;
    case view_mode_month:
      document.contents_month--;
      if (document.contents_month == 0) {
	document.contents_year--;
	document.contents_month = 12;
      }
      break;
    }
  }
  else if (day == 'next' || (day && typeof(day) == 'string' && day.substring(0,4) == 'next')) {
    switch (view_mode) {
    case view_mode_day:
      var offset = parseInt(day.substring(4));
      if (!offset)
        offset = 1;
      var next_day = planyo_get_next_day (document.contents_day, document.contents_month, document.contents_year, offset);
      document.contents_day = next_day [0];
      document.contents_month = next_day [1];
      document.contents_year = next_day [2];
      break;
    case view_mode_week:
      var next_day = planyo_get_next_day (document.contents_day, document.contents_month, document.contents_year, 7);
      document.contents_day = next_day [0];
      document.contents_month = next_day [1];
      document.contents_year = next_day [2];
      break;
    case view_mode_month:
      document.contents_month++;
      if (document.contents_month == 13) {
	document.contents_year++;
	document.contents_month = 1;
      }
      break;
    }
  }
  else if (day == 'now') {
    var now = new Date();
    document.contents_day = now.getDate();
    document.contents_month = now.getMonth() + 1;
    document.contents_year = now.getFullYear();
  }
  else {
    document.contents_day = !day ? 1 : day;
    document.contents_month = month;
    document.contents_year = year;
    if (day)
      is_day_set = true;
  }
  if (is_day_set && document.active_view_mode == view_mode_month) {
    if (document.min_granulation <= 60)
      js_set_view_mode (view_mode_day, false);
    else
      js_set_view_mode (view_mode_week, false);
  }
  else if (day == null && document.active_view_mode == view_mode_day)
    js_set_view_mode (view_mode_month, true);

  js_nav_refresh_data ();
}

function js_nav_refresh_data () {
  js_fetch_calendar_data (document.contents_month, document.contents_year);
  var next_month = planyo_get_next_month (document.contents_month, document.contents_year);
  var prev_month = planyo_get_prev_month (document.contents_month, document.contents_year);
  js_fetch_calendar_data (next_month [0], next_month [1]);
  js_fetch_calendar_data (prev_month [0], prev_month [1]);

  js_show_calendar_nav (document.contents_month, document.contents_year);
  js_update_views();
  var active_day = (document.active_view_mode != view_mode_month) ? document.contents_day : null;
  if (!document.getElementById('horizontal_calendar'))
    Cookie.write('nav', JSON.encode(new Array (document.contents_year, document.contents_month, active_day)), {duration: 60});
}

function handle_drop (element_id, target) {
  var children = target.getChildren();
  var cell_time = children[0].innerHTML;
  var cell_resource = children[1].innerHTML;
  var cell_assignment = encodeURIComponent(children[2].innerHTML);
  if (cell_time && cell_resource) {
    var separator = element_id.indexOf('_');
    if (separator > 3) {
      var rental_id = element_id.substring (3, separator);
      window.open("modify-rental.php?verify_data=false&id="+rental_id+"&resource_id="+cell_resource+(cell_assignment ? "&assignment1="+cell_assignment : "&assignment1=Unassigned")+"&time_offset="+cell_time,"datemodif","status=0,toolbar=0,location=0,menubar=0,directiories=0,width=600,height=400");
    }
  }
}

function js_update_pastables() {
  $$('.draggable').each(function(item){
      item.addEvent('mousedown', function(e) {
	  if (document.pasted_item_img) {
	    document.pasted_item_img.src = 'images/empty.gif';
	    document.pasted_item_img = null;
	  }
	  document.pasted_item = item.id;
	  document.pasted_item_img = e.target;
	  e.target.src='images/empty-sel.png';
	});
    });
  $$('.droppable').each(function(item){
      item.addEvent('click', function(e) {
	  if (document.pasted_item && e.target && e.target.tagName == 'TD') {
	    var item_id = document.pasted_item;
	    document.pasted_item = null;
	    if (document.pasted_item_img) {
	      document.pasted_item_img.src = 'images/empty.gif';
	      document.pasted_item_img = null;
	    }
	    document.pasted_item_img = null;
	    handle_drop (item_id, e.target);
	  }
	});
    });
  window.addEvent('keypress', function(e) {
      if (e && e.key == 'esc') {
	if (document.pasted_item_img) {
	  document.pasted_item_img.src = 'images/empty.gif';
	  document.pasted_item_img = null;
	}
	document.pasted_item = null;
      }
    });
}

function js_update_draggables() {
  $$('.draggable').each(function(item){
      item.addEvent('mousedown', function(e) {
	  e = new Event(e).stop();

	  var clone = this.clone();
	  clone.id = item.id+'drag';
	  clone.setStyles(this.getCoordinates());
	  clone.setStyles({'opacity': 0.7, 'position': 'absolute'});
	  clone.addEvent('mouseup', function() {
	      this.dispose();});
	  clone.inject(document.body);
	  var drag = clone.makeDraggable({
	    onDrop: function(element, droppable) {
		if (droppable) {
		  handle_drop (element.id, droppable);
		}
		element.dispose();
	      },
	    droppables: '.droppable'
		});
	  drag.start(e);
	});
    });
}

function js_update_views() {
  js_update_month ();
  js_update_week ();
  js_update_day ();
  document.vacation_tips = new Tips('.vacation');
  document.standard_tips = new Tips('.with_tooltip');
  if (!document.drag_disabled)
    js_update_draggables ();
  else
    js_update_pastables ();
}

function js_mark_fetching_data (month, year, is_fetching) {
  if (!planyo_isset (document.fetching_data, year))
    document.fetching_data [year] = new Array ();
  document.fetching_data [year][month] = is_fetching;
}

function js_save_fetched_data (month, year, data_root) {
  js_mark_fetching_data (year, month, false);
  if (!planyo_isset (document.fetched_data, year))
    document.fetched_data [year] = new Array ();
  document.fetched_data [year][month] = data_root ['db_data'];
  if (!planyo_isset (document.time_data_month, year))
    document.time_data_month [year] = new Array ();
  document.time_data_month [year][month] = data_root ['day_items'];
  if (!planyo_isset (document.time_data_day, year))
    document.time_data_day [year] = new Array ();
  document.time_data_day [year][month] = data_root ['hour_items'];
  if (!planyo_isset (document.resource_usage, year))
    document.resource_usage [year] = new Array ();
  document.resource_usage [year][month] = data_root ['res_usage'];
  if (!planyo_isset (document.vacations, year))
    document.vacations [year] = new Array ();
  document.vacations [year][month] = data_root ['vacations'];
  if (data_root ['start_days']) {
    if (!planyo_isset (document.start_day_restrictions, year))
      document.start_day_restrictions [year] = new Array ();
    document.start_day_restrictions [year][month] = data_root ['start_days'];
  }
  if (data_root ['deps'])
    document.deps = data_root['deps'];
}

function js_is_admin_panel () {
  return (document.getElementById ('month_contents') || document.getElementById ('week_contents') || document.getElementById ('month_contents') || document.admin_mode);
}

function js_fetch_calendar_data (month, year) {
  if (!planyo_isset (document.fetched_data, year, month) && !planyo_isset (document.fetching_data, year, month)) {
    js_mark_fetching_data (month, year, true);
    set_cursor ('wait');
    var req_url = js_get_protocol() + js_get_root () + "/fetch-data.php";
    var req_data = "id=" + document.calendar_id + "&month=" + month + "&year=" + year + (planyo_isset (document.resource_admin_mode) ? '&limited=1' : '');
    var precache_next_months = true;
    if (document.min_granulation > 0 && document.min_granulation <= 60)
      precache_next_months = false;
    if (precache_next_months) {
      var next_month = planyo_get_next_month (month, year);
      if (!planyo_isset(document.fetched_data, next_month[1], next_month[0]) && !planyo_isset(document.fetching_data, next_month[1], next_month[0])) {
	req_data += "&month2=" + next_month[0] + "&year2=" + next_month[1];
	js_mark_fetching_data (next_month[0], next_month[1], true);
      }
      var next_month_2 = planyo_get_next_month (next_month[0], next_month[1]);
      if (!planyo_isset(document.fetched_data, next_month_2[1], next_month_2[0]) && !planyo_isset(document.fetching_data, next_month_2[1], next_month_2[0])) {
	req_data += "&month3=" + next_month_2[0] + "&year3=" + next_month_2[1];
	js_mark_fetching_data (next_month_2[0], next_month_2[1], true);
      }
      var prev_month = planyo_get_prev_month (month, year);
      if (!planyo_isset(document.fetched_data, prev_month[1], prev_month[0]) && !planyo_isset(document.fetching_data, prev_month[1], prev_month[0])) {
	req_data += "&month4=" + prev_month[0] + "&year4=" + prev_month[1];
	js_mark_fetching_data (prev_month[0], prev_month[1], true);
      }
    }
    if (document.fetch_data_ver)
      req_data += "&ver="+document.fetch_data_ver;
    if (document.resource_id)
      req_data += "&resource_id="+document.resource_id;
    else if (document.limited_resources)
      req_data += "&limited_resources="+document.limited_resources;
    if (!js_is_admin_panel ())
      req_data += "&grouped=1";
    if (document.separate_units)
        req_data += "&separate-units=1";
    var xhr_req = new Request.JSON (
		{
		       url:req_url+"?"+req_data,
		       onComplete: function (obj) {
			   set_cursor ('default');
			   if (!obj)
			     return;
			   js_save_fetched_data (obj['month'], obj['year'], obj);
			   for (var m = 2; m <= 4; m++) {
			   if (planyo_isset (obj, 'month'+m))
			     js_save_fetched_data (obj['month'+m]['month'], obj['month'+m]['year'], obj['month'+m]);
			   }
			   js_update_views();
			 }
		}).send();
  }
}

function js_planyo_start () {
  document.debug_mode = false;
  document.debug_log = '';
  document.texts = new Array();
  document.texts ['all_day']= document.s_allday ? document.s_allday : 'All day';
  document.texts ['vacation'] = document.s_vacation ? document.s_vacation : 'Vacation';
  
  document.fetched_data = new Array(); // ajax-fed data
  document.fetching_data = new Array(); // let's not send multiple ajax requests for the same time period
  document.resource_usage = new Array(); // gives complete data over resource usage
  document.vacations = new Array(); // resource vacations
  document.time_data_month = new Array();
  document.time_data_day = new Array();
  document.start_day_restrictions = new Array();
  document.deps = null;
  if (!planyo_isset (document.month_view_max_items))
    document.month_view_max_items = 3;
  if (!planyo_isset (document.calendar_type))
    document.calendar_type = calendar_type_all_resources_grouped;
  if (!document.getElementById ('horizontal_calendar') && !document.getElementById ('calendar_nav') && document.force_view_mode)
    js_set_view_mode (document.active_view_mode, true);
  else if (!document.getElementById ('horizontal_calendar') && !document.getElementById ('calendar_nav') && Cookie.read ('mode')) 
    js_set_view_mode (parseInt (Cookie.read ('mode')), true);
  else if (!planyo_isset (document.active_view_mode))
    js_set_view_mode (view_mode_month, true);
  var nav_cookie = null;
  if (!document.getElementById('horizontal_calendar'))
    nav_cookie = Cookie.read ('nav');
  if (document.default_date) {
    js_nav (document.active_view_mode == view_mode_month ? null : document.default_date [2], document.default_date [1], document.default_date [0]);
  }
  else if (nav_cookie) {
    var nav = JSON.decode (nav_cookie);
    js_nav (document.active_view_mode == view_mode_month ? null : (nav [2] ? parseInt (nav [2]) : 1), parseInt (nav [1]), parseInt (nav [0]));
  }
  else {
    js_nav ('now');
  }
  js_show_calendar_nav ();
  js_show_horizontal_calendar(null, null, null, document.resource_id);
  js_show_horizontal_day_view(null, null, null, document.resource_id);
}

function js_clear_log () {
  document.debug_log = '';
}

window.addEvent('load', js_planyo_start);

