/*
    CruiseHolidays.Web.UI
    
    Preferences class is used to dynamically manage preferences (combo boxes that appear in Preferences box).
    It also wraps serverPrefs object (deserialized JSON LightweightUserPreferences object passed from MasterPage)
    and transparently sets it's properties.
*/

function Preferences() {
    this.dateRangeIndex = 0;
    this.dateRange = "";
    this.regionId = 0;
    this.cruiselineId = 0;
    this.shipId = 0;
    this.portId = 0;
    
    this.dateRangeList = null;
    this.regionList = null;
    this.portList = null;
    this.cruiselineList = null;
    this.shipList = null;
    
    this.userPrefs = null; //a reference to serverPrefs object (deserialized JSON LightweightUserPreferences object passed from MasterPage)
    
    this.onChanged = null; //event(Preferences, type, id) fires after one of the properties are changed (manually or by the code)
    this.onUIChanged = null; //event(Preferences, type, id) fires after one of the preferences are changed manually (by selecting a new item in the drop down box)
    
    this._getItemIndexByValue = function(select, value) {
        for (var i=0; i<select.options.length; i++) {
            if (select.options[i].value==value) {
                return i;
            }
        }
        return 0;
    }
    
    this.resetListReferences = function() {
        if(this.dateRangeList && this.dateRangeList.id) this.dateRangeList = document.getElementById(this.dateRangeList.id);
        this.regionList = document.getElementById(this.regionList.id);
        this.portList = document.getElementById(this.portList.id);
        this.cruiselineList = document.getElementById(this.cruiselineList.id);
        this.shipList = document.getElementById(this.shipList.id);
        
        this.initListHandlers()
    }
    
    /*
        Creates onchange handlers for all the lists (drop-down boxes) so when chainging them onUIChanged event is fired
    */
    this.initListHandlers = function() {
        var self = this;
        if (this.regionList)
            Events.attachEvent(this.regionList, "change", function(e) {
                if (e.srcElement) {
                    self.setRegion(e.srcElement.value, e.srcElement)
                } else {
                    self.setRegion(e.target.value, e.target)
                }
            });
        if (this.portList)
            Events.attachEvent(this.portList, "change", function(e) {
                if (e.srcElement) {
                    self.setPort(e.srcElement.value, e.srcElement)
                } else {
                    self.setPort(e.target.value, e.target)
                }
            });
        if (this.dateRangeList)
            Events.attachEvent(this.dateRangeList, "change", function(e) {
                if (e.srcElement) {
                    self.setDateRange(e.srcElement.value, e.srcElement)
                } else {
                    self.setDateRange(e.target.value, e.target)
                }
            });
        if (this.cruiselineList)
            Events.attachEvent(this.cruiselineList, "change", function(e) {
                if (e.srcElement) {
                    self.setCruiseline(e.srcElement.value, e.srcElement)
                } else {
                    self.setCruiseline(e.target.value, e.target)
                }
            });
        if (this.shipList)
            Events.attachEvent(this.shipList, "change", function(e) {
                if (e.srcElement) {
                    self.setShip(e.srcElement.value, e.srcElement)
                } else {
                    self.setShip(e.target.value, e.target)
                }
            });
    }
    
    this.saveUserPrefs = function() {
        if (!this.userPrefs)
            return;
        setCookie('userPrefs', Sys.Serialization.JavaScriptSerializer.serialize(this.userPrefs), 14, null, null, null);
    }


    this.setUserPrefs = function(prefs) {
        this.userPrefs = prefs;
        //this.setContext(this.userPrefs.Where.Type, this.userPrefs.Where.Id);
        if (this.userPrefs.RegionId>0)
            this.setContext("Region", this.userPrefs.RegionId);
        if (this.userPrefs.PortId>0)
            this.setContext("Port", this.userPrefs.PortId);
        this.setContext(this.userPrefs.Who.Type, this.userPrefs.Who.Id);
        
        //TODO: sort out issue with Who.Type="Ship" - in this case we don't know CruiseLine id.
    }
    
    this.loadUserPrefs = function() {
        var userPrefsCookie = getCookie('userPrefs');
        if (userPrefsCookie && userPrefsCookie!="") {
            this.setUserPrefs(Sys.Serialization.JavaScriptSerializer.deserialize(userPrefsCookie));
            return true;
        } else
            return false;
    }
    
    this.loadFromUI = function() {
        if (debug) debug.writeLine("preferences.loadFromUI();");
        //if (debug) debug.writeLine("cruiseline id: "+this.cruiselineList.options[this.cruiselineList.selectedIndex].value);
        
        if (this.regionList)
            this.setContext("Region");
        if (this.portList)
            this.setContext("Port");
        if (this.dateRangeList)
            this.setContext("DateRange");
        if (this.cruiselineList)
            this.setContext("CruiseLine");
        if (this.shipList)
            this.setContext("Ship");
    }
    
    /*
        this method is to be called by map's mapContextChange event
    */
    this.setContext = function(type, id) {
        if (type=="Region")
            this.setRegion(id);
        else if (type=="CruiseLine")
            this.setCruiseline(id);
        else if (type=="Ship")
            this.setShip(id);
        else if (type=="DateRange")
            this.setDateRange(id);
        else if (type=="Port")
            this.setPort(id);
        
        /* don't set port as a Where preference, as we don't want to filter by Port.
        
        else if (type=="Port") {
            this._setUserPrefs(type, id);
        }*/
    }
    
    /*
        this method can be be called by dropdown boxes, i.e. from its onChange event (instead of calling setRegion(), setCruiseline(), setShip() individually
    */
    this.setContextManually = function(type, id, sender) {     
        if (type=="Region")
            this.setRegion(id, sender);
        else if (type=="Port")
            this.setPort(id, sender);
        else if (type=="CruiseLine")
            this.setCruiseline(id, sender);
        else if (type=="Ship")
            this.setShip(id, sender);
        else if (type=="DateRange")
            this.setDateRange(id, sender);
    }
    
    /*
        this method sets userPrefs object's properties based on context type and id
    */
    this._setUserPrefs = function(type, id, second_value) {
        if (!this.userPrefs)
            return;
            
        if (debug) debug.writeLine("preferences._setUserPrefs(" + type + ", " + id+");");

        if (type=="Region") {
            this.userPrefs.RegionId = id;
        } else if (type=="Port") {
            this.userPrefs.PortId = id;
        } else if (type=="CruiseLine" || type=="Ship") {
            this.userPrefs.Who.Type = type;
            this.userPrefs.Who.Id = id;
            
        } else if (type=="SetDateRange") {
            //if (debug) debug.writeLine("id: "+id);
            if (id) {
                this.userPrefs.When = new Array({ From: null, To: null });
                this.userPrefs.When[0].From = id
                this.userPrefs.When[0].To = second_value
            } else
                this.userPrefs.When = {};
                           
        } else if (type=="DateRange") {
            //if (debug) debug.writeLine("id: "+id);
            if (id) {
                var dateElements = id.split("/");
                this.userPrefs.When = new Array({ From: null, To: null });
                this.userPrefs.When[0].From = new Date();
                this.userPrefs.When[0].From.setTime(0);
                this.userPrefs.When[0].From.setFullYear(("20"+dateElements[2])*1, dateElements[1]*1-1, dateElements[0]*1);
                this.userPrefs.When[0].To = new Date();
                this.userPrefs.When[0].To.setTime(0);
                this.userPrefs.When[0].To.setFullYear(("20"+dateElements[2])*1, dateElements[1]*1-1, 1);
                this.userPrefs.When[0].To.setDate(this._getDaysInMonth(this.userPrefs.When[0].To.getMonth()+1, this.userPrefs.When[0].To.getYear()));
                if (debug) debug.writeLine("from "+this.userPrefs.When[0].From + " to "+this.userPrefs.When[0].To);
            } else
                this.userPrefs.When = {};
        }
        //TODO: set date range user prefs
    }
    
    this._daysInFebruary = function(year){
	    // February has 29 days in any year evenly divisible by four,
        // EXCEPT for centurial years which are not also divisible by 400.
        return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
    }
    
    this._daysArray = function(n) {
	    for (var i = 1; i <= n; i++) {
		    this[i] = 31
		    if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
		    if (i==2) {this[i] = 29}
       } 
       return this;
    }
    
    this._getDaysInMonth = function(month, year) {
        if (month==2)
            return this._daysInFebruary(year);
        else
            return this._daysArray(12)[month];
    }
    
    

    this.setDateRange2 = function(from, to, sender){
        this.resetListReferences()
    
        this.userPrefs.When = new Array({ "From" : from, "To" : to });
        if (debug) debug.writeLine("from "+this.userPrefs.When[0].From + " to "+this.userPrefs.When[0].To);
        this._setUserPrefs("SetDateRange", from, to)
    }


    this.setDateRange = function(value, sender) {
        this.resetListReferences()
    
        if(value){
            if (debug) debug.writeLine("preferences.setDateRange(" + value + ", " + sender+");");

            if (sender==undefined || sender!=this.dateRangeList) {
                //request to change date range (internal dateRange and drop down box)
                //if (debug) debug.writeLine("1");
                if (value || value=="") {
                    //if (debug) debug.writeLine("2");
                    if (debug) debug.writeLine("this.dateRangeList: " + this.dateRangeList+";");
                    this.dateRangeIndex = this._getItemIndexByValue(this.dateRangeList, value);
                    if (debug) debug.writeLine("this.dateRangeIndex: " + this.dateRangeIndex+";");
                    //this.regionList.onchange();
                    if (this.dateRangeIndex!=this.dateRangeList.selectedIndex) {
                        //if (debug) debug.writeLine("__doPostBack("+this.dateRangeList.id+")");
                        this.dateRangeList.selectedIndex = this.dateRangeIndex;
                        setTimeout("__doPostBack('"+this.dateRangeList.id+"','')", 0);
                    } else{
                        this.dateRangeList.selectedIndex = this.dateRangeIndex;
                        if(this.dateRangeIndex == 0){
                            // HACK : Add the month if it dosnt exist to keep UI sane
                            var month = months[(parseFloat(value.split("/")[1])) - 1] + " 20" + value.split("/")[2]
                            var option = new Option(month, value)
                            this.dateRangeList.options[this.dateRangeList.options.length] = option
                            this.dateRangeList.value = value;
                        }
                    }
                    this.dateRange = value;
                } else {
                    //if (debug) debug.writeLine("3");
                    this.dateRangeIndex = this.dateRangeList.selectedIndex;
                    this.dateRange = this.dateRangeList.options[this.dateRangeList.selectedIndex].value;
                }
            } else {
                //drop-down box change. 
                this.dateRange = value;
                this.dateRangeIndex = this._getItemIndexByValue(this.dateRangeList, value);
            }
            
            setCookie('pr:dat', this.dateRange, 14, null, null, null); //this is superceeded in _setUserPrefs by storing userPrefs (=serverPrefs) as JSON-serialized string to cookie
            
            if (this.onChanged && (sender==undefined || sender!=this.dateRangeList))
                this.onChanged(this, "DateRange", this.dateRange);
                
            if (this.onUIChanged && sender==this.dateRangeList)
                this.onUIChanged(this, "DateRange", this.dateRange);
                
                
            this._setUserPrefs("DateRange", value)
                
        }
            
    }
    
    this.resetDateRange = function(sender) {    
        this.resetListReferences()
    
        if (debug) debug.writeLine("preferences.resetDateRange(" + sender+");");
          
        this.setDateRange("", sender);
        return;
        this.dateRangeIndex = 0;
        this.dateRange = "";
        this._setUserPrefs("DateRange", null);
        
        deleteCookie('pr:dat', null, null); //this is superceeded in _setUserPrefs by storing userPrefs (=serverPrefs) as JSON-serialized string to cookie
        
        /*
        if (sender==undefined || sender!=this.regionList) {
            this.dateRangeList.selectedIndex = 0;
            this.dateRangeList.onchange();
        }*/
        
        if (this.onChanged)
            this.onChanged(this, "DateRange", this.dateRange);
            
        if (this.onUIChanged && sender)
            this.onUIChanged(this, "DateRange", this.dateRange);
    }
    
    
    this.setRegion = function(id, sender) {    
        this.resetListReferences()
       
        if (debug) debug.writeLine("preferences.setRegion(" + id + ", " + sender+");");
        
        var oldRegionId = this.regionId;
        
        if (sender==undefined || sender!=this.regionList) {
            //request to change region (internal regionId and drop down box)
            if (id!=undefined) {
                var index = this._getItemIndexByValue(this.regionList, id);
                //this.regionList.onchange();
                if (index!=this.regionList.selectedIndex) {
                    this.regionList.selectedIndex = index;
                    setTimeout("__doPostBack('"+this.regionList.id+"','')", 0);
                } else
                    this.regionList.selectedIndex = index;
                this.regionId = id*1;
            } else {
                this.regionId = (this.regionList.options[this.regionList.selectedIndex].value)*1;
            }
        } else {
            //drop-down box change. 
            id = id*1;
            this.regionId = id;
        }
        this._setUserPrefs("Region", this.regionId);
           
        if (oldRegionId>0 && oldRegionId!=this.regionId)
            this.resetPort(this);
            
        setCookie('pr:rgn', this.regionId, 14, null, null, null); //this is superceeded in _setUserPrefs by storing userPrefs (=serverPrefs) as JSON-serialized string to cookie
            
        if (this.onChanged && (sender==undefined || sender!=this.regionList))
            this.onChanged(this, "Region", this.regionId);
            
        if (this.onUIChanged && sender==this.regionList)
            this.onUIChanged(this, "Region", this.regionId);
    }
    
    this.resetRegion = function(sender) {
        this.resetListReferences()
    
        this.regionId = 0;
        this.portId = 0;
        this._setUserPrefs("Region", 0);
        deleteCookie('pr:rgn', null, null); //this is superceeded in _setUserPrefs by storing userPrefs (=serverPrefs) as JSON-serialized string to cookie
        
        /*if (sender==undefined || sender!=this.regionList) {
            this.regionList.selectedIndex = 0;
            this.regionList.onchange();
        }*/
        
        if (this.onChanged)
            this.onChanged(this, "Region", 0);
            
        if (this.onUIChanged && sender)
            this.onUIChanged(this, "Region", 0);
    }
    
    this.setPort = function(id, sender) {   
        this.resetListReferences()
        
        if (debug) debug.writeLine("preferences.setPort(" + id + ", " + sender+");");
        
        var oldPortId = this.portId;
        
        if (sender==undefined || sender!=this.portList) {
            //request to change port (internal portId and drop down box)
            if (id!=undefined) {
                var index = this._getItemIndexByValue(this.portList, id);
                //this.portList.onchange();
                if (index!=this.portList.selectedIndex) {
                    this.portList.selectedIndex = index;
                    setTimeout("__doPostBack('"+this.portList.id+"','')", 0);
                } else
                    this.portList.selectedIndex = index;
                this.portId = id*1;
            } else {
                this.portId = (this.portList.options[this.portList.selectedIndex].value)*1;
            }
        } else {
            //drop-down box change. 
            id = id*1;
            this.portId = id;
        }
        
        if (this.portId>0)
            this._setUserPrefs("Port", this.portId);
        else
            this._setUserPrefs("Region", this.regionId);

            
        if (this.onChanged && (sender==undefined || sender!=this.portList))
            this.onChanged(this, "Port", this.portId);
            
        if (this.onUIChanged && sender==this.portList)
            this.onUIChanged(this, "Port", this.portId);
    }
    
    this.resetPort = function(sender) {
        this.resetListReferences()
    
        if (debug) debug.writeLine("preferences.resetPort();");
        this.setPort("0", null);
        return;
    }
    
    this.setCruiseline = function(id, sender) {     
        this.resetListReferences()
      
        var oldCruiselineId = this.cruiselineId;
        //if (debug) debug.writeLine("preferences.setCruiseline(" + id + ", " + sender+");");
                
        if (sender==undefined || sender!=this.cruiselineList) {
            //request to change cruiseline (internal cruiselineId and drop down box)
            if (id!=undefined) {
                if (debug) debug.writeLine("yes");
                var index = this._getItemIndexByValue(this.cruiselineList, id);
                this.cruiselineList.selectedIndex = index;
                setTimeout("__doPostBack('"+this.cruiselineList.id+"','')", 0);
                this.cruiselineId = id*1;
            } else {
                //TODO: IE vector map - JS error - this.cruiselineList.selectedIndex=-1?
                this.cruiselineId = (this.cruiselineList.options[this.cruiselineList.selectedIndex].value)*1;
            }
        } else {
            //drop-down box change.
            id = (id)*1 ;
            this.cruiselineId = id;
            //TODO: send event to map
        }
       
        this._setUserPrefs("CruiseLine", this.cruiselineId);
        if (oldCruiselineId>0 && oldCruiselineId!=this.cruiselineId)
            this.resetShip(this);
        setCookie('pr:cru', this.cruiselineId, 14, null, null, null);
        
        if (this.onChanged && (sender==undefined || sender!=this.cruiselineList))
            this.onChanged(this, "CruiseLine", this.cruiselineId);
            
            //if (debug) debug.writeLine("this.onUIChanged: "+this.onUIChanged);
            //if (debug) debug.writeLine("sender==this.cruiselineList: "+(sender==this.cruiselineList));
        if (this.onUIChanged && sender==this.cruiselineList)
            this.onUIChanged(this, "CruiseLine", this.cruiselineId);
    }
    
    this.resetCruiseline = function(sender) {
        this.resetListReferences()
    
        if (debug) debug.writeLine("preferences.resetCruiseline();");
        this.setCruiseline("0", null);
        //alert(1);
        return;
        
        this.cruiselineId = 0;
        this._setUserPrefs("CruiseLine", 0);
        deleteCookie('pr:cru', null, null); //this is superceeded in _setUserPrefs by storing userPrefs (=serverPrefs) as JSON-serialized string to cookie
        
        /*if (sender==undefined || sender!=this.cruiselineList) {
            this.cruiselineList.selectedIndex = 0;
            this.cruiselineList.onchange();
        }*/
        
        this.resetShip(this);
        
        if (this.onChanged)
            this.onChanged(this, "CruiseLine", 0);
            
        if (this.onUIChanged && sender)
            this.onUIChanged(this, "CruiseLine", 0);
    }
    
    this.setShip = function(id, sender) {  
        this.resetListReferences()
         
        if (sender==undefined || sender!=this.shipList) {
            //request to change ship (internal shipId and drop down box)
            if (id!=undefined) {
                var index = this._getItemIndexByValue(this.shipList, id);
                this.shipList.selectedIndex = index;
                this.shipId = id*1;
            } else {
                this.shipId = (this.shipList.options[this.shipList.selectedIndex].value)*1;
            }
        } else {
            //drop-down box change. 
            id = (id)*1;
            this.shipId = id;
            //TODO: send event to map
        }
        if (this.shipId>0)
            this._setUserPrefs("Ship", this.shipId);
        else
            this._setUserPrefs("CruiseLine", this.cruiselineId);
            
        setCookie('pr:shp', this.shipId, 14, null, null, null); //this is superceeded in _setUserPrefs by storing userPrefs (=serverPrefs) as JSON-serialized string to cookie
        
        if (this.onChanged && (sender==undefined || sender!=this.shipList))
            this.onChanged(this, "Ship", this.shipId);
            
        if (this.onUIChanged && sender==this.shipList)
            this.onUIChanged(this, "Ship", this.shipId);
    }
    
    this.resetShip = function(sender) {
        this.resetListReferences()
    
        if (debug) debug.writeLine("preferences.resetShip();");
        this.setShip("0", null);
        //alert(2);
        return;
        
        this.shipId = 0;
        //this._setUserPrefs("Ship", 0);
        this._setUserPrefs("CruiseLine", this.cruiselineId);
        deleteCookie('pr:shp', null, null); //this is superceeded in _setUserPrefs by storing userPrefs (=serverPrefs) as JSON-serialized string to cookie
        
        /*if (sender==undefined || sender!=this.shipList) {
            this.shipList.selectedIndex = 0;
            this.shipList.onchange();
        }*/
        
        if (sender==undefined || sender!=this) {
            if (this.onChanged)
                this.onChanged(this, "Ship", 0);
                
        if (this.onUIChanged && sender)
            this.onUIChanged(this, "Ship", 0);
        }
    }
}
var months = new Array(12);
months[0] = "January";
months[1] = "February";
months[2] = "March";
months[3] = "April";
months[4] = "May";
months[5] = "June";
months[6] = "July";
months[7] = "August";
months[8] = "September";
months[9] = "October";
months[10] = "November";
months[11] = "December";

var ConvertToTicks = function(date)
{
   this.day = date.getDate();
   this.month = date.getMonth() + 1;
   this.year = date.getFullYear();
   this.hour = date.getHours();
   this.minute = date.getMinutes();
   this.second = date.getSeconds();
   this.ms = date.getMilliseconds();
   
   this.monthToDays = function(year, month)
   {
      var add = 0;
      var result = 0;
	    if((year % 4 == 0) && ((year % 100  != 0) || ((year % 100 == 0) && (year % 400 == 0)))) add++;
         
      switch(month)
      {
         case 0: return 0;
         case 1: result = 31; break;
         case 2: result = 59; break;
         case 3: result = 90; break;
         case 4: result = 120; break;
         case 5: result = 151; break;
         case 6: result = 181; break;
         case 7: result = 212; break;
         case 8: result = 243; break;
         case 9: result = 273; break;
         case 10: result = 304; break;
         case 11: result = 334; break;
         case 12: result = 365; break;
      }
      if(month > 1) result += add;
      return result;      
   }

   this.dateToTicks = function(year, month, day)
   {
      var a = parseInt((year - 1) * 365);
      var b = parseInt((year - 1) / 4);
      var c = parseInt((year - 1) / 100);
      var d = parseInt((a + b) - c);
      var e = parseInt((year - 1) / 400);
      var f = parseInt(d + e);
      var monthDays = this.monthToDays(year, month - 1);
      var g = parseInt((f + monthDays) + day);
      var h = parseInt(g - 1);
      return h * 864000000000;
   }

   this.timeToTicks = function(hour, minute, second)
   {
      return (((hour * 3600) + minute * 60) + second) * 10000000;
   }   
   
   return this.dateToTicks(this.year, this.month, this.day) + this.timeToTicks(this.hour, this.minute, this.second) + (this.ms * 10000);
}

function days_between(date1, date2) {

    // The number of milliseconds in one day
    var ONE_DAY = 1000 * 60 * 60 * 24

    // Convert both dates to milliseconds
    var date1_ms = date1.getTime()
    var date2_ms = date2.getTime()

    // Calculate the difference in milliseconds
    var difference_ms = Math.abs(date1_ms - date2_ms)
    
    // Convert back to days and return
    return Math.round(difference_ms/ONE_DAY)

}
