if (typeof Cookstr == 'undefined') {
  var Cookstr = {};
}

Cookstr.queryString = function(url) {
  if (! url) {
    return '';
  }

  var index = url.indexOf('?')
  if (index == url.length || index == -1) {
    return ''
  }
  
  return url.substr(url.indexOf('?') + 1);
},

Cookstr.queryToHash = function(queryString) {
  if (queryString == null || queryString == '') {
    return {};
  }

  var decode = function(string) {
    return decodeURIComponent(string).replace(/\+/g, ' ')
  }

  var pairs = queryString.split('&');
  var i;
  var hash = {};
  for(i = 0; i < pairs.length; i++) {
    var tokens = pairs[i].split('=');
    var key = decode(tokens[0])
    var multiValued = key.match(/\[\]/)
    key = key.replace('[]', '')
    var value = tokens.length > 1 ? decode(tokens[1]) : '';
    var currentValue = hash[key];
    if (currentValue === undefined) {
      hash[key] = multiValued ? [value] : value;
    } else {
      // it's multi-valued
      currentValue.push(value);
    }
  }

  return hash;
};

Cookstr.setCookie = function(name, value, ttlSeconds) {
  if (ttlSeconds) {
    var date = new Date();
    date.setTime(date.getTime()+(ttlSeconds * 1000));
    var expires = "; expires="+date.toGMTString();
  }
  else {
    var expires = "";
  }
  document.cookie = name+"="+value+expires+"; path=/";
};

Cookstr.getCookie = function(name) {
  var nameEQ = name + "=";
  var cookies = document.cookie.split(';');
  for(var i=0;i < cookies.length;i++) {
    var c = jQuery.trim(cookies[i]);
    if (c.indexOf(nameEQ) == 0) {
      return c.substring(nameEQ.length, c.length);
    }
  }
  return null;
};

Cookstr.clearCookie = function(name) {
  Cookstr.setCookie(name, "", -1)
};


Cookstr.SearchWidget = {
  searchTextParamName: 'st',
  submitOnClearSearch: false,

  init: function() {
    Cookstr.SearchWidget.loadParamsIfNecessary();
    Cookstr.SearchWidget.initializeExpandedElements(jQuery);
    Cookstr.SearchWidget.initializeSelectTags(jQuery);
    Cookstr.SearchWidget.initializeCheckboxes(jQuery);
    Cookstr.SearchWidget.initializeSearchField(jQuery);
    Cookstr.SearchWidget.bindBehaviors(jQuery);
    Cookstr.SearchWidget.scrollToPreviousPosition(jQuery);
  },

  searchParamsIncluded: function() {
    return !(Cookstr.SearchWidget.params[Cookstr.SearchWidget.searchTextParamName] === undefined);
  },

  initializeSearchField: function($) {
    var paramName = Cookstr.SearchWidget.searchTextParamName;
    if(Cookstr.SearchWidget.params[paramName]) {
      $('#cookstr-search-form input.recipe-text').val(Cookstr.SearchWidget.params[paramName]);
    }
  },

  initializeExpandedElements: function($) {
    $('#cookstr-search-form li[search-key]').each(function() {
      var searchKey = $(this).attr('search-key');
      if (Cookstr.SearchWidget.params[searchKey + '-e'] == 1) {
        $(this).find('.cookstr-field-name').addClass('expanded');
        $(this).find('.cookstr-field-name').addClass('expanded-name');
        $(this).find('.cookstr-form-element').addClass('expanded');
        $(this).find('.cookstr-form-element').addClass('expanded-element');
      }
    });
  },

  initializeSelectTags: function($) {
    $('#cookstr-search-form li[search-key] select').each(function() {
      var name = $(this).attr('name');
      var value = Cookstr.SearchWidget.params[name];
      if (value) {
        $(this).val(value)
      }
    });
  },

  initializeCheckboxes: function($) {
    $('#cookstr-search-form li[search-key]').each(function() {
      var li = this;
      var searchKey = $(li).attr('search-key');
      if (Cookstr.SearchWidget.params[searchKey]) {
        $(li).find('input[type=checkbox][value=Yes]').attr('checked', 'checked');
        $.each(Cookstr.SearchWidget.params[searchKey], function() {
          $(li).find('input[type=checkbox][value=' + this + ']').attr('checked', 'checked');
        });
      }
    });
  },

  scrollToPreviousPosition: function($) {
    if (Cookstr.SearchWidget.autoscrollingEnabled) {
      var position = Cookstr.getCookie('scrollPosition');
      $(window).scrollTop(position);
      Cookstr.clearCookie('scrollPosition');
    }
  },

  recordScrollPosition: function() {
    if (Cookstr.SearchWidget.autoscrollingEnabled) {
      Cookstr.setCookie('scrollPosition', jQuery(window).scrollTop(), 60);
    }
  },

  bindBehaviors: function($) {
    $('#cookstr-search-form .cookstr-field-name a').click(Cookstr.SearchWidget.toggleFormElement);
    $('a#cookstr-clear-search-link').click(Cookstr.SearchWidget.clearForm);
    if (Cookstr.SearchWidget.submitOnClearSearch) {
      $('a#cookstr-clear-search-link').click(Cookstr.SearchWidget.submitSearchForm);
    }
    $('#cookstr-search-form').submit(Cookstr.SearchWidget.recordScrollPosition);
    $('#cookstr-search-form').submit(Cookstr.SearchWidget.appendHiddenExpansionFields);
    $('#cookstr-search-form input[type=checkbox]').change(Cookstr.SearchWidget.submitSearchForm);
    $('#cookstr-search-form select').change(Cookstr.SearchWidget.submitSearchForm);

    if (jQuery.browser.msie) {
      $("#cookstr-search-form input[type=checkbox]").click(function() {
        $(this).trigger( 'change' )
      });
    }
  },

  toggleFormElement: function() {
    jQuery(this).parents('.cookstr-field-name').toggleClass('expanded');
    jQuery(this).parents('.cookstr-field-name').toggleClass('expanded-name');
    jQuery(this).parents('.cookstr-search-field').children('.cookstr-form-element').toggleClass('expanded');
    jQuery(this).parents('.cookstr-search-field').children('.cookstr-form-element').toggleClass('expanded-element');
    return false;
  },

  appendHiddenExpansionFields: function() {
    var expandedFields = jQuery('div.cookstr-field-name.expanded').parents('li.cookstr-search-field')
    expandedFields.each(function() {
      var hiddenFieldName = jQuery(this).attr('search-key') + '-e';
      jQuery('#cookstr-search-form').append("<input type='hidden' name='" + hiddenFieldName + "' value='1'/>");
    });
  },

  clearForm: function() {
    var form = jQuery('#cookstr-search-form');
    form.get(0).reset();
    jQuery('input[name=st]', form).attr('value', '');
    jQuery('input', form).removeAttr("checked");
    jQuery('.cookstr-form-element', form).removeClass('expanded');
    jQuery('.cookstr-form-element', form).removeClass('expanded-element');
    jQuery('.cookstr-field-name', form).removeClass('expanded');
    jQuery('.cookstr-field-name', form).removeClass('expanded-name');
    return false;
  },

  submitSearchForm: function() {
    Cookstr.SearchWidget.recordScrollPosition();
    jQuery('#cookstr-search-form').submit();
    return false;
  },

  loadParamsIfNecessary: function() {
    // if the params hash is not already defined, we assume we're on a recipe detail
    // page having linked from a search results page
    if (typeof Cookstr.SearchWidget.params == 'undefined') {
      Cookstr.SearchWidget.params = Cookstr.queryToHash(Cookstr.queryString(document.referrer));
    }
  }
};


Cookstr.Base64 = {
  enc64List: [],
  dec64List: [],

  init: function() {
    var enc64List = Cookstr.Base64.enc64List;
    var dec64List = Cookstr.Base64.dec64List;
    var i;
    for (i = 0; i < 26; i++) {
        enc64List[enc64List.length] = String.fromCharCode(65 + i);
    }
    for (i = 0; i < 26; i++) {
        enc64List[enc64List.length] = String.fromCharCode(97 + i);
    }
    for (i = 0; i < 10; i++) {
        enc64List[enc64List.length] = String.fromCharCode(48 + i);
    }
    enc64List[enc64List.length] = "+";
    enc64List[enc64List.length] = "/";
    for (i = 0; i < 128; i++) {
        dec64List[dec64List.length] = -1;
    }
    for (i = 0; i < 64; i++) {
        dec64List[enc64List[i].charCodeAt(0)] = i;
    }
  },

  decode: function(str) {

    var c=0, d=0, e=0, f=0, i=0, n=0;
    var input = str.split("");
    var output = "";
    var ptr = 0;
    do {
        f = input[ptr++].charCodeAt(0);
        i = Cookstr.Base64.dec64List[f];
        if ( f >= 0 && f < 128 && i != -1 ) {
            if ( n % 4 == 0 ) {
                c = i << 2;
            } else if ( n % 4 == 1 ) {
                c = c | ( i >> 4 );
                d = ( i & 0x0000000F ) << 4;
            } else if ( n % 4 == 2 ) {
                d = d | ( i >> 2 );
                e = ( i & 0x00000003 ) << 6;
            } else {
                e = e | i;
            }
            n++;
            if ( n % 4 == 0 ) {
                output += String.fromCharCode(c) +
                          String.fromCharCode(d) +
                          String.fromCharCode(e);
            }
        }
    }
    while (typeof input[ptr] != "undefined");
    output += (n % 4 == 3) ? String.fromCharCode(c) + String.fromCharCode(d) :
              ((n % 4 == 2) ? String.fromCharCode(c) : "");
    return output;
  }
}

Cookstr.Base64.init();
