<?xml version="1.0" encoding="UTF-8" ?> 
<Module> 
<ModulePrefs 
	title="Hostel Reservations"
	directory_title="Availability"
	description="Free availability calendar for hostels."
        title_url="http://www.ineedtogetaproperdomain.info/"
	author="Alejo Sanchez"
	height="215">
	<Require feature="setprefs" />
 </ModulePrefs>
<Content type="html"> 
<![CDATA[

<!--

    Copyright 2009 Alejo Sanchez info@alejosanchez.com

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

 -->
<style type="text/css">

.asone {
display: inline-block;
}

table.results td {
    text-align: center;
    border: solid;
    border-width: 1px;
}

.check {
    color: #00FF00; /* green */
    background-color: #003300;
}

.cross {
    color: #FF0000; /* red */
    background-color: #330000;
}

td.sunday {
    background-color: #6666FF;
}

</style>

<div class="asone">
Pasajeros:

<select id="guests">
    <option value="1">1</option>
</select>
</div> <!-- guestblock -->

<div class="asone">

Noches:

<select id="nights">
    <option value="1">1</option>
</select>
</div> <!-- nightsblock -->

<div class="asone">

Arribo:

<select id="days">
    <option value="1">1</option>
</select>

<select id="months" onchange="resetDays()">
    <option value="1">Enero</option>
</select>

<select id="years" onchange="resetDays()">
    <option value="2009">2009</option> <!-- put something here -->
</select>

<button type="find" onclick="findAvailability()">Buscar</button>

</div> <!-- arriveblock -->

<br>

<div id="result"></div>

<div id="reservationForm"></div>

<script>
/*
 *  Check availability for hostel.
 *
 */

/*
 * Add getDOY() to get day of year from Date()
 */
Date.prototype.getDOY = function() {
    var onejan = new Date(this.getFullYear(),0,1);
    return Math.ceil((this - onejan) / 86400000);
} 

var BASEROW = 3;       // first two rows of spreadsheet are titles
var TOTALDAYS = 15;    // maximum total days to display, max from select + 1
var DEFAULTNIGHTS = 2; // default nights to search for
var MAXGUESTS = 14;    // maximum guests to allow

var weekDayInitialES = [ "D", "L", "M", "M", "J", "V", "S" ];
var weekDaysShortES = ['Do', 'Lu', 'Ma', 'Mi', 'Jue', 'Vie', 'Sa' ];
var weekDayLongES = [ "Domingo", "Lunes", "Martes", "Mi&eacute;rcoles",
    "Jueves", "Viernes", "S&aacute;bado" ];
var monthShortES = [ "Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Aug",
    "Sep", "Oct", "Nov", "Dec" ];
var monthLongES = [ "Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio",
    "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre" ];

var now = new Date();   // Right now, including seconds
var today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
var baseYear = now.getFullYear();

var check = '&#10003;';     // HTML check mark
var cross = '&#10007;';     // HTML cross (ballot) mark
var emptyCheck = '&#9744;'; // HTML empty check box

var guests = document.getElementById('guests');
var nights = document.getElementById('nights');

var days = document.getElementById('days');
var months = document.getElementById('months');
var years = document.getElementById('years');

var result = document.getElementById('result');
var reservationForm = document.getElementById('reservationForm');

// Some constants to do date arithmetic
var oneMinute = 60 * 1000;
var oneHour = oneMinute * 60;
var oneDay = oneHour * 24;
//var oneWeek = oneDay * 7;


function callMeMartha(cells) {

    // We got the cells from spreadsheet

    while(result.hasChildNodes())
        result.removeChild(result.firstChild); // remove previous result

    var arrival = new Date(years.selectedIndex + baseYear, months.selectedIndex,
            days.selectedIndex + 1);
    var num_guests = guests.selectedIndex + 1;
    var num_nights = nights.selectedIndex + 1;

    var firstInList = new Date(arrival.getTime() - oneDay); // one extra before
    var lastInList = new Date(firstInList.getTime() + ((TOTALDAYS - 1) * oneDay) );

    var missingRoom = 0; // if there are missing rooms, don't offer reserve

    var t = document.createElement('table');
    t.className = 'results';

    // IE demands tbody, then other browsers reserve space for footer/header
    var th = document.createElement("thead"); th.style.height = '0px';
    var tb = document.createElement('tbody');
    var tf = document.createElement("tfoot"); tf.style.height = '0px';
    t.appendChild(th); t.appendChild(tb); t.appendChild(tf);
    

    var tr = document.createElement('tr');

    function getTd(row, innerHTML, style) {

        var td = document.createElement('td');
        td.innerHTML = innerHTML;
        if (style)
            td.className = style;
        row.appendChild(td);
    }

    // Fill header row
    for (var d = firstInList; d.getTime() <= lastInList.getTime();) {

        getTd(tr, weekDaysShortES[d.getDay()] + '<br>' + d.getDate(),
                d.getDay() == 0 ? 'sunday' : '');

        d = new Date(d.getTime() + oneDay); // next
    }

    tb.appendChild(tr);
    var tr = document.createElement('tr'); // next row

    // Now availability

    getTd(tr, emptyCheck, '');

    for (k in cells.feed.entry) {

        // fill availability squares: check, cross
        if (num_guests <= cells.feed.entry[k].content['$t']) {

            getTd(tr, check, 'check');

        } else {

            getTd(tr, cross, 'cross');
            missingRoom++;

        }
    }

    // Pad days after range requested
    for (var d = (cells.feed.entry.length + 1) ; d < TOTALDAYS; d++)
        getTd(tr, emptyCheck, '');

    tb.appendChild(tr);
    result.appendChild(t); // Add the results table
    result.appendChild(document.createElement('br'));

    // XXX finish
    if (missingRoom) {

        result.appendChild(document.createTextNode('Lamentablemente no hay disponibilidad en este'
            + 'momento para el pedido solicitado.'));
        return;
    }

    // Create the form to perform the request
    function getInput(type, name, value) {
        var i = document.createElement('input');
        i.setAttribute('type', type);
        i.setAttribute('name', name);
        i.setAttribute('value', value);
        return i;
    }

    var f = document.createElement('form');
    f.setAttribute('method', 'POST');
    f.setAttribute('action',
            'http://spreadsheets.google.com/formResponse?key=pFRjNDW1OAkxwnvo815qhUg');

    function formLine(form, textNodeName, inputName) {

        var d = document.createElement('div');
        d.className = 'asone';
        d.appendChild(document.createTextNode(textNodeName));
        d.appendChild(getInput('text', inputName, ''));
        form.appendChild(d);
    }

    formLine(f, 'Your full name (required): ', 'entry.0.single');
    formLine(f, 'Your email (required): ', 'entry.1.single');
    formLine(f, 'Your phone (optional): ', 'entry.2.single');

    f.appendChild(getInput('hidden', 'entry.3.single', num_guests));
    f.appendChild(getInput('hidden', 'entry.4.single', num_nights));
    f.appendChild(getInput('hidden', 'entry.5.single',
            arrival.toDateString().substring(0,15)));

    f.appendChild(document.createElement('br'));
    f.appendChild(getInput('submit', 'submitButton', 'Reserve'));

    result.appendChild(f); // Add the form after the results

}


function getScript(url){

    // Create a script tag (and hope they won't fsck up
    var scriptTag = document.createElement("script");
    scriptTag.setAttribute("type", "text/javascript");
    scriptTag.setAttribute("src", url);
    document.getElementsByTagName("head")[0].appendChild(scriptTag);

}

function findAvailability() {

    // get data to search
    var arrival = new Date(years.selectedIndex + baseYear, months.selectedIndex,
            days.selectedIndex + 1);

    // var num_guests = guests.selectedIndex + 1;
    var num_nights = nights.selectedIndex; // Don't +1 since 1st is there

    if (arrival.getFullYear() > baseYear && arrival.getDOY() > 30) {

        result.innerHTML = 'Date is too far in the future';
        return;

    } else if (arrival.getTime() < today.getTime()) {

        result.innerHTML = 'Date is in the past';
        return;

    }

    // calculate position
    var spreadsheetDayCellRowStart = arrival.getDOY() + BASEROW;
    var spreadsheetDayCellRowEnd = arrival.getDOY() + num_nights + BASEROW;

    // Get the values as a dynamic script tag (hack) with callback
    getScript('http://spreadsheets.google.com/feeds/cells/'
            + 'pFRjNDW1OAkxZiUO1uzKTVQ/2/public/values/?alt=json-in-script&'
            + 'range=B' + spreadsheetDayCellRowStart + ':B'
            + spreadsheetDayCellRowEnd + '&callback=callMeMartha');

}

function refillSelect(theSel, values, selected) {

    // empty previous values
    for (var i = 0; i < theSel.length; i++)
        theSel.remove(i);

    // fill in new values
    for (var i = 0; i < values.length; i++)
        theSel[i] = new Option(values[i], i);

    theSel.selectedIndex = selected; // set preset value
}

// Make a list from a supplied range
function range(min, max) {
    var ret = [];
    for (var i = min; i <= max; i++)
        ret.push(i);
    return ret;
}

function daysInMonth(iMonth, iYear) {

    // from http://snippets.dzone.com/posts/show/2099
	return 32 - new Date(iYear, iMonth, 32).getDate();
}

function resetDays() {

    var current_day = days.selectedIndex;

    // reset days to match month and year (e.g. Feb 28...)
    refillSelect(days, range(1, daysInMonth(months.selectedIndex,
                    years[years.selectedIndex].value)), 1);

    // Try to keep the selected day, or closest match
    if (days.length < current_day)
        days.selectedIndex = days.length - 1;
    else
        days.selectedIndex = current_day;
}

function sendRequest() {
    // Send a message requesting reservation
    // XXX
}

// Run

refillSelect(years, [baseYear, baseYear + 1], 0);
refillSelect(months, monthLongES, now.getMonth());

// Set this month number of days and preselect today
refillSelect(days, range(1, daysInMonth(now.getMonth(), now.getFullYear())),
        now.getDate() - 1);

refillSelect(nights, range(1, TOTALDAYS -1), DEFAULTNIGHTS - 1);

refillSelect(guests, range(1, MAXGUESTS), 0);

</script>

]]>
</Content>
</Module>
