$(function(){
  $("img[src*=-off.]").rollover();
  $('.collapse_link').collapselink();
  $('dl').collapselist();
  $([$('a:has(img[src*=button])'), $('#heartwill_tabset')]).each(function(){$(this).pngFix();});
  setInterval(function(){$.get('/ping.html?'+Math.random());}, 1500*1000); // 25 minutes
  $('.tooltip').each(function(){$(this).tooltip({showURL:false})});
  $('#page_container h1').after('<strong><hr class="main" /></strong>');
});

(function($){
  $.fn.rollover = function(options)
  {
    var opts = $.extend({}, $.fn.rollover.defaults, options);
    
    return this.each(function(){
      var offImg = new Image(); offImg.src = $(this).attr('src');
      var overImg = new Image(); overImg.src = $(this).attr('src').replace(opts.off_suffix, opts.over_suffix);
      $(this).hover(function(){$(this).attr('src', overImg.src);}, function(){$(this).attr('src', offImg.src);});
    });
  }
  
  $.fn.rollover.defaults = {
    off_suffix: '-off.',
    over_suffix: '-over.'
  }
})(jQuery);

(function($){
  $.fn.collapselink = function(options)
  {
    var opts = $.extend({}, $.fn.collapselink.defaults, options);
    
    return this.each(function(){
      var target = $(this).attr('href');
      
      $(this).click(function(){
        if ($(target).is(':visible'))
        {
          $(target).slideUp(opts.effect_speed);
          $(this).text(opts.collapsed_text);
        }
        else
        {
          $(target).slideDown(opts.effect_speed);
          $(this).text(opts.expanded_text);
        }
        
        return false;
      });
    });
  }
  
  $.fn.collapselink.defaults = {
    effect_speed: 'slow',
    expanded_text: 'Collapse List',
    collapsed_text: 'Expand List'
  };
})(jQuery);

(function($){
  $.fn.collapselist = function(options)
  {
    var opts = $.extend({}, $.fn.collapselist.defaults, options);
    
    return $(this).each(function(){
      var dl = $(this);
      
      dl.bind('close_all', function(){$('dt', dl).each(function(){$(this).trigger('close');});});
      
      $('dt', $(this)).each(function(){
        var dt = $(this);
        
        dt.data('definition_element', dt.next('dd'));
        
        dt.bind('open', function(){if (opts.open_single) dl.trigger('close_all'); dt.data('definition_element').slideDown(opts.effect_speed); dt.addClass('open');});
        
        dt.bind('close', function(){dt.data('definition_element').slideUp(opts.effect_speed); dt.removeClass('open');});
        
        dt.bind('click', function(){dt.trigger(dt.data('definition_element').is(':visible') ? 'close' : 'open');});
        
        if (opts.initially_collapsed) dl.trigger('close_all');
      });
    });
  };
  
  $.fn.collapselist.defaults = {
    effect_speed: 'fast',
    initially_collapsed: true,
    open_single: true
  };
})(jQuery);

(function($){
  $.cookie = function(name, value, days)
  {
    var get = function()
    {
      var nameEQ = name + "=";
      var ca = document.cookie.split(';');
      
      for(var i=0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
      }
      
      return null;
    }
    
    var set = function()
    {
      if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        var expires = "; expires=" + date.toGMTString();
      }
      else var expires = "";
      
      document.cookie = name + "=" + value + expires + "; path=/";
    }
    
    if (arguments.length == 1)
    {
      return get();
    }
    else
    {
      return set();
    }
  }
})(jQuery);

(function($){
  $.fn.myheartwilldialog = function(options)
  {
    var opts = $.extend({}, $.fn.myheartwilldialog.defaults, options);

    var buttons = {};
    buttons[opts.cancel_button] = function(){dialog.dialog('close');};
    buttons[opts.ok_button] = function()
    {
      dialog.addClass('loading').html('');
      
      $.ajax({
        cache: false,
        complete: function(){dialog.dialog('close'); opts.complete();},
        data: $.fn.myheartwilldialog.form_data,
        error: function(){alert(opts.error_message); opts.error();},
        success: function(data){
          if (opts.update_element)
          {
            opts.update_element.slideUp('fast', function(){
              opts.update_element.html(data);
              opts.update_element.slideDown();
            });
          }
          
          opts.success();
        },
        type: 'post',
        url: opts.url
      });
    };
    
    var dialog = $(opts.dialog_element).dialog({
      autoOpen: false,
      modal: true,
      buttons: buttons
    });
    
    return this.each(function(){
      $(this).click(function(){
        $.fn.myheartwilldialog.form_data = {};
        
        // Parse the anchor's rel attribute into post data
        if ($(this).attr('rel')) $.fn.myheartwilldialog.form_data = eval('new function(){return '+$(this).attr('rel')+';}();');
        
        // Make all form fields update a global var to post
        $(':input', dialog).each(function(){
          $(this).bind('change', function(){
            $.fn.myheartwilldialog.form_data[$(this).attr('name')] = $(this).val();
          });
        });
        
        // Prepopulate form fields based on the bind option
        for (var elId in options.bind) $('#'+elId).val($(options.bind[elId], $(this).parent().parent()).text());
        
        dialog.dialog('open');
        
        return false;
      });
    });
  }
  
  $.fn.myheartwilldialog.defaults = {
    dialog_element: $('<div title="New Dialog"></div>'),
    error_message:  'Could not complete transation.',
    update_element: null,
    url:            '',
    ok_button:      'OK',
    cancel_button:  'Cancel',
    success:        function(){},
    error:          function(){},
    complete:       function(){}
  };
})(jQuery);

(function($){
  $.fn.scroller = function(options)
  {
    var opts = $.extend({}, $.fn.scroller.defaults, options);
    
    $(this).wrapInner('<div class="scrolling_sidebar"></div>');
    
    var scrolling_section = $('.scrolling_sidebar', $(this));
    
    var $this = $(this);
    
    var begin = function()
    {
      var item_height = (opts.item_height ? opts.item_height : $('li', scrolling_section).outerHeight());
      $(scrolling_section).height(item_height * 3);
      
      if ($('li', scrolling_section).length > 6)
      {
        var up_arrow = $('<a href="#" class="scrolling_sidebar_up">'+opts.up_arrow_content+'</a>').click(function(){
          scrolling_section.animate({
            scrollTop: scrolling_section.scrollTop() - item_height
          });
          
          return false;
        });
        $this.append(up_arrow);
        $(up_arrow).css({
          position: 'absolute',
          top: 0,
          left: (scrolling_section.outerWidth()/2) - (up_arrow.outerWidth()/2)
        });
        
        var down_arrow = $('<a href="#" class="scrolling_sidebar_down">'+opts.down_arrow_content+'</a>').click(function(){
          scrolling_section.animate({
            scrollTop: scrolling_section.scrollTop() + item_height
          });
          
          return false;
        });
        $this.append(down_arrow);
        down_arrow.css({
          position: 'absolute',
          top: scrolling_section.height() - down_arrow.height(),
          left: (scrolling_section.width()/2) - (down_arrow.width()/2)
        });
      }
    };
    
    /*
     * WebKit browsers (Safari and Chrome) load JavaScript and CSS information in parallel. 
     * Thus, JavaScript may execute before the styling effects of CSS have been computed,
     * returning the wrong height.
     * http://stackoverflow.com/questions/318630/get-real-image-width-and-height-with-javascript-in-safari-chrome
     */
    $('.thumbnail_list_image_container img:last', scrolling_section).load(function(){setTimeout(begin, 50)});
  }
  
  $.fn.scroller.defaults = {
    item_height: null,
    up_arrow_content: 'Up',
    down_arrow_content: 'Down'
  }
})(jQuery);

(function($){
  $.fn.textsize = function(options)
  {
    var $this = $(this);
    
    var opts = $.extend({}, $.fn.textsize.defaults, options);
    var current_scale = 1;
    
    var smaller = function(){return set(current_scale - opts.increment);}
    var reset = function(){return set(1);}
    var larger = function(){return set(current_scale + opts.increment);}
    var set = function(new_scale){$.cookie(opts.cookie_name, new_scale); return apply(new_scale);}
    
    var apply = function(new_scale)
    {
      current_scale = parseFloat(new_scale);
      $this.css('font-size', current_scale + 'em');
      return false;
    }
    
    if (cookie_value = $.cookie(opts.cookie_name)) apply(cookie_value);

    if (opts.smaller_link) $(opts.smaller_link).click(smaller);
    if (opts.reset_link) $(opts.reset_link).click(reset);
    if (opts.larger_link) $(opts.larger_link).click(larger);
  }
  
  $.fn.textsize.defaults = {
    cookie_name: 'text_size',
    increment: .1
  };
})(jQuery);

(function($){
  $.fn.fieldlabel = function(options)
  {
    var opts = $.extend({}, $.fn.fieldlabel.defaults, options);

    return this.each(function(){
      var $this = $(this);

      $this.data('default', $this.val());

      $this.focus(function(){if ($this.data('default') == $this.val()) $this.val('');});

      $this.blur(function(){if ('' == $this.val()) $this.val($this.data('default'));});

      $this.closest('form').submit(function(){if ($this.val() == $this.data('default')) $this.val('');});
    });
  };

  $.fn.fieldlabel.defaults = {};
})(jQuery);

(function($){
  $.fn.strengthIndicator = function(options)
  {
    var opts = $.extend({}, $.fn.strengthIndicator.defaults, options);

    return this.each(function(){
      var timer;
      var $this = $(this);
      var func = {};

      $this.parent().append('<span class="'+opts.indicatorClass+'"></span>');
      var indicator = $('.' + opts.indicatorClass, $this.parent());

      func._checkStrength = function()
      {
        var pw = $this.val();

        if (pw.match(/[a-z]/g) && pw.match(/[A-Z]/g) && pw.match(/[0-9]/g) && pw.match(/^(.{6,12})$/g))
        {
          if (pw.match(/[a-z]/g).length > 1 && pw.match(/[A-Z]/g).length > 1 && pw.match(/[0-9]/g).length > 1 && pw.length > 7)
          {
            // EXCELLENT: lc>1 and uc>1 and num>1 and pw > 7 and punc>0
            if (pw.match(/\W/g)) return 3;

            // GOOD: lc>1 and uc>1 and num>1 and pw > 7
            else return 2;
          }
          // MEDIUM: lc>0 and uc>0 and num>0 and 6 < pw < 12
          else return 1;
        }

        // BAD: 0lc or 0uc or 0num or 6 > pw > 12
        return 0;
      }

      func._updateStrength = function(text, additionalClass)
      {
        indicator.html(text).attr('class', opts.indicatorClass + ' ' + additionalClass);
      }

      func._displayStrength = function(strength)
      {
        if (!strength) var strength = func._checkStrength();

        if (strength == 3) func._updateStrength(opts.excellentText, opts.excellentClass);
        else if (strength == 2) func._updateStrength(opts.goodText, opts.goodClass);
        else if (strength == 1) func._updateStrength(opts.mediumText, opts.mediumClass);
        else func._updateStrength(opts.badText, opts.badClass);
      }

      $this.bind('keypress', function()
      {
        clearTimeout(timer);
        timer = setTimeout(function(){
          func._displayStrength();
        }, opts.delay);
      });

      if (opts.preventSubmit) $this.closest('form').bind('submit', function(){
        if (func._checkStrength() == 0)
        {
          opts.preventSubmitCallback($this, func);
          return false;
        }
      });
    });
  }

  $.fn.strengthIndicator.defaults = {
    delay: 1000,
    preventSubmit: true,
    preventSubmitCallback: function($this, func){func._displayStrength(); $this.focus().parent().animate({marginLeft:'15px'}, 75, null, function(){$this.parent().animate({marginLeft:'0px'}, 75, null, function(){$this.parent().animate({marginLeft:'15px'}, 75, null, function(){$this.parent().animate({marginLeft:'0px'}, 75, null, null);});});});},
    indicatorClass: 'strength_indicator',

    excellentClass: 'strength_indicator_excellent',
    goodClass: 'strength_indicator_good',
    mediumClass: 'strength_indicator_medium',
    badClass: 'strength_indicator_bad',

    excellentText: 'Excellent',
    goodText: 'Good',
    mediumText: 'Medium',
    badText: 'Bad'
  };
})(jQuery);

(function($){
  $.fn.validemail = function()
  {
    return this.each(function(){
      var timer;
      
      var $this = $(this);

      var checkEmail = function(email){return /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/.test(email) ? true : false;}

      var _waitForCheck = function(){clearTimeout(timer); timer = setTimeout(_doCheck, 1000);}

      var _doCheck = function()
      {
        clearTimeout(timer);
        
        var email = $this.val();

        if (email)
        {
          var isValid = checkEmail(email);
          if (isValid) $this.css({color:'#34373B'});
          else $this.css({color:'#CC0000'});
        }
      }

      $this.bind('keyup', _waitForCheck).bind('blur', _doCheck);
    });
  }
})(jQuery);

(function($){
  $.fn.promocode = function(options)
  {
    var opts = $.extend({}, $.fn.promocode.defaults, options);
    
    return this.each(function(){
      var $this = $(this);
      
      var updatePromoCodeDescription = function (code, country)
      {
        clearTimeout(opts.timer);
        
        opts.timer = setTimeout(function(){
          $.get(opts.url, {promo_code:code, country:country}, function(data)
          {
            if (data && !$('.promo_description', $this.parent()).length) $this.after('<span class="promo_description"></span>');
            $('.promo_description', $this.parent()).html(data);
          });
        }, 500);
      };
      
      $this.change(function(){
        $this.val($this.val().toUpperCase());
        updatePromoCodeDescription($this.val(), opts.countryField.val());
      });
      
      opts.countryField.change(function(){
        if ($this.val()) updatePromoCodeDescription($this.val(), opts.countryField.val());
      });
      
      updatePromoCodeDescription($this.val(), opts.countryField.val());
    });
  }
    
  $.fn.promocode.defaults = {
    url: null,
    timer: null,
    countryField: null
  };
})(jQuery);