function Booking(locString)
{
    this.rowDetails = document.getElementById( "rowDetails" );
    this.tblDetails = document.getElementById( "tblBookingDetails" );
    this.rooms = new Array();
    this.rooms[ "superior" ] = {
	units : 0,
	details : new Array(),
	name : locStrings[ "superior" ],
	tag : "superior",
	max : locStrings[ "max_superior" ]
    };
    this.rooms[ "classic" ] = {
	units : 0,
	details : new Array(),
	name : locStrings[ "classic" ],
	tag : "classic",
	max : locStrings[ "max_classic" ]
    };
    this.rooms[ "comfort" ] = {
	units : 0,
	details : new Array(),
	name : locStrings[ "comfort" ],
	tag : "classic",
	max : locStrings[ "max_comfort" ]
    };

    this.errors = new Array();
    this.errors[ "err_emptyName" ] = locString[ "err_emptyName" ];
    this.errors[ "err_emptySurname" ] = locString[ "err_emptySurname" ];
    this.errors[ "err_emptyEmail" ] = locString[ "err_emptyEmail" ];
    this.errors[ "err_invalidEmail" ] = locString[ "err_invalidEmail" ];
    this.errors[ "err_emptyPhone" ] = locString[ "err_emptyPhone" ];
    this.errors[ "err_wrongDates" ] = locString[ "err_wrongDates" ];
    this.errors[ "err_invertedDates" ] = locString[ "err_invertedDates" ];
    this.errors[ "err_noRooms" ] = locString[ "err_noRooms" ];
    this.errors[ "err_noGuests" ] = locString[ "err_noGuests" ];
    this.errors[ "err_pvcWarning" ] = locString[ "err_pvcWarning" ];
}

Booking.prototype.refresh = function()
{
    if( !this.rowDetails )
	this.rowDetails = document.getElementById( "rowDetails" );

    if( !this.tblDetails )
	this.tblDetails = document.getElementById( "tblBookingDetails" );
}

Booking.prototype.onNumRooms = function(room_type, field)
{
    this.refresh();

    var quantity = field.value;

    if( (isNaN( quantity )) || (quantity < 0) ) {
	field.value = this.rooms[ room_type ].units;
	window.setTimeout( "var f = document.getElementById( \"" + field.name + "\"); f.focus(); f.select();", 100 );
	return false;
    }

    if( !this.rooms[ room_type ] ) {
	return false;
    }

    this.rooms[ room_type ].units = quantity;
    this.rooms[ room_type ].details.length = this.rooms[ room_type ].units;

    for( var j = 0; j < this.rooms[ room_type ].details.length; j ++ ) {
	if( !this.rooms[ room_type ].details[ j ] ) {
	    this.rooms[ room_type ].details[ j ] = new Array();
	    this.rooms[ room_type ].details[ j ][ "adults" ] = 0;
	    this.rooms[ room_type ].details[ j ][ "children" ] = 0;
	    this.rooms[ room_type ].details[ j ][ "infants" ] = 0;
	}
    }

    this.validateDetails();
}

Booking.prototype.initNumField = function(name, val)
{
    var fld = document.createElement( "INPUT" );
    fld.type = "text";
    fld.size = "3";
    fld.name = name;
    fld.id = name;
    fld.value = val;
    setEventHandler( fld, "change", function() {
			booking.onNumGuests(fld);
		     } );
    return fld;
}

Booking.prototype.onNumGuests = function(field)
{
    if( (isNaN( field.value )) || (field.value < 0) ) {
	// TODO: error
	field.value = "0";
	window.setTimeout( "var f = document.getElementById( \"" + field.name + "\"); f.focus(); f.select();", 100 );
	return false;
    }

    var path = new String( field.name ).split( "_" );

    if( path.length != 3 ) {
	// TODO: exception
	return false;
    }

    var roomType = path[0];
    var roomIdx = path[1];
    var guestType = path[2];

    if( this.rooms[ roomType ] !== undefined ) {
	if( this.rooms[ roomType ].details !== undefined ) {
	    if( this.rooms[ roomType ].details.length !== undefined ) {
		if( this.rooms[ roomType ].details.length > roomIdx ) {
		    if( guestType != "infants" ) {
			var other = new Number();

			if( guestType != "adults" )
			    other = other + new Number( this.rooms[ roomType ].details[ roomIdx ][ "adults" ] );

			if( guestType != "children" )
			    other = other + new Number( this.rooms[ roomType ].details[ roomIdx ][ "children" ] );

			if( (other + new Number( field.value ) ) > this.rooms[ roomType ].max ) {
			    // TODO: note the error
			    field.value = this.rooms[ roomType ].max - other;
			    window.setTimeout( "var f = document.getElementById( \"" + field.name + "\"); f.focus(); f.select();", 100 );
			}

			var rem = this.rooms[ roomType ].max - (other + new Number( field.value ) );
			var fldRem = document.getElementById( this.rooms[ roomType ].tag + "_" + roomIdx + "_rem" );

			if( fldRem )
			    fldRem.innerHTML = new String( rem );
		    }

		    this.rooms[ roomType ].details[ roomIdx ][ guestType ] = new Number( field.value );
		}
	    }
	}
    }
}

Booking.prototype.initRemField = function(name, val)
{
    var fld = document.createElement( "SPAN" );
    fld.id = name;
    fld.innerHTML = new String( val );
    return fld;
}

Booking.prototype.setRoomRows = function(room)
{
    for( var j = 0; j < room.units; j ++ ) {
	var row = document.createElement( "tr" );
	var cellName = document.createElement( "td" );
	var cellAdults = document.createElement( "td" );
	var cellChildren = document.createElement( "td" );
	var cellInfants = document.createElement( "td" );
	var cellBeds = document.createElement( "td" );
	var fldAdults = this.initNumField( room.tag + "_" + j + "_adults", room.details[ j ][ "adults" ] );
	var fldChildren = this.initNumField( room.tag + "_" + j + "_children", room.details[ j ][ "children" ] );
	var fldInfants = this.initNumField( room.tag + "_" + j + "_infants", room.details[ j ][ "infants" ] );
	var spanRem = this.initRemField( room.tag + "_" + j + "_rem",
	    room.max - (room.details[ j ][ "adults" ] +
			room.details[ j ][ "children" ]) );
	cellName.innerHTML = room.name + " " + (j+1);
	cellAdults.appendChild( fldAdults );
	cellChildren.appendChild( fldChildren );
	cellInfants.appendChild( fldInfants );
	cellBeds.appendChild( spanRem );
	row.appendChild( cellName );
	row.appendChild( cellAdults );
	row.appendChild( cellChildren );
	row.appendChild( cellInfants );
	row.appendChild( cellBeds );
	this.tblDetails.tBodies[0].appendChild( row );
    }
}

Booking.prototype.validateDetails = function()
{
    var totalRooms = 0;

    totalRooms += this.rooms[ "superior" ].units;
    totalRooms += this.rooms[ "classic" ].units;
    totalRooms += this.rooms[ "comfort" ].units;

    if( totalRooms <= 0 ) {
	this.rowDetails.style.display = "none";
	this.tblDetails.style.display = "none";
	return;
    }

    // show the grid
    this.rowDetails.style.display = "";
    this.tblDetails.style.display = "";

    // reset
    while( this.tblDetails.tBodies[0].rows.length > 0 )
	this.tblDetails.tBodies[0].deleteRow( 0 );

    this.setRoomRows( this.rooms[ "superior" ] );
    this.setRoomRows( this.rooms[ "classic" ] );
    this.setRoomRows( this.rooms[ "comfort" ] );
}

Booking.prototype.addError = function(field, err)
{
    var p;

    if( field.parentNode !== undefined )
	p = field.parentNode;
    else if( field.parentElement !== undefined )
	p = field.parentElement;

    if( !p ) return;

    var imgErr = document.createElement( "IMG" );
    imgErr.src = "/layout/error.jpg";
    imgErr.width = 16;
    imgErr.height = 16;
    imgErr.border = "0";
    imgErr.title = err;
    imgErr.alt = err;
    imgErr.style.marginLeft = "6px";
    imgErr.style.marginBottom = "0px";
    imgErr.style.position = "relative";
    imgErr.style.top = "2px";
    p.appendChild( imgErr );
}

Booking.prototype.resetErrors = function()
{
    var imgs = document.getElementsByTagName( "IMG" );
    var torem = new Array();

    for( var j = 0; j < imgs.length; j ++ ) {
	if( imgs[ j ].src.indexOf( "/layout/error.jpg" ) != -1 ) {
	    torem[ torem.length ] = imgs[ j ];
	}
    }

    for( var j = 0; j < torem.length; j ++ ) {
	var p;

	if( torem[ j ].parentNode !== undefined )
	    p = torem[ j ].parentNode;
	else if( torem[ j ].parentElement !== undefined )
	    p = torem[ j ].parentElement;

	p.removeChild( torem[ j ] );
    }
}

Booking.prototype.onSubmit = function(frm)
{
    this.resetErrors();
    var res = true;

    if( frm[ "NomeMittente" ].value == "" ) {
	this.addError( frm[ "NomeMittente" ], this.errors[ "err_emptyName" ] );
	res = false;
    }

    if( frm[ "CognomeMittente" ].value == "" ) {
	this.addError( frm[ "CognomeMittente" ], this.errors[ "err_emptySurname" ] );
	res = false;
    }

    if( frm[ "Email" ].value == "" ) {
	this.addError( frm[ "Email" ], this.errors[ "err_emptyEmail" ] );
	res = false;
    } else {
	var mask = /^([_a-zA-Z0-9-]+)(\.[_a-zA-Z0-9-]+)*@([a-zA-Z0-9-]+)(\.[a-zA-Z0-9-]+)*(\.[a-zA-Z]{2,4})$/;
	if( !mask.test( frm[ "Email" ].value ) ) {
	    this.addError( frm[ "Email" ], this.errors[ "err_invalidEmail" ] );
	    res = false;
	}
    }

    if( frm[ "Telefono" ].value == "" ) {
	this.addError( frm[ "Telefono" ], this.errors[ "err_emptyPhone" ] );
	res = false;
    }

    var day1, day2, today;

    today = new Date();
    day1 = new Date();
    day2 = new Date();

    day1.setFullYear( today.getFullYear(), new Number( frm[ "DaMese" ].options[ frm[ "DaMese" ].selectedIndex ].value ) - 1, frm[ "DaGiorno" ].options[ frm[ "DaGiorno" ].selectedIndex ].value );
    day2.setFullYear( today.getFullYear(), new Number( frm[ "AlMese" ].options[ frm[ "AlMese" ].selectedIndex ].value ) - 1, frm[ "AlGiorno" ].options[ frm[ "AlGiorno" ].selectedIndex ].value );

    if( day1 < today ) {
        day1.setFullYear( today.getFullYear() + 1, new Number( frm[ "DaMese" ].options[ frm[ "DaMese" ].selectedIndex ].value ) - 1, frm[ "DaGiorno" ].options[ frm[ "DaGiorno" ].selectedIndex ].value );
        day2.setFullYear( today.getFullYear() + 1, new Number( frm[ "AlMese" ].options[ frm[ "AlMese" ].selectedIndex ].value ) - 1, frm[ "AlGiorno" ].options[ frm[ "AlGiorno" ].selectedIndex ].value );
    } else if( day2 < day1 ) {
        day2.setFullYear( today.getFullYear() + 1, new Number( frm[ "AlMese" ].options[ frm[ "AlMese" ].selectedIndex ].value ) - 1, frm[ "AlGiorno" ].options[ frm[ "AlGiorno" ].selectedIndex ].value );
    }

    if( day1 <= today ) {
	this.addError( frm[ "AlMese" ], this.errors[ "err_wrongDates" ] );
	res = false;
    } else if( day1 > day2 ) {
	this.addError( frm[ "AlMese" ], this.errors[ "err_invertedDates" ] );
	res = false;
    } else if( day1 == day2 ) {
	this.addError( frm[ "AlMese" ], this.errors[ "err_wrongDates" ] );
	res = false;
    } else if( day1.getDate() != frm[ "DaGiorno" ].options[ frm[ "DaGiorno" ].selectedIndex ].value ) {
	this.addError( frm[ "AlMese" ], this.errors[ "err_wrongDates" ] );
	res = false;
    } else if( day2.getDate() != frm[ "AlGiorno" ].options[ frm[ "AlGiorno" ].selectedIndex ].value ) {
	this.addError( frm[ "AlMese" ], this.errors[ "err_wrongDates" ] );
	res = false;
    } else if( (day1.getDate() == day2.getDate()) && (day1.getMonth() == day2.getMonth()) && (day1.getFullYear() == day2.getFullYear()) ) {
	this.addError( frm[ "AlMese" ], this.errors[ "err_wrongDates" ] );
	res = false;
    }

    if( (this.rooms[ "superior" ].units <= 0) &&
	(this.rooms[ "classic" ].units <= 0) &&
	(this.rooms[ "comfort" ].units <= 0) ) {
	this.addError( frm[ "n_superior" ], this.errors[ "err_noRooms" ] );
	this.addError( frm[ "n_classic" ], this.errors[ "err_noRooms" ] );
	this.addError( frm[ "n_comfort" ], this.errors[ "err_noRooms" ] );
    } else {
	if( !this.checkGuests( this.rooms[ "superior" ] ) )
	    res = false;
	if( !this.checkGuests( this.rooms[ "classic" ] ) )
	    res = false;
	if( !this.checkGuests( this.rooms[ "comfort" ] ) )
	    res = false;
    }

    if( !frm[ "privacy" ].checked ) {
	alert( this.errors[ "err_pvcWarning" ] );
	res = false;
    }

    if( res ) {
	frm.action = "/php/booking.php";
    }

    return res;
}

Booking.prototype.checkGuests = function(room)
{
    var res = true;

    for( var j = 0; j < room.details.length; j ++ ) {
	if( (room.details[ j ][ "adults" ] <= 0) &&
	    (room.details[ j ][ "children" ] <= 0) ) {
	    var fld = document.getElementById( room.tag + "_" + j + "_adults" );

	    if( fld ) { 
		this.addError( fld, this.errors[ "err_noGuests" ] );
		res = false;
	    }
	}
    }

    return res;
}


