/* Rent.com JavaScript Framework © Copyright 2007 Rent.com */
/* requires jQuery framework */

// Don't execute more than once.
if (typeof window.rent == 'undefined') {

// define namespaces
var rent = window.Rent || {}; // rent global namespace
rent.version  = 0.01; // beta
rent.dom      = {}; // document object model
rent.util     = {}; // utilities
rent.omniture = {}; // utilities
rent.form     = {}; // form
rent.events   = {}; // events
rent.ajax     = {}; // ajax
rent.win      = {}; // window
rent.hcc      = {}; // HCC
rent.constants = {
  MONTHS_ABREV: {'Jan':1,'Feb':2,'Mar':3,'Apr':4,'May':5,'Jun':6,'Jul':7,'Aug':8,'Sep':9,'Oct':10,'Nov':11,'Dec':12},
  MONTHS_LONG: {'January':1,'February':2,'March':3,'April':4,'May':5,'June':6,'July':7,'August':8,'September':9,'October':10,'November':11,'December':12}
};
// end of namespace definitions

// Omniture helper utils.  These will throw all kinds of errors unless
// the Omniture libraries are loaded.
rent.omniture = {
  trackClick:function(element) {
    var linkname = element.getAttribute('linkname');
    if (linkname) {
      var event = element.getAttribute('event') || '';
      rent.omniture.linkTrackHandler({
        'element' : element,
        'linkName': linkname,
        'event'   : event
      });
    }
  },
  linkTrackHandler:function(args){
    // This may seem silly, but it'll make implementing optional args easier.
    var s_account = args.account != null ? args.account : "rentcom";
    var element = args.element;
    var linkName = args.linkName;
    var props = args.props != null ? args.props : [ 'prop20', 'prop25' ];
    var eventDesc = args.eventDesc != null ? args.eventDesc : 'None';
    var linkType = args.linkType != null ? args.linkType : 'o';
    var propDesc = args.propDesc != null ? args.propDesc : linkName;
    var events = args.events != null ? args.events : '';
    if (s_gi) {
      var s = s_gi(s_account);
      s.linkTrackVars = props.join(',');
      s.linkTrackEvents = eventDesc;
      s.events = events;
      s.prop20 = propDesc;
      s.prop25 = propDesc;
      s.tl(true, linkType, linkName);
    }
  }
};

rent.form = {
  firstFieldFocus:function() {
    if ($("input:text:visible:enabled:first")) {
      $("input:text:visible:enabled:first").focus();
    } else if ($("select:visible:enabled:first")) {
      $("select:visible:enabled:first").focus();
    } else if ($("textarea:visible:enabled:first")) {
      $("textarea:visible:enabled:first").focus();
    } // first field type conditional
  }, // end firstFieldFocus()
	
  formTimeout:function(seconds) {
    $().ready(function(){
      $("form.submitControl").submit(function(){
        var form_timeout = seconds;
        if (form_timeout == null) form_timeout = 20000;
        else form_timeout = form_timeout * 1000;
        $(this).children("input:submit").attr("disabled","disabled");
        $(this).children("input:image").attr("disabled","disabled");
        $(this).animate({opacity: 1.0}, form_timeout).fadeIn('fast', function() {
          $(this).children("input:submit").removeAttr("disabled");
          $(this).children("input:image").removeAttr("disabled");
        }); // end form enabling function
      }); // end form submit functionality
    }); // end $()
  } // end formTimeout function
};

//  Data Verification Framework
rent.form.verify = {
  ValidDayForMonth:function(){
    var localThis = this;  // for closures
    this.setYear(function(){return $("select[@name=year]").val()});
    this.setMonth(function(){return $("select[@name=month]").val()});
    this.setDayElements(function(){return $("select[@name=day]")});
    this.handlers = {
      event:function(){localThis.updateDay()}
    };
  },
  dateDelta:function(month,day,year) {
    var now = new Date();
    var valDate = new Date(year,rent.constants.MONTHS_ABREV[month]-1,day);
    var dateDiff = ((valDate - now)/1000/60/60/24);
    return dateDiff;
  },
  // rent range warning
  rentAmt:function(controlAmt,reportAmt,deviation) {
    var rentRatio = reportAmt/controlAmt;
    var lowRatio = 1-deviation;
    var highRatio = 1+deviation;
    return ((rentRatio >= lowRatio) && (rentRatio <= highRatio));
  }, // end rentAmt()
	
  rentAmtMax:function(controlAmt,reportAmt,deviation) {
    var rentRatio = reportAmt/controlAmt;
    var lowRatio = 1-deviation;
    var highRatio = 1+deviation;
    return (rentRatio <= highRatio);
  }, // end rentAmtMax()
	
  rentAmtMin:function(controlAmt,reportAmt,deviation) {
    var rentRatio = reportAmt/controlAmt;
    var lowRatio = 1-deviation;
    var highRatio = 1+deviation;
    return (rentRatio >= lowRatio);
  } // end rentAmtMax()
	
	
};

// ValidDayForMonth methods

rent.form.verify.ValidDayForMonth.prototype.getYear = function () {
  if (typeof this.year === 'function') return this.year();
  return this.year;
};
rent.form.verify.ValidDayForMonth.prototype.setYear = function (value) {
  this.year = value;
};

rent.form.verify.ValidDayForMonth.prototype.getMonth = function () {
  if (typeof this.month === 'function') return this.month();
  return this.month;
};
rent.form.verify.ValidDayForMonth.prototype.setMonth = function (value) {
  this.month = value;
};

rent.form.verify.ValidDayForMonth.prototype.getDayElements = function () {
  if (typeof this.dayElements === 'function') return this.dayElements();
  return this.dayElements;
};
rent.form.verify.ValidDayForMonth.prototype.setDayElements = function (value) {
  this.dayElements = value;
};

rent.form.verify.ValidDayForMonth.prototype.validDay = function (day) {
  var year = this.getYear();
  var month = this.getMonth() - 1;
  var valDate = new Date(year, month, day);
  return valDate.getMonth() == month;
};

// This routine could use some abstraction.  There is far too much of
// the view embedded here.
rent.form.verify.ValidDayForMonth.prototype.updateDay = function () {
  // Get the value attribute of the currently selected day.
  var prevSelected = this.getDayElements().children('option[@selected]').val();
  // Find the max day for this month.
  var maxDay = 28;
  while (this.validDay(maxDay + 1)) ++maxDay;
  // Set previously selected to the max day if it was too big.
  if (prevSelected > maxDay) prevSelected = maxDay
  var newContent = '';
  for (var idx = 1; idx <= maxDay; ++idx) {
    newContent += '<option value="' + idx + '">' + idx + "</option>\n";
  }
  this.getDayElements().html(newContent);
  // And make sure the correct day is selected.
  this.getDayElements().children('option[@value=' + prevSelected + ']').attr('selected', true);
};

rent.form.verify.ValidDayForMonth.prototype.getEventHandler = function () {
  return this.handlers.event;
};
rent.form.verify.ValidDayForMonth.prototype.setEventHandler = function (value) {
  this.handlers.event = value;
};

// Window Framework
rent.win = {
  //print window for browsers that support it
  printWindow:function() {
    if (window.print){
      window.print();
    } else {
      alert('Your browser does not support this feature.  Please use the browser print feature.');
    }
  } // end printWindow()
}; // end rent.win

// Utility Framwork
rent.util = {
  replaceChars:function(txt,outStr,inStr) { // replace a character in a string w/another
    output = "" + txt; // temporary holder
    while (output.indexOf(outStr)>-1) {
      pos= output.indexOf(outStr);
      output = "" + (output.substring(0, pos) + inStr + output.substring((pos + outStr.length), output.length));
    }
    return output;
  },  // end replaceChars()

  // rt 8462:
  // customize the display of days for months (such that April has days 1 to 30
  // while may has days 1 to 31)
  // TBD:  we should have a unified method for displaying months and days.  So 
  // this probably sohould be merged into the rent.form.verify.ValidDayForMonth
  // (which is too specific for now)
  displayDaysForMonth:function(input, dayElementId) { 
    // get dayElement object and its selected index 
    var dayElement = $("select[@name=movein_day]");
    var selectedIdx = dayElement.val();

    // input is in "month/year" format, so we need to get month and year
    var month_year = new Array();
    month_year = input.split('/');
    // rent.com month starts from 1, while Date() object starts with 0
    var month = month_year[1] - 1;
    var year = month_year[0];

    // By utilizing Date() overflow, we actually successfully detect how many 
    // days in a month ( you can use any number >= 32 here instead of 32)
    // Note that this takes care of leap years as well.
    var maxDay = 32 - new Date(year, month, 32).getDate();
    //alert("maxDay is " + maxDay);
    var newContent = '';
    for (var idx = 1; idx <= maxDay; ++idx) {
      newContent += '<option value="' 
                 + idx 
                 + '"' 
                 + (idx == selectedIdx ? " class='selected'" : "") 
                 + '>' 
                 + idx 
                 + "</option>\n";
    }
    dayElement.html(newContent);
    dayElement.children(".selected").attr({selected: "selected"});
  } // end displayDaysForMonth

}; // end rent.util

} // close window.rent



