

    var SpecialOffer = makeClass();
	
	function setGlobalSpecialOfferVars(){
		
		if (typeof window.BOOKING_FORM_HTML === "undefined") {
			window.BOOKING_FORM_HTML = $('#BookingContainerDiv').html();
			$('#BookingContainerDiv').empty();
		}
		
		if (typeof window.CURRENT_SO === "undefined") {
			window.CURRENT_SO = {};
		}

	}
	
	function bookNow() {
		
		// -- when the user hits 'book now'
        var airportDD = $("#sOfferDepartureAirport");
        var errorTxt = $("#noSelectedAirport");

        if (airportDD !== null && airportDD.val() == "-") {
            errorTxt.html("<span>Please select an airport.</span>");
            errorTxt.show();
            return false;
        }
        return true;

	};
	
	/**
	 * SpecialOffer - reusable class that controls a single special offer 
	 * 
	 * requires ;
	 * 		- jquery.js
	 * 		- vh.util.js
	 */
	
    SpecialOffer.prototype = {
		
		_data : {}, // JSON object that holds all Special Offer Data
		appended : false // flag if we've already appended the booking form
		
    };
    
	SpecialOffer.prototype.init = function( SpecialOfferJSON ) {
		
		// ref
		var self = this;
		
		// guard
		if (VH.UTIL.isUndefinedOrNull(SpecialOfferJSON)) {
			return;
		}
		
		// set the data for this instance	
		self._data = SpecialOfferJSON;

		self.InitControls();

	};

	SpecialOffer.prototype.InitControls = function() {

	    var so = this;
	    var openBtn = $(so._data.offerCellId + " td.book a.moreinfo");

	    // set href, click and show button
	    if (!VH.UTIL.isUndefinedOrNull(so._data.useAnchor)) {
	        openBtn.attr("href", so._data.offerCellId)
	    }

	    // click and show button
	    openBtn.click(function(e) {
	   
	        if (VH.UTIL.isUndefinedOrNull(so._data.useAnchor)) {
	            e.preventDefault();
	        }
	        // is there a form open?
	        if (!VH.UTIL.isUndefinedOrNull(CURRENT_SO.UnloadBookingForm)) {
	            CURRENT_SO.UnloadBookingForm();
	        }
	        CURRENT_SO = so;
	        so.LoadBookingForm();

	      
	    }).show();

	};

	SpecialOffer.prototype.UnloadBookingForm = function() {

	    var so = this;
	    var formCell = $(so._data.bookingFormCellId);
	    var offerCell = $(so._data.offerCellId);

	    // do we need to close the hotel info? (/special_offers/)
	    if (so._data.hotelInfoCellId !== '') {
	        $(so._data.hotelInfoCellId).hide();
	    }

	    formCell.hide();
	    formCell.empty();

	    offerCell.removeClass("CurrentOffer");
	    offerCell.find("td:first").css({ "border-left": "none" });
	    offerCell.find("td:last").css({ "border-right": "none" });

	    var closeBtn = null;

	    if (so._data.mainSo) { // is /special_offers/
	        closeBtn = offerCell.find("td.book a.moreinfo");
	        closeBtn.find("img").attr("src", "/_assets/images/special_offers/more_info.gif");
	    } else { // is /special_offers/carribean/
	        closeBtn = formCell.find(".shrink a");
	    }

	    closeBtn.unbind();
	    closeBtn.click(function(e) {
	        if (VH.UTIL.isUndefinedOrNull(so._data.useAnchor)) {
	            e.preventDefault();
	        }
	        // is there a form open?
	        if (!VH.UTIL.isUndefinedOrNull(CURRENT_SO.UnloadBookingForm)) {
	            CURRENT_SO.UnloadBookingForm();
	        }
	        CURRENT_SO = so;
	        so.LoadBookingForm();
	    }).show();


	    so.appended = false;

	};

	SpecialOffer.prototype.LoadBookingForm = function() {

	    var so = this;
	    
	    // get the right table cell id and append the booking form 
	    var formCell = $(so._data.bookingFormCellId);
	    var offerCell = $(so._data.offerCellId);
	    if (!so.appended) {
	        formCell.append('<td colspan="9" style="padding:0;">' + BOOKING_FORM_HTML + '</td>');
	        so.appended = true;
	    }

        
	    // set up close btn
	    var closeBtn = null;

	    if (so._data.mainSo) { // is /special_offers/
	        closeBtn = offerCell.find("td.book a.moreinfo");
	        closeBtn.find("img").attr("src", "/_assets/images/special_offers/less_info.gif");
	    } else { // is /special_offers/carribean/
	        closeBtn = formCell.find(".shrink a");
	    }

	    closeBtn.unbind();
	    closeBtn.click(function(e) {
	        e.preventDefault();
	        so.UnloadBookingForm();
	    });

	    // set up book now btn 
	    var bookBtn = formCell.find(".OfferButton");
	    bookBtn.click(function(e) {
	        return (bookNow());
	    });

	    // do we need to show the hotel info? (/special_offers/)
	    if (so._data.hotelInfoCellId !== '') {
	        $(so._data.hotelInfoCellId).show();
	    }

	    // init form
	    so.InitAirports();
	    so.WriteOfferDetails();
	    so.RenderCalendar();
	    so.UpdateHiddenFields();

	    offerCell.addClass("CurrentOffer");
	    offerCell.find("td:first").css({ "border-left": "1px solid #C00" });
	    offerCell.find("td:last").css({ "border-right": "1px solid #C00" });

	    formCell.show();

	    //create core metrics tag

	    var hotelInfo = $(so._data.hotelInfoCellId);
	    var hotelName = hotelInfo.find(".title h2").text();
	    if (hotelName.length == 0) {
	        hotelName = $('#a_name_' + so._data.mainAccom).find("span").text();
	    }
	    
	    var key = so._data.company + ":" + so._data.accomCode
	    var category = so._data.brochureName

	    cmCreatePropertyviewTag(key, hotelName, category);  
	};
	
	// -- returns an <option> for dropdowns
  	SpecialOffer.prototype.CreateOption = function(value, text, selected) {
         return '<option value="' + value + '">' + text + '</option>';
    };
	
	// -- takes a date string in the form  DD/MM/YYYY and returns a date object
	SpecialOffer.prototype.GetDate = function( date ) {
			var dateStr = date.split("/");
			return new Date(dateStr[2], dateStr[1] - 1, dateStr[0]);
	};

	// -- fills in details in the <ul />
	SpecialOffer.prototype.WriteOfferDetails = function() {

	    var so = this;

	    var hotelInfo = $(so._data.hotelInfoCellId);

	    var hotelName = hotelInfo.find(".title h2").text();

	    if (hotelName.length == 0) {
	        hotelName = $('#a_name_' + so._data.mainAccom).find("span").text();
	    }

	    // small text at bottom
	    $("#txtDestinationName").html("<br />" + hotelName);
	    $("#txtDuration").text(so._data.duration);
	    $("#txtDepartureDates").text(so._data.bookableFrom + " - " + so._data.bookableTo);

	    var tempAirports = so._data.origins.split("|");
	    var airportTxt = "";
	    for (var i = 0; i < tempAirports.length; i++) {
	        airportTxt += tempAirports[i].split("^")[1];
	        if (i + 1 < tempAirports.length) {
	            airportTxt += " or ";
	        }
	    }

	    $("#txtDepartureAirports").text(airportTxt);
	    $("#txtBoardBasis").text(so._data.board);
	    $("#Pax2who .adult").find("select").val("2");

	}; 
	
	// -- populates hidden booking form fields
	SpecialOffer.prototype.UpdateHiddenFields = function() {
		
		var so = this;
		var hotelName = $('#a_name_' + so._data.mainAccom).find("span").text();
		$("#sOfferMainAccom").val(so._data.mainAccom);
        $("#sOfferDestination").val(so._data.destination);
        $("#sOfferProgram").val(so._data.programId);
        $("#sOfferCompany").val(so._data.company);
        $("#sOfferDuration").val(so._data.duration);
        $("#sOfferHotelName").val(hotelName);
	};

    // -- populates the departure airport dropdown
    SpecialOffer.prototype.InitAirports = function() {
		
		var so = this;
        var arr = so._data.origins.split("|");
		var airportDD = $("#sOfferDepartureAirport");

        airportDD.empty();
 
		// more than one airport?
		if ( arr.length > 1 ){
			airportDD.append('<option value="-">Please select</option>');
		} 
		
		for (var i = 0; i < arr.length; i++) {
        	airportDD.append(so.CreateOption(arr[i].split("^")[0], arr[i].split("^")[1]));
   	 	}
		
    };
	
	// -- render the calendar 	
	SpecialOffer.prototype.RenderCalendar = function (){
			
		var so = this;

		$("#staticCal").datepicker({
		
			// basic options
            rangeSelect: false, // no date range selection
            numberOfMonths: 1, // no. of calendars to show
            yearRange: '-0:+2', // sets to current year + 2
            firstDay: 1, // sets to Monday
            changeFirstDay: false, // disable links on days of week
            hideIfNoPrevNext: true, // hide links
            speed: '', // just show it

            // min, max and formatting
            minDate: so.GetDate(so._data.bookableFrom), // earliest selectable date 
            maxDate: so.GetDate(so._data.bookableTo), // latest selectable date 
            setDate: so.GetDate(so._data.bookableFrom), // default selected date
            dateFormat: 'D d M yy',
            dayNamesMin: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],

            // callbacks
            onRender: so.FixDisplay, // custom Zolv callback
            onSelect: so.UpdateForm
		
		});
		
		$("#sOfferDepartureDate").val(
			$.datepicker.formatDate('D d M yy', so.GetDate(so._data.bookableFrom))
		);
						
	};



	SpecialOffer.prototype.UpdateForm = function(date){
		$("#sOfferDepartureDate").val(date);
	};
	
	SpecialOffer.prototype.FixDisplay = function(){
	};
	
	
