/**
 * @author Lincoln
 
  Implements all the FlipKey namespace functions that can be expected globally using jQuery
 
 * Provides a namespace and common interface functions, including in all layouts
 * -Lightboxes
 * These are just contatiners, centered, over dark transparent bg, 100px from top of screen.
 * Right now there can be only one (kind of intended).
 * -Tabs
 * I wanted JS tabs that did nothing visual but automated the AJAX loading / table displays.
 * I also wanted them to redirect the user with anchor text so they can use back button, and be
 * directly sent to a certain tab.
 */
 
if (typeof FlipKey != "object") FlipKey = new Object();

Object.extend(FlipKey, 
{
    loader: new Image(),
    loader_src: '/img/ajax-loader.gif',
     
    //Shows a lightbox with a given string
    showLightboxText: function(textContent, close_button, loading_indicator, callback, width)
    {
        this.config = {};
        	
		var style;
        if (width) style = "width: " + width + "px";
        else style = ""
        this._lightBox('<div id="lightbox_default" style="' + style + '">' + textContent + '</div><br/>', close_button, loading_indicator, callback);
    },
    
    //Shows a lightbox with from a given existing div.  Bad idea for forms.
    showLightboxFromDiv: function(source_div, close_button, loading_indicator, callback)
    {
        this.config = {};
        
        if (typeof source_div == "string") source_div = $(source_div);
        source_div.setStyle({position: 'absolute', display: "block", top :  (Position.page(document.body)[1]*-1 + 100)  + 'px'});
        this.centerElement(source_div, document.body);
		this._box = source_div;
		if ($("lb_close")) $("lb_close").remove();
        if (close_button) this._box.innerHTML += '<div id="lb_close"><a class="small_button small_stroke_button small_brown_stroke" style="float:right; margin-bottom: 6px" onclick="FlipKey.closeLightbox()" ><span>Close</span></a><br/></div>';
        
        document.body.appendChild(this._box);
        this.addOpaque();
        this._box.show();
		
		if (typeof callback == "function") callback();
    },
    
    //Shows a lightbox from a given URL.  The parent div of this content needs a background color and definted width
    showLightboxAjax: function(url, close_button, loading_indicator, callback, _params, config)
    {
        this.showLightboxText('Loading...<br/>', false, true);
        
        if (!config) config = {};
        this.config = config;

        new Ajax.Request(url, {
            parameters: _params,
            onSuccess: 
            function(data) {
                FlipKey._lightBox(data.responseText, close_button, loading_indicator, callback)
            }
        });
               
    },
    
    //Removes a lightbox.  There can only be one
    closeLightbox: function()
    {
        if (typeof FlipKey.config.onClose == "function") FlipKey.config.onClose(); 
      	FlipKey._box.hide();
        Element.hide($('loading_opaque'));

    },
    
    addOpaque: function()
    {
    	if (!$('loading_opaque'))
    	{
        	var opaque = document.createElement('div');
            Element.extend(opaque);
            
        	opaque.id = 'loading_opaque';
            opaque.observe('click', FlipKey.closeLightbox);
            
    	    var styles = { 
                background: '#333333',
                width: '100%',
                position: 'fixed',
                display: 'block',
                height: '100%'
            };
            
            document.body.appendChild(opaque);
    	    $('loading_opaque').setStyle(styles);
    	}
    	else $('loading_opaque').setStyle({display: 'block'});
    	
    },
    
    _lightBox: function(textContent, close_button, loading_indicator, callback)
    {
        if ($('lightbox_container')) Element.remove($('lightbox_container')); 
                
        //Our tooltips would be on top of the opaque bg.
    	if (typeof hideTooltips == "function") hideTooltips();
    	
    	var styles = { 
                background: '#333333',
                display: 'block',
                width: '100%',
                height: document.documentElement.scrollHeight + "px"
            };
    	    	
        
    	//Using spans to prevent the 'div is as big as body' issue in IEs
    	var box = document.createElement('span');
    	box.id = 'lightbox_container'; 
    	box.innerHTML = textContent;
    	document.body.appendChild(box);
    	//document.body.insertBefore(box, document.body.childNodes[0]);
    	        
        var control_wrap = document.createElement('span');
        control_wrap.id = 'lightbox_control_wrap';
        
    	if (loading_indicator) {
            FlipKey.loader.src = FlipKey.loader_src;
            FlipKey.loader.className = "ajax_loader";
            control_wrap.appendChild(FlipKey.loader);
        }
        
        if (close_button) {
            control_wrap.innerHTML += '<a class="small_button small_stroke_button small_brown_stroke" style="float:right; margin-bottom: 6px" onclick="FlipKey.closeLightbox()" ><span>Close</span></a><br/>';
        }
        
        this.addOpaque();
        $('lightbox_container').descendants()[0].appendChild(control_wrap);
        
    	// set the style of the element so it is centered
    	styles = { 
    		top :  (Position.page(document.body)[1]*-1 + 100)  + 'px',
    		display: 'block'
    		
    	};
    
    	$('lightbox_container').setStyle(styles);			
    	this.centerElement($('lightbox_container'), document.body);
         
        this._box = $('lightbox_container');
		//console.log(typeof callback);
        if (typeof callback == "function") callback();      
    },
    
    //Simple lightbox updator w built in form post
    lightboxSubmit: function(form, url, update_el, callback)
    {
		if (!update_el) update_el = $('lightbox_container');
        new Ajax.Request(url, {
            parameters: form.serialize(true),
            method: 'POST',
            onSuccess: function(response){
                if (update_el) update_el.update(response.responseText);
                if (typeof callback == "function") callback();
            }});        
    },
    
    /*Creates the green/red message for success or failure, wants JSON like
    {status: 'saved|error|this will become the class of the div', text: [Goes in the div]}
    */
    lightboxMessage: function(message_div, response)
    {
        message_div.innerHTML = response.text;
        message_div.className = response.status;
        message_div.show();
        Effect.Fade(message_div, {delay: 2, duration: 2});
       
    },
    
    lightboxLoading: function()
  	{
  		var loader = new Element('div');
  		loader.id = "lightbox_loading";
  		loader.innerHTML = "Loading...";
  		this._box.appendChild(loader);
  	},
    
    //Prototype 1.5 is missing this.  Must add element to DOM before this works.
    centerElement: function(element, parent)
    {

        var w, h, pw, ph;
        var d = Element.getDimensions(element);
        w = d.width;
        h = d.height;
        Position.prepare();
        if (!parent) {
                var ws = Position.GetWindowSize();
                pw = ws[0];
                ph = ws[1];
        } else {
                pw = parent.offsetWidth;
                ph = parent.offsetHeight;
        }
        //Vertical centering still having issues.  Lightboxes are 100px from the top of the screen for now.
        //element.style.top = (ph/2) - (h/2) -  Position.deltaY + "px";
        element.style.left = (pw/2) - (w/2) -  Position.deltaX + "px";

    }
});

/*
 * The idea of FlipKey.Tabs is to create the tab markup as divs or spans with the calss "tab".
 * When new FlipKey.Tabs() is created, the div or spans will be made into tabs (functionally).
 * Whatever url you specify as the ajax attribute of that element will be loaded.  If you specify
 * the table attribute instead it makes a DataTable automatically.  See RBO rep manager.
 */

//Constructor for FlipKey Tabs.
FlipKey.Tabs = Class.create();
FlipKey.Tabs.prefix = "";

FlipKey.Tabs.prototype = 
{
    initialize: function()
    {     
        FlipKey.TABS = $$('.tab');
        
        if (!FlipKey.Tabs.prefix)
        	FlipKey.Tabs.prefix = "";
        
        if (document.location.hash.length <= 0) {
            if (FlipKey.TABS.length > 0) FlipKey.Tabs.changeTab(FlipKey.TABS[0], false, null);
        }
        else {
            FlipKey.ACTIVE_TAB = document.location.hash;
            FlipKey.ACTIVE_TAB = FlipKey.ACTIVE_TAB.replace('#/', '');
            
            if (FlipKey.ACTIVE_TAB != null && $(FlipKey.ACTIVE_TAB))
            {
            	FlipKey.Tabs.changeTab($(FlipKey.ACTIVE_TAB), false, null);
            }	
        }
        
        FlipKey.Tabs.listen();
        for (var i=0; i<FlipKey.TABS.length; i++)
        {
            FlipKey.TABS[i].onclick = function(){
                FlipKey.Tabs.changeTab(this.id, true, null);
            }
        }
    }
}

FlipKey.Tabs.loader = document.createElement('div');
FlipKey.Tabs.loader.id = "tab_loader";
FlipKey.Tabs.loadComplete = false;
FlipKey.tables = [];

//FlipKey.Tabs namespace methods
Object.extend(FlipKey.Tabs, 
{
    //Changes to the tab of the given id.  If redirect is given, we send them to that id as anchor text.
    changeTab: function(tab_id, redirect, callback)
    {
		//tab exists
		if (!tab_id || tab_id.length == 0 || !$(tab_id)) return false;

		FlipKey.Tabs.loadComplete = false;
        var active_tab = $(tab_id);
        FlipKey.ACTIVE_TAB = $(tab_id);
        if (active_tab.className == "tab") 
        {
            FlipKey.TABS.each(function(tab) {tab.className = "tab"});
            active_tab.className = "tab active";
            if (redirect) document.location = document.location.protocol + '//' + document.location.hostname + document.location.pathname + '#/' + FlipKey.ACTIVE_TAB.id;
            
            var element_id = FlipKey.Tabs.prefix + "tab_content";
            
            var ajax;
            if (ajax = Element.readAttribute(FlipKey.ACTIVE_TAB, "ajax")) 
            {
                $(element_id).appendChild(FlipKey.Tabs.loader);
                
                var html_callback = eval(Element.readAttribute(FlipKey.ACTIVE_TAB, "callback"));

                if (html_callback)
                {
                    if (typeof html_callback == "function") callback = html_callback;
                }
                new Ajax.Request(ajax, 
                		{onSuccess: 
		                    function(response) 
		                    {
		                        $(element_id).innerHTML = response.responseText;
		                        FlipKey.Tabs.loadComplete = true; 
		                        if (callback) callback(); 
		                        
		                    }
                		});
                    
            }
            
            
            var table;
            if (table = Element.readAttribute(FlipKey.ACTIVE_TAB, "datatable")) 
            {
                $(element_id).appendChild(FlipKey.Tabs.loader);
				
				if (typeof FlipKey.tables[FlipKey.ACTIVE_TAB.id] != "object")				
					FlipKey.tables[FlipKey.ACTIVE_TAB.id] = new DataTable({
						baseURL: table,
						element_id: element_id,
						limit: 20,
						dir: Element.readAttribute(FlipKey.ACTIVE_TAB, "dir"),
						page: 1,
						order_by: Element.readAttribute(FlipKey.ACTIVE_TAB, "order")
					});
				
				
				
				FlipKey.tables[FlipKey.ACTIVE_TAB.id].refresh();
				FlipKey.Tabs.loadComplete = true;
            }
        }        
    },
    
    //Refreshes tab user is on
    reloadTab : function()
    {
	    var ajax;
	    
	    var element_id = FlipKey.Tabs.prefix + "tab_content";
	    
        FlipKey.Tabs.loadComplete = false;
        if (ajax = Element.readAttribute(FlipKey.ACTIVE_TAB, "ajax")) 
        {
            
        	$(element_id).appendChild(FlipKey.Tabs.loader);
            
            var html_callback = eval(Element.readAttribute(FlipKey.ACTIVE_TAB, "callback"));

            if (typeof html_callback == "function") callback = html_callback;
            else callback = null;
           
            new Ajax.Updater(element_id, ajax, {onSuccess:  function () {FlipKey.Tabs.loadComplete = true; if (callback) callback();}, evalScripts:true });
        }
        
        var table;
        if (table = Element.readAttribute(FlipKey.ACTIVE_TAB, "datatable")) 
        {
            $(FlipKey.Tabs.prefix + 'tab_content').appendChild(FlipKey.Tabs.loader);
			
			if (typeof FlipKey.tables[FlipKey.ACTIVE_TAB.id] != "object")				
				FlipKey.tables[FlipKey.ACTIVE_TAB.id] = new DataTable({
					baseURL: table,
					element_id: FlipKey.Tabs.prefix + "tab_content",
					limit: 20,
					dir: Element.readAttribute(FlipKey.ACTIVE_TAB, "dir"),
					page: 1,
					order_by: Element.readAttribute(FlipKey.ACTIVE_TAB, "order")
				});
			
			FlipKey.tables[FlipKey.ACTIVE_TAB.id].refresh();
        }     
    },
    
    listen: function()
    {
        if (typeof FlipKey.ACTIVE_TAB == "undefined") return false;
        
        if (document.location.hash.length <= 0 || !$(FlipKey.ACTIVE_TAB)) FlipKey.Tabs.changeTab(FlipKey.TABS[0], false,null); 
        else if (document.location.hash != '#/' + FlipKey.ACTIVE_TAB.id) FlipKey.Tabs.changeTab(document.location.hash.replace('#/', ''), true, null); 
       
        if (!FlipKey.Tabs.loadComplete)
        	window.setTimeout("FlipKey.Tabs.listen()", 500);
    },
    
    /* Adds a message at the top of tab_content.  status should be either
      'success' or 'failure' */
    showMessage: function(status, message)
    {
	// Determine css class for message based on status
	if (status == 'success')
	{
	    message_html = '<p class="saved">';
	}
	else if (status == 'failure')
	{
	    message_html = '<p class="error">';
	}
	else
	{
	    throw("showMessage status parameter must be either 'success' or 'failure'. Provided: " + status);
	}
	
	// Remove all existing error messages
	errorMsgClasses = Array('saved', 'error');
	errorMsgClassesLength = errorMsgClasses.length - 1;
	for (x = 0; x <= errorMsgClassesLength; ++x)
	{
	    possible_error_classes = $$('#tab_content p.' + errorMsgClasses[x]);
	    if (possible_error_classes.length > 0)
	    {
		possible_error_classes[0].remove();
	    }
	}
	
	new Insertion.Top('tab_content', message_html + message + "</p>");
    }
}); 

FlipKey.loadAvailability = function(property_id)
{
    new Ajax.Request('/properties/calendar_ajax/' + property_id +'/' + new Date().getFullYear(), FlipKey.processAjax);
}

//Process JSON from /properties/calendar_ajax
FlipKey.processAjax = function(response)
{
	var year_hash = eval(response.responseText);
    FlipKey.booked_dates = year_hash.dates;
	FlipKey.calendar.render();
}

FlipKey.createDatePicker = function()
{
    Event.observe(window, 'load', function() {
    
    	Calendar.setup({
    		inputField:  'arrival_date',
    		button:      'arrival_calendar',
    		weekNumbers: false,
    		range:       [new Date().getFullYear(), new Date().getFullYear()+4],
            ifFormat: "%m-%d-%Y",
            align: "TR",
            onUpdate: selectArrival,
    		dateStatusFunc: FlipKey.disableDate,
            onOpen: function(cal) {calendar = cal}
    	});
    
    	Calendar.setup({
    		inputField:  'departure_date',
    		button:      'departure_calendar',
    		weekNumbers: false,
    		range:       [new Date().getFullYear(), new Date().getFullYear()+4],
            ifFormat: "%m-%d-%Y",
            align: "TR",
            onUpdate: selectDeparture,
    		dateStatusFunc: FlipKey.disableDate,
            onOpen: function(cal) {calendar = cal}
    	});
        
    });
}

// Disables past dates and uses date info from ajax
FlipKey.restoredArrivalDate = null;
FlipKey.disableDate = function(date, year, month, day)
{
    if (calendar.params.inputField.id == "arrival_date") var mode = "arrival";
	else var mode = "departure";
	
   //Disable arrival date for departure calendar 
   if (mode == 'departure')
   {
       //First step - Natural select case 
       if (FlipKey.arrival_date && (date <= FlipKey.arrival_date))
       {
           return "disabled";
       }
       //Second step - Dates was restore from inputs
       else if ($('arrival_date') && $('arrival_date').value.length)
       {
           if (!(FlipKey.restoredArrivalDate)) 
           {
               var a = $('arrival_date').value.toString().split("-");
              //create arrival date object and store it for compute only once
               FlipKey.restoredArrivalDate = new Date(parseInt(a[2]),parseInt(a[0] - 1),parseInt(a[1]));
           }
           if (date <=  FlipKey.restoredArrivalDate ) return "disabled";
       }
   }

   //Allow today to be booked, only disable if given dates numerical day is less than todays numercal day
	if (date < new Date() && !(date.getDate() == new Date().getDate() && date.getMonth() == new Date().getMonth() && date.getFullYear() == new Date().getFullYear())) return "disabled";

	
	if (!FlipKey.booked_dates) return "";

	if (FlipKey.booked_dates[year] == "none" || !FlipKey.booked_dates[year]) return "";

	if (FlipKey.booked_dates[year][month])
	{
	    if (mode == "departure") {
			if (FlipKey.booked_dates[year][month][day] == 2) {
				return "disabled";
			}
		}
		else if (mode == "arrival") {
			if (FlipKey.booked_dates[year][month][day] == 1 || FlipKey.booked_dates[year][month][day] == 2) {
				return "disabled";
			}
		}
	}
	return "";
}

FlipKey.loadGoogleMap = function()
{
    Event.observe(window, 'load', function()
    {
        if (document.getElementById('smallGoogleMap')) document.getElementById('smallGoogleMap').src = FlipKey.google_map_url;
    });
}

Position.GetWindowSize = function(w) 
{
    var width, height;
    w = w ? w : window;
    width = w.innerWidth || (w.document.documentElement.clientWidth || w.document.body.clientWidth);
    height = w.innerHeight || (w.document.documentElement.clientHeight || w.document.body.clientHeight);

     return { width: width, height: height };
}

Position.center = function(element, parent) 
{
    var w, h, pw, ph;
    var d = Element.getDimensions(element);
    w = d.width;
    h = d.height;
    Position.prepare();
    if (!parent) {
            var ws = Position.GetWindowSize();
            pw = ws[0];
            ph = ws[1];
    } else {
            pw = parent.offsetWidth;
            ph = parent.offsetHeight;
    }
    //element.style.top = (ph/2) - (h/2) -  Position.deltaY + "px";
    element.style.left = (pw/2) - (w/2) -  Position.deltaX + "px";
}

function showLoadingWithoutBR(text)
{	
	if (!text)
	{
		text = 'Loading, please wait...';
	}
	
	if (typeof hideTooltips == "function") hideTooltips();
	
	if (!$('loading_opaque')) {
		var opaque = document.createElement('div');
		opaque.id = 'loading_opaque';
	document.body.appendChild(opaque);
	}
	var styles = { 
		background: '#333333',
		display: 'block',
		width: '100%',
		height: document.documentElement.scrollHeight + "px"
	};
	$('loading_opaque').setStyle(styles);
	
	var box = document.createElement('span');
	box.id = 'loading'; 
	box.innerHTML = text;
	document.body.appendChild(box);
	document.body.insertBefore(box, document.body.childNodes[0]);
	

	
	// set the style of the element so it is centered
	styles = { 
		top :  (Position.page(document.body)[1]*-1 + 100)  + 'px',
		display: 'block'
		
	};

	$('loading').setStyle(styles);			
	Position.center($('loading'), document.body);
}

function showLoading(text)
{	
    if (!text)
	{
		text = 'Loading, please wait...';
	}
	
	if (typeof hideTooltips == "function") hideTooltips();
	
	if (!$('loading_opaque')) {
		var opaque = document.createElement('div');
		opaque.id = 'loading_opaque';
	document.body.appendChild(opaque);
	}
	var styles = { 
		background: '#333333',
		display: 'block',
		width: '100%',
		height: document.documentElement.scrollHeight + "px"
	};
	$('loading_opaque').setStyle(styles);
	
	var box = document.createElement('span');
	box.id = 'loading'; 
	box.innerHTML = text + '<br/><br/>';
	document.body.appendChild(box);
	document.body.insertBefore(box, document.body.childNodes[0]);
	
	if (!loader) var loader = new Image(); 
	box.appendChild(loader);
	loader.src = "/img/ajax-loader.gif";

	
	// set the style of the element so it is centered
	styles = { 
		top :  (Position.page(document.body)[1]*-1 + 100)  + 'px',
		display: 'block'
		
	};

	$('loading').setStyle(styles);			
	Position.center($('loading'), document.body);
}

FlipKey.loader.src = FlipKey.loader_src;






/* DEPRECATED */ 
function showAjax(url)
{
    FlipKey.showLightboxAjax(url);
}

function closeLightbox()
{
    FlipKey.closeLightbox(); 
}

FlipKey.tooltip_options = {
    backgroundColor: "#D0DAE0", 
    borderColor: "#3892CB", 
	textColor: "#333333"
}
