// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults

// console.log wrapper, much leverage of firebug-lite
// Tested and functional in Chrome on linux, IE 7 and 8 on Windows 7, and 
// Safari on Windows 7.
//
// still shouldn't be used anywhere other than in limited debugging use on
// staging...
var C = {};
(function() {
  // global debug on|off
  var debug = true;

  // drop or alert if console isn't available
  // true  = don't show log
  // false = show log
  var quietDismiss = true;

  this.toggle = function () {
    debug = !debug;
    if (logWindow) {
      logWindow.toggle();
    }
  };

  this.enable = function() { debug = true; };
  this.disable = function() { debug = false; };

  this.log = function() {
    if (!debug) return false;

    if (typeof console === 'object' && typeof console.log !== "undefined" && Prototype.Browser.Gecko) {
      // IE 8 developer mode, and possibly Safari expose their own console.log methods
      // that seem to be incompatible with Firebug's 
      console.log.apply(this, arguments); 
    }
    else if (!quietDismiss) {
      if (!logWindow) {
        // Insert and use a floating log window
        if (!logWindowSetup()) return;
      }
      // Might not exist if document hasn't finished loading
      _log.apply(this,arguments);
    }
  };

  var logWindow = null;
   
  logWindowSetup = function() {
    if (!$(document.body)) {
      return false;
    }
    $(document.body).insert(new Element('div', { 'id': '_logwindow' }));
    logWindow = $('_logwindow');
    logWindow.absolutize();
    logWindow.setStyle({
      'width': '600px', 
      'height':'200px', 
      'backgroundColor':'#333', 
      'padding':'1em', 
      'color':'white', 
      'fontWeight':'normal', 
      'overflow': 'auto',
      'filter':'alpha(opacity=70)',
      '-moz-opacity':0.7,
      '-khtml-opacity': 0.7,
      'opacity': 0.7
    });
    layout(); 
    if (Prototype.Browser.IE) { 
      window.attachEvent('onresize', layout);
      window.attachEvent('onscroll', layout);
    } else { 
      Event.observe(document.onresize ? document : window, "resize", layout);
      Event.observe(document.onscroll ? document : window, "scroll", layout);
    }

    return true;
  };

  layout = function() {
    var top = 0, left = 0;
    var styles = {
        position: 'fixed'
    };
    
    if (Prototype.Browser.IE) {
      styles['position'] = 'absolute';
    }
    
    logWindow.setStyle(styles);
    
    var dimensions = document.viewport.getDimensions();
    top = parseInt(dimensions.height - logWindow.getHeight()-10);
    left = parseInt(dimensions.width - logWindow.getWidth()-10);
    
    if (Prototype.Browser.IE) {
      top += document.viewport.getScrollOffsets().top;
    }
    
    styles['top'] = top+'px';
    styles['left'] = left+'px';
    
    logWindow.setStyle(styles);
  };

  _log = function() {
    logWindow.insert(logFormatted(arguments));
  };

  logFormatted = function(objects, className)
  {
    var html = [];

    var format = objects[0];
    var objIndex = 0;

    if (typeof(format) != "string")
    {
      format = "";
      objIndex = -1;
    }

    var parts = parseFormat(format);
    for (var i = 0; i < parts.length; ++i)
    {
      var part = parts[i];
      if (part && typeof(part) == "object")
      {
        var object = objects[++objIndex];
        part.appender(object, html);
      }
      else
        appendText(part, html);
    }

    for (var i = objIndex+1; i < objects.length; ++i)
    {
      appendText(" ", html);

      var object = objects[i];
      if (typeof(object) == "string")
        appendText(object, html);
      else
        appendObject(object, html);
    }

    return new Element("div", { 'class': className }).update(html);
  };

  parseFormat = function(format)
  {
    var parts = [];

    var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
    var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};

    for (var m = reg.exec(format); m; m = reg.exec(format))
    {
      var type = m[8] ? m[8] : m[5];
      var appender = type in appenderMap ? appenderMap[type] : appendObject;
      var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);

      parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
      parts.push({appender: appender, precision: precision});

      format = format.substr(m.index+m[0].length);
    }

    parts.push(format);

    return parts;
  };

  // ***************************************************************************
  // From dojo/firebug.js
  function escapeHTML(value){
    function replaceChars(ch){
      switch(ch){
        case "<": return "&lt;";
        case ">": return "&gt;";
        case "&": return "&amp;";
        case "'": return "&#39;";
        case '"': return "&quot;";
      }
      return "?";
    }
    return String(value).replace(/[<>&"']/g, replaceChars);
  }

  function objectToString(object){
    try{
      return object+"";
    }catch(e){
      return null;
    }
  }

  function appendText(object, html){
    html.push(escapeHTML(objectToString(object)));
  };

  function appendNull(object, html){
    html.push('<span class="objectBox-null">', escapeHTML(objectToString(object)), '</span>');
  };

  function appendString(object, html){
    html.push('<span class="objectBox-string">&quot;', escapeHTML(objectToString(object)),
            '&quot;</span>');
  };

  function appendInteger(object, html){
    html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
  };

  function appendFloat(object, html){
    html.push('<span class="objectBox-number">', escapeHTML(objectToString(object)), '</span>');
  };

  function appendObject(object, html){
    try{
      if(object === undefined){
        appendNull("undefined", html);
      }else if(object === null){
        appendNull("null", html);
      }else if(typeof object == "string"){
        appendString(object, html);
      }else if(typeof object == "number"){
        appendInteger(object, html);
      }else{
        appendText(object, html);
      }
    }catch(e){
      /* squelch */
    }
  };

}).apply(C);

/**
 * Simple cookie access. By default expiration date is 3000 days in the future.
 * Based on: http://www.stilbuero.de/2006/09/17/cookie-plugin-for-jquery/
 *
 * GET:
 *   Cookies('the_cookie');
 * SET:
 *   Cookies('the_cookie', 'the_value');
 *   //set cookie with an expiration date seven days in the future
 *   Cookies('the_cookie', 'the_value', { expires: 7 }); 
 * DELETE:
 *   Cookies('the_cookie', null);               
 *   Cookies('the_cookie', '', { expires: -1 });
 *
 */
function Cookies(name, value) {
  if (typeof value != 'undefined') { // name and value given, set cookie
    C.log("setting cookie %s...", name);
    var future = new Date();
    future.setDate(future.getDate() + 3000);
    var options = Object.extend({
      expires: future.toGMTString()
    }, arguments[2] || { });
    // options = options || {};
    if (value === null) {
      value = '';
      options.expires = -1;
    }
    var expires = '';
    if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
      var date;
      if (typeof options.expires == 'number') {
        date = new Date();
        date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
      } else {
        date = options.expires;
      }
      expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
    }
    var path = options.path ? '; path=' + (options.path) : '';
    var domain = options.domain ? '; domain=' + (options.domain) : '';
    var secure = options.secure ? '; secure' : '';
    C.log("... to %s", [name, '=', encodeURIComponent(value), expires, path, domain, secure].join(''));
    document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
  } else { // only name given, get cookie
    C.log("retrieving cookie %s", name);
    var cookieValue = null;
    if (document.cookie && document.cookie != '') {
      var cookies = document.cookie.split(';');
      for (var i = 0; i < cookies.length; i++) {
        var cookie = cookies[i].strip();
        // Does this cookie string begin with the name we want?
        if (cookie.substring(0, name.length + 1) == (name + '=')) {
          cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
          break;
        }
      }
    }
    C.log("with value %s", cookieValue);
    return cookieValue;
  }
};

