// Common utility actions, in a nice namespace. 
// Goal is browser support for IE6+, FF2+, Safari and Opera
// Can assume jQuery support
Riven = {

  // Format a floating point value as a price with dollar sign, etc.
  toPrice: function(price) {
    price = ''+price;
    var sign = '';
    if (price.substring(0,1) == '-') { sign = '-'; price = price.replace('-', ''); }
    var bits = price.split(/\./);
    var dollars = bits[0];
    if (dollars.length > 3) {
      dollars = dollars.replace(/([0-9]*)([0-9]{3})$/, '$1,$2');
    }
    var cents = '';
    if (bits[1]) { cents = ''+bits[1]; }
    while (cents.length < 2) {
      cents = cents + '0';
    }
    if (cents.length > 2) {
      cents = cents.substring(0,2);
    }
    return sign + '$' + dollars + '.' + cents;
  },

  // Sets a cookie's value, defaults to 1 year duration, root path
  setCookie: function(name, value, expiresHours, path) {
    if (!expiresHours) { expiresHours = 24*365; }
    if (!path) { path = '/'; }

    var today = new Date();
    var expiresDate = new Date( today.getTime() + (expiresHours * 60 * 60 * 1000) );

    // Actually set the cookie
    document.cookie = name + "=" +escape(value) +
      ";expires=" + expiresDate.toGMTString() +
      ";path=" + path;
  },

  // Gets a cookie's value
  getCookie: function(name) {
    var cookies = document.cookie.split( ';' );
    for ( i = 0; i < cookies.length; i++ ) {
      var parts = cookies[i].split('=');
      if (parts[0].trim() == name) {
        return (parts.length > 1) ? unescape(parts[1]) : '';
      }
    }
    return false;
  },

    // Post a hash of params to a given url, then call the given callback (with 'this' optionally set to
    // the passed context) on success or failure.  Callback is required, and must be a function that
    // accepts two parameters, a success flag (of the ajax call, not necessarily the page result) and
    // a hash of result data if any from the called page (passed via JSON).
    //
    // Sample usage:
    //
    // function onResults(success, data) {
    //   if (success) {
    //     alert(data.message);
    //   } else {
    //     alert('Failed!');
    // }
    //
    // function saveValue(val) {
    //   url = '/site/module/page';
    //   params = {
    //     value: val
    //   };
    //   Riven.postAJAX(url, params, onResults);
    // }
    postAJAX: function(url,params,callback,context) {
        params = params || {};
        $.ajax({
            type: 'POST',
            url: url,
            data: params,
            cache: false,
            dataType: 'json',
            success: function(json) {
                callback.call(context||this, true, json);
            },
            error: function(xhr,status) {
                callback.call(context||this, false, null);
            }
        });
    },

    // Filters a select input element's states based on a select with
    // national markets listed - used in CRM for market editing.
    // Pass in id's for national and state select elements as params.
    filterStates: function(nationID, stateID) {
        var nations = $('#'+nationID);
        var states = $('#'+stateID);
        var cache = $('#'+stateID+'-cache');
        
        // Sanity check
        if (!nations || !states) {
            return;
        }

        var curNation = nations.val();
        if (!this.curNation || curNation != this.curNation) {
            // Save our current val, and clear out the states select
            this.curNation = curNation;
            states.empty();

            if (curNation) {
                // Clone all options that have their national market id set to our current selection into the states control
                var selID = cache.val().match(/[^\-]+$/);
                cache.find("option[national_market_id='"+curNation+"']").clone().appendTo(states);
                states.find("option").each(function() {
                    // Set option vals to correct value (strip national id)
                    $(this).attr('value',$(this).attr('value').match(/[^\-]+$/));
                });
                states.show();
                states.val(selID);
                $('#'+stateID+'-none').hide();
            } else {
                // No selected nation, so reset value and hide it
                states.hide();
                $('#'+stateID+'-none').show();
            }
        }
        
    },

    filterCities: function(mode) {
        // If mode is not set, do both modes
        if (mode == null) {
            Riven.filterCities('quicksearch');
            Riven.filterCities('body');
            return;
        }

        // Get our nodes
        var states = $('#'+mode+'-state');
        if (!states || states.length == 0) { return; }
        var cities = $('#'+mode+'-city');
        var cache = $('#'+mode+'-city-cache');
        var curCity = cities.val();

        // Ensure the cache is populated
        if (cache.find('option').length <= 0) {
            cities.find('option').appendTo(cache);
        }

        // Populate the main select with the appropriate items
        var curState = states.val();
        if (!this.curState || curState != this.curState[mode]) {
            // Save our current val, and clear out the cities select
            if (!this.curState) { this.curState = []; }
            this.curState[mode] = curState;
            cities.empty();

            if (curState.length > 0) {
                // Clone first option ("any") and all options that have the state attribute set to our state abbreviation
                cache.find("option:first, option[state='"+curState+"']").clone().appendTo(cities);
                if (curCity && curCity != '') {cities.val(curCity);}
                $('#'+mode+'-city-row').show();
            } else {
                // No selected state, so reset city value and hide it
                $('#'+mode+'-city-row').hide();
            }
        }
    },

    // New mouseover code for our new-style graphical buttons
    hoverButton: function(node, over) {
        // Add/remove our pseudo-hover class for IE6 (hate hate)
        node.toggleClass('iehover', over);
        // If we don't have a src attr, find our child who does
        if (!node.attr('src')) { node = node.find('*[src]'); }
        // Update our src attr to point to appropriate image
        var newSrc = node.attr('src');
        if (over) {
            // Add '-over' to image url
            newSrc = newSrc.replace(/(-over)?\./,'-over.');
        } else {
            // Remove '-over'
            newSrc = newSrc.replace(/-over\./,'.');
        }
        node.attr('src',newSrc);
    },

    // Called once on page load
    onNewContent: function(node) {
      // If we don't have a specified node, look for all body contents
      if (!node) {
        node = $('body');
      }
      
      // Update visibility of elements based on javascript availability
      $('.js-hide').hide().removeClass('js-hide');
      $('.js-show').show().removeClass('js-show');
      
      // Enable lightbox on items that request it
      $('a[rel*=lightbox]').lightBox();
      
      // New-style buttons, hover to do mouseover look
      $('.button').hover(
        function() { Riven.hoverButton($(this),true) },
        function() { Riven.hoverButton($(this),false) }
      );
    }

};

function AddToMylist(returnPage) {
	var str = '';
	
	for (var i=0;i< document.results.elements.length;i++) {
    if (document.results.elements[i].name == 'listing_ids[]') {
    	if (document.results.elements[i].checked == true) {
	    	if (str != '') { str = str + ','; }
	      str = str + document.results.elements[i].value;
	    }
  	}
  }
  
  var url = '/site/mylist/add_listings?listing_ids=' + str;
  if (returnPage) { url += '&clause=' + returnPage; }
  top.location.href = url;
};

function resetQuickSearch(){
	var f = document.QuickSearch;
	for (var i=0;i<f.elements.length; i++ ){
		if (f.elements[i].type == 'select-one'){
			f.elements[i].selectedIndex=0;
		}
	}
};

function changeImages(id, src) { 
	  var el = Riven.get(id);
	  if (el) { el.src = src; }
};


// jQuery extensions
(function($) {
  // We're adding new methods to the jQuery result set object
  $.fn.extend({
    
    setMask: function(status) {
      // Sanity check
      var node = this;
      if (node.length <= 0) {
        return;
      }
      // Remove loading mask, if any
      node.find('.status-mask').remove();
      if (status) {
        // Create a mask object and overlay the node with it
        mask = '<div class="status-mask"><div class="status-mask-text">' + status + '</div></div>';
        node.prepend(mask);
        
        // Resize the mask to fit the node, and then show it
        maskNode = node.find('.status-mask');
        maskStatusNode = maskNode.find('.status-mask-text');
        w = node.width();
        h = node.height();
        maskNode.css({
          'width': w,
          'height': h,
          'opacity': 0.85
        });
        maskStatusNode.css({
          'margin-top': (h/2-10) | 0   // the "| 0" truncates the float result back to an int - all css sizes are in px
        });
      }
    },
    
    // Loads an html fragment into the current node
    loadUrl: function(loadingText, url, params, callback, context) {
      // Sanity check
      var node = this;
      if (node.length <= 0) {
        return;
      }
      // Note our loading status, if we have one.
      if (loadingText) {node.setMask(loadingText);}

      // Do the ajax call
      $.ajax({
        type: 'POST',  // Use post, since we may be sending arbitrarily large data chunks, and servers will barf on too-long urls
        url: url,
        data: params,
        cache: false,
        dataType: 'text',
        success: function(text) {
          node.html(text);
          Riven.onNewContent(node);
          if (callback) {
            callback.call(context||this, true);
          }
        },
        error: function(xhr,status) {
          alert('Unable to load '+url+'\n\n'+status);
          node.setMask(false);
          if (callback) {
            callback.call(context||this, false);
          }
        }
      });
    },

    // Common case handler - sets a hover behavior that sets/removes a given css class on hover for all selected items
    hoverClass: function(className) {
      return this.hover(
        function() {
          $(this).addClass(className);
        },
        function() {
          $(this).removeClass(className);
        }
      );
    }

  });

})(jQuery);


// Sets up any global page js stuff needed after page load
$(function() {
  // Setup styles, lightboxes, etc.
  Riven.onNewContent();
            
  // Layout specific items
  Riven.filterCities();
});
