// The Golden Rule
var $j = jQuery.noConflict();

(function($){
  $.extend($.expr[':'],{
    readonly: function(a) {
      return !!a.readOnly;
    }
  });
})(jQuery);

// Session Expiration Notification
(function($){
  $(window).load(function(){
    var url = window.location.toString();
    url.match(/\?(.+)$/);
    var params = RegExp.$1;
    var params = params.split("&");
    for( var i=0;i<params.length;i++ )
    {
      var tmp = params[i].split("=");
      if (tmp[0] == "message" && tmp[1] == "expired") {
        $.fn.statusMessage("Your session has expired.");
      }
    }
  });
})(jQuery);

/* Layer takes any element, passed to it as a selector (content), and renders it 
 * in a "layer" that is positioned relative to its containing elment (trigger).
 */
(function($){
  
  $.layer = {
    blocked: false,
    defaults: {
      animate: false,
      // id: 'Layer',
      placement: 'above',
      trigger: null
    },
    block: function() {
      $.layer.blocked = !$.layer.blocked;
    }
  }
  
  $.fn.extend({
    layer: function(options) {
      opts = $.extend({}, $.layer.defaults, options);
      $(document).ready(function() { insertLayer(opts); });
      return this.each(function() {
        var onShow = opts.onShow || function (){};
        $.data(this, 'layer', opts)
        // console.log($(this).data('layer'))
      })
      .click(handleClick);
    },
    display: function(elem) {
      $(this).appendTo(opts.layer)
      opts.layer
        .find(':first-child')
          .show()
        .end()
          .css({
            position: 'absolute',
            top: getMetrics(elem).top+'px',
            left: getMetrics(elem).left+'px'
          });
      (opts.animate) ? opts.layer.show('blind', 500) : opts.layer.show();
      $.layer.block();
      $(document).click(listenForHide);
      if ($.browser.msie && $.browser.version.substr(0,1) == 6)
        $('select:not(".layer select")').hide();
      if ($.data(elem, 'layer').onShow)
        $.data(elem, 'layer').onShow(opts.layer);
    },
    undisplay: function() {
      var content = opts.layer.children().eq(0).attr('id');
      var link    = $('a[href="#'+content+'"]');
      link.after($('#'+content).hide());
      opts.layer.hide();
      if ($.browser.msie && $.browser.version.substr(0,1) == 6)
        $('select:not(".layer select")').show();
      $(document).unbind('click', listenForHide);
    }
  })
  
  function insertLayer(opts) {
    opts.layer = $('<div class="layer"></div>').appendTo(document.body).hide();
    // opts.layer = $('<div id="'+opts.id+'" class="layer"></div>').appendTo(document.body).hide();
  }
  
  function getMetrics(elem) {
    $(elem).css('position', 'relative');
    return {
      top: ($(elem).data('layer').placement == 'above') ? $(elem).offset().top -= opts.layer.height() : $(elem).offset().top += $(elem).height(),
      left: $(elem).offset().left -= 5
    }
  }
  
  function handleClick(e) {
    if (e) e.preventDefault();
    if ($.layer.blocked) return;
    if (opts.layer.css('display') == 'block') $(opts.trigger).undisplay();
    
    var selector = $(this).data('layer').content || $(this).attr('href');
    opts.trigger = this;
    $(this)
      .next(selector)
        .display(this)
  }
  
  function handleCustomToggleChange(e) {
    var target = $(this), isChecked = target.attr('checked'), label;

    (label = target.prevAll('.custom-toggle-label').eq(0)).length ||
      (label = target.nextAll('.custom-toggle-label').eq(0)).length;

    label.removeClass('checked').addClass(isChecked ? 'checked' : '');
  }
  
  function listenForHide(e) {
    if (!$.layer.blocked) {
      if ($(e.target).parents('.layer').length == 0 && opts.layer.css('display') == 'block') {
        opts.layer.undisplay();
      }
    } else {
      $.layer.block();
    }
  }
    
})(jQuery);

// Cake Favorites
(function($){
  
  // Favorites encapsultes favoriting a cake or party plan
  // Most differences can be determined by the name, but can override
  function Favorites (name, params) {
    var defaults = {
      name: name,
      dataAttr: 'data-'+name+'id',
      linkClass: 'favorite-'+name,
      inputId: '#'+name+'_id',
      url: '/ajax/favorite_'+name+'s.json',
      favoriteTrackerUrl: '/favorite-this-'+name,
      unfavoriteTrackerUrl: '/unfavorite-this-'+name,
      responseIdAttr: name +'_id'
    };
    $.extend(this, defaults, params);    
  };
  
  Favorites.prototype = {
    initElements: function(elements, options) {
      var self = this;
      if ($.cookie('registered_user') == 'true') this.getFavs();
      return elements.click(function (e) { self.handleClick(e); });
    },
    
    // Get elements linked to this itemId, optionally of a given tag
    linkedElements: function(itemId, tag) {
      tag || (tag="*");
      var selector = '['+ this.dataAttr +'="'+ itemId +'"] a.'+ this.linkClass;
      return $(tag + selector);
    },
    
    linkedWithText: function (itemId) {
      return this.linkedElements(itemId, 'p').add(this.linkedElements(itemId, 'span'));
    },
    
    getFavs: function () {
      this.doAjax('get', 'index');
    },
    
    handleClick: function (e) {
      e.preventDefault();
      
      var target = $(e.target),
        itemId = target.closest('li').attr(this.dataAttr) || $(this.inputId).val(),
        method = target.hasClass('added') ? 'delete' : 'create';
        
      this.doAjax('post', method, itemId);

      try {
        var pageTracker = _gat._getTracker("UA-8529536-1");
        var pageURL = (method == 'create') ? this.favoriteTrackerUrl : this.unfavoriteTrackerUrl;
        pageTracker._trackPageview(pageURL);
      } catch(err) {}
    },
    
    doAjax: function (type, method, itemId) { 
      var success, dataType, self = this;
        
      if (itemId) {
        dataType = 'text';
        success = function () { self.handleFavoriteUpdate(itemId, method) };
      }
      else {
        dataType = 'json';
        success = this.handleFavoriteFetch;
      }

      $.ajax({
        type: type,
        dataType: dataType,
        url: this.url,
        data: {
          _method: method,
          id: itemId
        },
        context: this,
        error: this.handleFavoriteError,
        success: success
      });
    },
    
    // changes the text and icon
    updateLinkedElements: function (el, created) {
      var $this, text, 
        defaultText = created ? 'Remove from Favorites' : "Make it a Favorite";
      el.toggleClass('added', created).each(function () {
        // update link text with the default, or maybe grab from title
        $this = $(this);
        text = (!created && $this.attr('data-favorite-text')) || defaultText;
        $this.text(text);
      });
      el.prev('.favorite-text').toggle(!created); // for plan favorite "Don't forget" text
    },
    
    // either we added or removed it as a favorite
    handleFavoriteUpdate: function (itemId, method) {
      var linkedWithText, 
        created = (method == 'create');

      this.linkedElements(itemId, 'li').toggleClass('added', created);
      
      if ($(this.inputId).length)
        this.updateLinkedElements(this.linkedWithText(itemId), created);
    },
    
    // fetched the list of favorites
    handleFavoriteFetch: function (data) {
      var self = this, idAttr = this.responseIdAttr;
      $('a.'+this.linkClass).removeClass('added');
      $(data).each(function(i, node) {
        self.updateLinkedElements(self.linkedElements(node[idAttr]), true);
      });
    },

    handleFavoriteError: function (data, textStatus) {        
      if (data.status == 412)
        $.fn.statusMessage('You must sign-in to use this feature.');
    }
  };
  
  // Create 'favorites' objects for cakes and party plans
  var cakefav = new Favorites('cake', {
    url: "/ajax/favorites.json",
    linkClass: 'favorite',
    responseIdAttr: 'item_id'
  });
  var planfav = new Favorites('plan');

  // wire 'favorites' objects in to jquery 
  $.extend({  // don't believe these are needed
    cakeFavorites: { getFavs: function () { cakefav.getFavs() } },
    planFavorites: { getFavs: function () { planfav.getFavs() } }
  });
  $.fn.extend({
    cakeFavorites: function() { return cakefav.initElements(this) },
    planFavorites: function() { return planfav.initElements(this) }
  });
  
})(jQuery);


(function($){
  
  $.imgProcess = {
    count: 0,
    firstRun: true
  }
  
  $.fn.extend({
    imgProcess: function(options) {
      var options = $.extend({}, $.imgProcess, options);
      
      return this.each(function(i, el) {
        var obj = $(this);
        var slides = obj.find('a');
        
        slides.eq(0).css({
          display: 'block',
          opacity: 1.0
        });
        
        if (slides.length <= 1) return;
        
        var to = window.setInterval(function() {
          crossFade(slides, options);
        }, 3000);
      });    
    }
  });
  function crossFade(slides, options) {
    if (options.firstRun) {
      slides.eq(1).css('display', 'block');
      options.firstRun = false;
    }
    current = slides.eq(options.count);
    slides
      .eq(options.count)
        .animate({ opacity: 0.0 }, 1000, function(){ current.css('display', 'none') });
    (options.count < slides.length-1) ? options.count++ : options.count = 0;
    slides
      .eq(options.count)
        .css('display', 'block')
          .animate({ opacity: 1.0 }, 1000);
  };
  
})(jQuery);

// Events page
(function($){
  
  $.eventsControl = {
    defaults: {
      eventsObj: []
    }
  };
  
  $.fn.extend({
    eventsControl: function(options) {
      var options = $.extend({}, $.eventsControl.defaults, options);
      return this.each(function() {
        $.data(this, 'event', options);
        el = $(this);
        options.sel         = el.find('select#fbEventName');
        options.checkBox    = el.find('input:checkbox');
        options.eventName   = el.find('#event_name');
        options.createForm  = el.find('#CreateEvent');
        options.sel.bind('change', options, selectChange);
        options.checkBox.bind('change', options, checkboxChange);
      });
    }
  });
  
  function selectChange(e) {
    if (this.value == "false") {
      e.data.createForm
        .find(':readonly')
          .removeAttr('readonly')
            .val('');
      $('.ui-datepicker-trigger:first').show();
    } else {
      var fbId = this.value;
      var eventData = $.grep(e.data.eventsObj, function(obj, i) {
        // Get data for facebook event id
        return obj.eid == fbId;
      });
            
      // Set details for new cake event based on facebook event data
      e.data.eventName
        .attr('readonly', 'readonly')
          .val(eventData[0].name);
      e.data.checkBox.each(function(i, el) {
        
        // Get data for current form input from currently selected event
        var newVal = eventData[0][this.value];
        
        // Format if current input is date
        if (this.name == 'event_event_date') {
          newVal = $.datepicker.formatDate('MM d, yy', new Date(newVal * 1000));
          $('.ui-datepicker-trigger:first').hide();
        }
        
        // Set corresponding form input in create new event form, disable input
        e.data.createForm
          .find('#' + this.name)
            .attr('readonly', 'readonly')
              .val( el.checked ? newVal : '' );
      });
    }
  }
    
  function checkboxChange(e) {
    var fbId = $('#FbEventName').val();
    if (fbId != 'false') {
      var el = e.data.createForm.find('#' + this.name);
      var eventData = $.grep(e.data.eventsObj, function(obj, i) {
        // Get event data for facebook event id
        return obj.eid == fbId;
      });
      el.val( this.checked ? eventData[0][this.value] : '' );
    }
  }
  
})(jQuery);

// Utility functions
(function($){
  
  $.fn.truncate = function(txt, length, truncation) {
    length = length || 30;
    truncation = (truncation == undefined) ? '...' : truncation;
    return txt.length > length ?
      txt.slice(0, length - truncation.length) + truncation : String(txt);
  };
  
  // Use this for collapsible panes (not chainable)
  $.fn.toggleable = function(e) {
    var me = $(e.target);
    var t = (me.hasClass('.trigger') ? me : me.closest('.trigger'));
    (t.hasClass('open')) ? t.removeClass('open').next().hide() : t.addClass('open').next().show();
    return false;
  };
  
  // Creates a status message at the top of the page, similar to rails flash:notice method (not chainable)
  $.fn.statusMessage = function(content) {
    var statusmsg = '<div id="StatusMessage"><p>'+content+'</p></div>';
    if ($('#StatusMessage').length == 0) $('body').prepend(statusmsg);
    window.scrollTo(0,0);
    var clear = setTimeout(function() {
      $('#StatusMessage').slideUp(1000, onFinish);
      clearTimeout(clear);
    }, 4000);
    function onFinish() {
      $(this).remove();
    }
  };
  
  $.fn.registered = function(bool) {
    $.cookie('registered_user', bool, { path:'/' });
  };
  
  // Use this to set consistent heights on floated list elements (chainable)
  $.fn.extend({
    doHeights: function(sel) {
      var h = 0;
      return $(this).find('li').each(function(i, el) {
        if ($(el).outerHeight() > h) h = $(el).outerHeight();
      }).height(h);
    }
  });
  
  $(window).load(function(){
  	
		if ($('a.favorite-plan').length > 0) $('a.favorite-plan').planFavorites();
    if ($('a.favorite').length > 0) $('a.favorite').cakeFavorites();
    if ($('ul.selections').length > 0) $('ul.selections:visible').doHeights();
    if ($('.category-list').length > 0) {
      var cname = $('.category-list').prev('h3').text();
      $('.category-list').treeview({
        collapsed:true,
        persist:'cookie',
        cookieId:cname
      });
    };   
    
    $(".btn-close").bind('click', function(){
      jQuery.fancybox.close();
    });

    $(".btn-order").bind('click', function(){
      
      var consumerFirstName = $("input#consumer_first_name").val(), 
        consunmerLastName = $("input#consumer_last_name").val(), 
        consumerPhoneAreaCode = $("input#consumer_phone_area_code").val(), 
        consumerPhonePrefix = $("input#consumer_phone_line_prefix").val(), 
        consumerPhoneNumber = $("input#consumer_phone_line_number").val(),
        consumerEmail = $("input#consumer_email_order").val(), 
        cakeMessage = $("textarea#cake_message").val(), 
        cakeNote = $("textarea#cake_note").val(),
        
        cakeSize = $("select#cakeSize").val(),
        cakeFlavor = $("select#cakeFlavor").val(),
        cakeIcing = $("select#cakeIcing").val(),
        cakeIcingColor = $("select#cakeIcingColor").val();
        cakeFilling = $("select#cakeFilling").val();
      
      $("span.order-first-name").text(consumerFirstName);
      $("span.order-last-name").text(consunmerLastName);
      
      $("span.order-phone.area-number").text('('+consumerPhoneAreaCode+')');
      $("span.order-phone.prefix-number").text(consumerPhonePrefix);
      $("span.order-phone.line-number").text(consumerPhoneNumber);
      $("span.consumer-email").text(consumerEmail);
      $("dd.message-on-cake").text(cakeMessage);
      
      $("dd.decorator-note").text(cakeNote);
      
      $("dd.cake-size").text(cakeSize);
      $("dd.cake-flavor").text(cakeFlavor);
      $("dd.cake-icing").text(cakeIcing);
      $("dd.cake-icing-color").text(cakeIcingColor);
      $("dd.cake-filling").text(cakeFilling);
        
    });
    // $("input#consumer_email").keyup(function () {
    //   var value = $(this).val();
    //   $("span.consumer-email").text(value);
    // })
  });
    
})(jQuery);

String.prototype.capitalize = function(){ //v1.0
    return this.replace(/\w+/g, function(a){
        return a.charAt(0).toUpperCase() + a.substr(1).toLowerCase();
    });
};

// TEMPORARY HOME FOR NON-FIREBUG CONSOLE LOGGING, CAN REMOVE FOR PRODUCTION
if (!window.console){ // CONSOLE LOGGING FOR IE
    var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
    window.console = {};
    for (var i=0; i<names.length; ++i) window.console[names[i]] = function(){}
};

jQuery(function ($) {
  $('.planning-home .expand-content').click(showContent);
  $('.planning-home .expand-content .close-btn, .planning-home h3').click(hideContent); 
  
  function showContent () {
    var container = $(this).closest('.expand-module');
    if (container.hasClass('collapsed')) {
      $(this).animate({height: 340}, function () { container.removeClass('collapsed'); });
    }
    return false;
  }
  function hideContent () {
    var container = $(this).closest('.expand-module');
    if (container.hasClass('collapsed')) 
      return; // propagate to showContent handler
    container.addClass('collapsed')
    $(this).closest('.expand-content').animate({height: 50});
    return false;
  }
});

