/* Extend jQuery for additional event listeners */
$.extend($.fn, {
   observe: function($observed, event, callback){
      var $this = $(this);
      $observed.bind(event, function(e){ callback.apply($this, [e]); });
      return $this;
   }
});
$.extend($, {
   delegate: function(rules) {
      return function(e) {
         var $target = $(e.target);
         for (var selector in rules)
            if ($target.is(selector)) { return rules[selector].apply(this, $.makeArray(arguments)); }
      };
   }
});


/* Extend jQuery easing functions */
jQuery.extend( jQuery.easing, {
	easeInExpo: function (x, t, b, c, d) {
		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
	},
	easeOutExpo: function (x, t, b, c, d) {
		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
	},
	easeInOutExpo: function (x, t, b, c, d) {
		if (t==0) return b;
		if (t==d) return b+c;
		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
	}
});

/* END jQuery extensions */



MERCHANTS = {};

MERCHANTS.init = function(){
   MERCHANTS.TopNav.init();
   MERCHANTS.RelatedContent.init();
   $(function(){ MERCHANTS.SendTAC.init(); });

   // If there's a multipart form, initialize the functionality
   $(function(){ 
      var $form = $(MERCHANTS.Form.MultiPart._formSelector);
      if ($form.length) { MERCHANTS.Form.MultiPart.init($form); }
   });
   
   // Decorate all links in "Popular Downloads" module with download icon
   $(function(){
      var $downloads = $("div.header-aside > h4:contains('Popular Downloads')").parent().parent();
      if ($downloads.length) { $downloads.find("div.nav-aside > ul.nl > li > a").addClass("download") }
   });

   // Lightbox opener
   $(function(){
      $("a[rel='lightbox']").click(function(e){
         $(this).blur();
         e.preventDefault(); 
         e.stopPropagation();
         MERCHANTS.Lightbox.open();
      });
   });
   
   $(function(){
      $("a[rel='lightbox1']").click(function(e){
         $(this).blur();
         e.preventDefault(); 
         e.stopPropagation();
         MERCHANTS.Lightbox1.open();
      });
   });1

   /*
   // Top Nav png fix
   $(function(){
      if ($.browser.msie && $.browser.version < 7){
         $("div.nav-top > ul.nl > li.nav-item").each(function(){
           var $a = $(this).find("div.nav-label > a"),
               off_image = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='%1',sizingMethod='crop')".replace("%1", $a.css("background-image").replace(/url\(([\S]+)\)/, "$1")),
               on_image = off_image.replace(".png", "_ro.png");
            $a.css("background-image", "none").css("filter", off_image)
            $a.hover(
               function(){ $(this).css("filter", on_image) },
               function(){ $(this).css("filter", off_image) }
            );
           
         })
      }
   });
   */
};

MERCHANTS.TopNav = {
   X_BOUNDARY: 0,
   
   init: function(){ $(function(){
      var $ul = $("div.nav-top > ul.nl"),
          $li = $ul.children("li.nav-item:not(:eq(0))");
      if ($ul.length) {
	  	MERCHANTS.TopNav.X_BOUNDARY = $ul.offset().left + $ul.width();
	  	
	  	$li.each(function(){
	  		var $this = $(this), $flyout = $(this).find("div.nav-flyout");
	  		
	  		// set align r/l if run up against page boundaries
					if ($flyout.length && ($this.offset().left + $flyout.width() > MERCHANTS.TopNav.X_BOUNDARY)) {
						$flyout.css("right", 0);
					}
					else {
						$flyout.css("left", 0);
					}
					$this.hover(function(){
						$this.addClass("hover");
					}, function(){
						$this.removeClass("hover");
					});
				});
			}
   }); }
   
};


MERCHANTS.RelatedContent = {
   init: function(){ $(function(){
      var $opened = false;
      $("div.related div.nav-related > ul.nl > li.nav-item").each(function(){
         var $this = $(this),
             $handle = $this.find("div.item-inner > a"),
             $content = $this.find("div.item-content");
             
         $handle.click(function(e){
            $(this).blur();
            e.preventDefault(); 
            e.stopPropagation();
            
            if ($opened) {
               $opened.slideUp("fast");
               if($opened == $content) {
                  //$content.slideUp("fast");
                  $opened = false;
                  return;
               }
            }
            
            $content.slideDown("fast");
            $opened = $content;
         });
      });
      
      $("div.related div.nav-related > ul.nl > li.nav-item:eq(0) > div.item-inner > a").click();
   }); }
};


MERCHANTS.Lightbox = {
   $overlay : $("<div class='overlay'></div>"),
   $content: $("<div class='empty'></div>"),
   elements : [],
   duration: 400,
   opacity: .8,
   color: "#000",
   INITIALIZED: false,
   OPENED: false,
   
   init: function(params){
      if (MERCHANTS.Lightbox.INITIALIZED) return MERCHANTS.Lightbox;
      
      $.extend(MERCHANTS.Lightbox, params);
      
      MERCHANTS.Lightbox.elements = [MERCHANTS.Lightbox.$content, MERCHANTS.Lightbox.$overlay];
      
      MERCHANTS.Lightbox.$overlay.hide()
                        .css({ "background-color": MERCHANTS.Lightbox.color, "opacity": MERCHANTS.Lightbox.opacity });
      
      MERCHANTS.Lightbox.$overlay.bind("click.overlay", MERCHANTS.Lightbox.close);
      $("body").append(MERCHANTS.Lightbox.$overlay);
      
      MERCHANTS.Lightbox.INITIALIZED = true;
      return MERCHANTS.Lightbox;
   },

   open: function(){
      MERCHANTS.Lightbox.recenter();
      if($.browser.msie) { $("select").css("visibility", "hidden"); }
      $.each(MERCHANTS.Lightbox.elements, function(){
         $(this).stop().fadeIn({
            duration: MERCHANTS.Lightbox.duration,
            easing: "easeInExpo"
         });
         MERCHANTS.Lightbox.OPENED = true;
      });
      return MERCHANTS.Lightbox;
   },
   
   close: function(){
      if($.browser.msie) { $("select").css("visibility", "visible"); }
      $.each(MERCHANTS.Lightbox.elements, function(){
         $(this).stop().fadeOut({
            duration: MERCHANTS.Lightbox.duration,
            easing: "easeOutExpo"
         });
         MERCHANTS.Lightbox.OPENED = false;
      });
      return MERCHANTS.Lightbox;
   },
   
   recenter: function(){
      var scrollbars = ($.browser.msie && (jQuery.browser.version < 7)) ? 21 : 0,	// this is to compensate for IE's scrollbars
	      docHeight = document.documentElement.clientHeight,
	      docWidth = document.documentElement.clientWidth,
          proposedY = (docHeight/2) - (MERCHANTS.Lightbox.$content.height() /2) + document.documentElement.scrollTop,
          proposedX = (docWidth/2) - (MERCHANTS.Lightbox.$content.width() /2);
      
      MERCHANTS.Lightbox.$content.css({
         "top": proposedY < 0 ? 0 : proposedY,
         "left": proposedX < 0 ? 0 : proposedX
      });
      
      MERCHANTS.Lightbox.$overlay.height($(document).height())
                                 .width($(document).width() - scrollbars);
         
      return MERCHANTS.Lightbox;
   }
};


MERCHANTS.Lightbox1 = {
   $overlay : $("<div class='overlay'></div>"),
   $content: $("<div class='empty'></div>"),
   elements : [],
   duration: 400,
   opacity: .8,
   color: "#000",
   INITIALIZED: false,
   OPENED: false,
   
   init: function(params){
      if (MERCHANTS.Lightbox1.INITIALIZED) return MERCHANTS.Lightbox1;
      
      $.extend(MERCHANTS.Lightbox1, params);
      
      MERCHANTS.Lightbox1.elements = [MERCHANTS.Lightbox1.$content, MERCHANTS.Lightbox1.$overlay];
      
      MERCHANTS.Lightbox1.$overlay.hide()
                        .css({ "background-color": MERCHANTS.Lightbox1.color, "opacity": MERCHANTS.Lightbox1.opacity });
      
      MERCHANTS.Lightbox1.$overlay.bind("click.overlay", MERCHANTS.Lightbox1.close);
      $("body").append(MERCHANTS.Lightbox1.$overlay);
      
      MERCHANTS.Lightbox1.INITIALIZED = true;
      return MERCHANTS.Lightbox1;
   },

   open: function(){
      MERCHANTS.Lightbox1.recenter();
      if($.browser.msie) { $("select").css("visibility", "hidden"); }
      $.each(MERCHANTS.Lightbox1.elements, function(){
         $(this).stop().fadeIn({
            duration: MERCHANTS.Lightbox1.duration,
            easing: "easeInExpo"
         });
         MERCHANTS.Lightbox1.OPENED = true;
      });
      return MERCHANTS.Lightbox1;
   },
   
   close: function(){
      if($.browser.msie) { $("select").css("visibility", "visible"); }
      $.each(MERCHANTS.Lightbox1.elements, function(){
         $(this).stop().fadeOut({
            duration: MERCHANTS.Lightbox1.duration,
            easing: "easeOutExpo"
         });
         MERCHANTS.Lightbox1.OPENED = false;
      });
      return MERCHANTS.Lightbox1;
   },
   
   recenter: function(){
      var scrollbars = ($.browser.msie && (jQuery.browser.version < 7)) ? 21 : 0,	// this is to compensate for IE's scrollbars
	      docHeight = document.documentElement.clientHeight,
	      docWidth = document.documentElement.clientWidth,
          proposedY = (docHeight/2) - (MERCHANTS.Lightbox1.$content.height() /2) + document.documentElement.scrollTop,
          proposedX = (docWidth/2) - (MERCHANTS.Lightbox1.$content.width() /2);
      
      MERCHANTS.Lightbox1.$content.css({
         "top": proposedY < 0 ? 0 : proposedY,
         "left": proposedX < 0 ? 0 : proposedX
      });
      
      MERCHANTS.Lightbox1.$overlay.height($(document).height())
                                 .width($(document).width() - scrollbars);
         
      return MERCHANTS.Lightbox1;
   }
};



MERCHANTS.Form = {};

MERCHANTS.Form.MultiPart = {
   _formSelector: "form.multipart",
   _navSelector: "div.nav-page_step",
   $form: null,
   $nav: null,
   $steps: {},
   currentStep: -1,
   totalSteps: 0,
   INITIALIZED: false,
   
   init: function($form) {
      if (MERCHANTS.Form.MultiPart.INITIALIZED) return MERCHANTS.Form.MultiPart;
      
      MERCHANTS.Form.MultiPart.$steps = $form.children("div.section");
      MERCHANTS.Form.MultiPart.totalSteps = MERCHANTS.Form.MultiPart.$steps.length;
      
      MERCHANTS.Form.MultiPart.$form = $form;
      
      MERCHANTS.Form.MultiPart.$form.bind("prev.form_multipart", function(){ MERCHANTS.Form.MultiPart.step("prev"); })
           .bind("next.form_multipart", function(){ MERCHANTS.Form.MultiPart.step("next"); })
           .trigger("next.form_multipart")
           .bind("finalize.form_multipart", function(){ 
               var count = MERCHANTS.Form.MultiPart.currentStep,
                   $current = MERCHANTS.Form.MultiPart.$steps.eq(count);
              if (MERCHANTS.Form.validate.isValid($current)) { $form.submit(); } 
           });
      
      var $nav = $(MERCHANTS.Form.MultiPart._navSelector);
      
      if($nav.length) {
         MERCHANTS.Form.Nav.init($nav);
         MERCHANTS.Form.MultiPart.$nav = $nav;
      }
      
      MERCHANTS.Form.MultiPart.INITIALIZED = true;
      return MERCHANTS.Form.MultiPart;
   },
   step: function(direction) {
      var count = MERCHANTS.Form.MultiPart.currentStep,
          incremented = false,
          $current = MERCHANTS.Form.MultiPart.$steps.eq(count);

      if (direction == "next") {
         if ($current.length && !MERCHANTS.Form.validate.isValid($current)) { window.location = "#"; return; }
         else if (count < MERCHANTS.Form.MultiPart.totalSteps -1) {
            $current.hide().next().show();
            MERCHANTS.Form.MultiPart.currentStep++;
            incremented = true;
         }
      };
      if (direction == "prev") {
         if (count > 0) {
            $current.hide().prev().show();
            MERCHANTS.Form.MultiPart.currentStep--;
            incremented = true;
         }
      };
      
      if (incremented) {
         MERCHANTS.Form.MultiPart.$form.trigger("incremented.form_multipart");
         window.location = "#";
      }
   }
   
};

MERCHANTS.Form.Nav = {
   $nav: null,
   $prev: null,
   $next: null,
   $final: null,
   init: function($nav){
      MERCHANTS.Form.Nav.$prev = $nav.find("ul.nl > li.step-prev");
	   MERCHANTS.Form.Nav.$next = $nav.find("ul.nl > li.step-next");
      MERCHANTS.Form.Nav.$finish = $nav.find("ul.nl > li.step-finish");
      
      MERCHANTS.Form.Nav.checkStatus();
      $nav.observe(MERCHANTS.Form.MultiPart.$form, "incremented.form_multipart", MERCHANTS.Form.Nav.checkStatus);
      
      MERCHANTS.Form.Nav.$prev.children("a").bind("click.form_nav", function(e){
         e.preventDefault();
         $(this).blur();
         MERCHANTS.Form.MultiPart.$form.trigger("prev.form_multipart");
      });
      MERCHANTS.Form.Nav.$next.children("a").bind("click.form_nav", function(e){
         e.preventDefault();
         $(this).blur();
         MERCHANTS.Form.MultiPart.$form.trigger("next.form_multipart");
      });
      MERCHANTS.Form.Nav.$finish.children("a").bind("click.form_nav", function(e){
         e.preventDefault();
         MERCHANTS.Form.MultiPart.$form.trigger("finalize.form_multipart");
      });
      
   },
   checkStatus: function(){
      var count = MERCHANTS.Form.MultiPart.currentStep;
      
      MERCHANTS.Form.Nav.$prev.show();
      
      if(count == MERCHANTS.Form.MultiPart.totalSteps -1) {
         MERCHANTS.Form.Nav.$next.hide();
         MERCHANTS.Form.Nav.$finish.show();
      }
      else {
         MERCHANTS.Form.Nav.$next.show();
         MERCHANTS.Form.Nav.$finish.hide();
      }
      if(count <= 0) {
         MERCHANTS.Form.Nav.$prev.hide();
      }
   }
   
};

MERCHANTS.Form.validate = {
   _fieldErrorClass: "field-error",
   _noteErrorClass: "note-error",
   isValid: function($section){
      var valid = false,
          v = MERCHANTS.Form.validate,
			 inputsValid = v.validateInputFields($section),
			 selectsValid = v.validateSelectFields($section),
			 oneRequiredsValid = v.validateOneValueRequireds($section);

      valid = (inputsValid && selectsValid && oneRequiredsValid);
      return valid;
   },
   validateInputFields: function($section){
      var $inputs = $section.find("div.field-required > input"),
          valid = true;
      
      if ($inputs.length) {
         $inputs.each(function(){
            var $this = $(this), $field = $this.parent();
            
            $field.removeClass(MERCHANTS.Form.validate._fieldErrorClass);
            
            if (!$this.val()) {
               $field.addClass(MERCHANTS.Form.validate._fieldErrorClass);
               valid = false;
            }
            else { valid = (valid == true) ? true : valid; }
         });
      }
      else { valid = true; }
		return valid;
   },
   validateSelectFields: function($section){
      var $selects = $section.find("div.field-required select"),
      	 valid = true;
      if ($selects.length) {
         $selects.each(function(){
            var $this = $(this), $field = $this.parent();
            
            $field.removeClass(MERCHANTS.Form.validate._fieldErrorClass);
            if (!$this.val() || ($this.val() == $this.children().eq(0).val())) {
               $field.addClass(MERCHANTS.Form.validate._fieldErrorClass);
               valid = false;
            }
            else { valid = (valid == true) ? true : valid; }
         });
      }
		else { valid = true; }
      return valid;
   },
	validateOneValueRequireds: function($section){
		var $oneVals = $section.find("fieldset:has(div.note-required)"),
		    valid = true;
      if ($oneVals.length) {
         $oneVals.each(function(){
            var $this = $(this), 
                $requiredNote = $this.find("div.note-required"),
                checksValid = $this.find(":checkbox").length ? MERCHANTS.Form.validate.validateOneCheckboxRequired($this) : true,
                radiosValid = $this.find(":radio").length ? MERCHANTS.Form.validate.validateOneRadioRequired($this) : true,
                selectsValid = $this.find("select").length ? MERCHANTS.Form.validate.validateOneSelectionRequired($this) : true;
            
            $requiredNote.removeClass(MERCHANTS.Form.validate._noteErrorClass);
            
            if (!(checksValid && radiosValid && selectsValid)) {
               $requiredNote.addClass(MERCHANTS.Form.validate._noteErrorClass);
               valid = false;
            }
            else { valid = (valid == true) ? true : valid; }
         });
      }
      else { valid = true; }
		return valid;
	},
	validateOneRadioRequired: function($fieldset){
		var $radios = $fieldset.find(":radio");
		return $radios.length ? $radios.filter(":checked").length : true;
	},
	validateOneCheckboxRequired: function($fieldset){
		var $checkboxes = $fieldset.find(":checkbox");
		return $checkboxes.length ? $checkboxes.filter(":checked").length : true;
	},
	validateOneSelectionRequired: function($fieldset){
      return $fieldset.find("select").filter(function(){
         var $this = $(this);
         if ($this.val() && ($this.val() != $this.children().eq(0).val())) { return $this; }
      }).length;
	}
};

MERCHANTS.SendTAC = {
    init: function(){
        this.$defaultView = $("#SendTAC-default");
        this.$completeView = $("#SendTAC-complete");
        this.$errorView = $("#SendTAC-error");
        this.$form = this.$defaultView.find("form");
        this.$required = this.$form.find("fieldset div.field-required");
        this.$notrequired = this.$form.find("fieldset div.field-block:not(.field-required)");
        this.$emails = this.$form.find("input.input-email");
        this.$errMsg = this.$form.find("div.note-error");
        this.$preview = this.$defaultView.find("div.sendtac-preview > div.preview-message");
        this.$bound = this.$defaultView.find("span[class^='bind.']");
        this.$send = this.$defaultView.find("li.sendtac-send > input");
        this.$cancel = this.$defaultView.find("li.sendtac-cancel > input");
        this.$prevLightboxContent = MERCHANTS.Lightbox.$content;
        
        // not sure what to do with the following
        
            var $trigger = $("div.func-page a.email");
            $trigger.click(function(e){
                e.preventDefault();
                MERCHANTS.SendTAC.open();
            });
        
        // end
        
        // note that callbacks need full namespace
        this.$send.click(function(e){
            e.preventDefault();
            MERCHANTS.SendTAC.send();
        });
        
        // Cancel button closes form
        this.$cancel.click(function(e){
            e.preventDefault();
            MERCHANTS.SendTAC.close();
        });
        
        // Clear form
        this.reset();
        
        // Bind spans in preview to input fields
        this.bindFieldsToPreview();
        return this;
    },
    open: function(){
        MERCHANTS.SendTAC.$completeView.hide();
        MERCHANTS.SendTAC.$defaultView.show();
        MERCHANTS.SendTAC.$prevLightboxContent = MERCHANTS.Lightbox.$content;
        MERCHANTS.Lightbox.$content = $("div.lightbox-sendtac");
        MERCHANTS.Lightbox.elements = [MERCHANTS.Lightbox.$content, MERCHANTS.Lightbox.$overlay];
        MERCHANTS.Lightbox.$overlay.bind("click", MERCHANTS.SendTAC.close);
        MERCHANTS.Lightbox.open();
    },
    close: function(){
        MERCHANTS.SendTAC.reset();
        MERCHANTS.Lightbox.close();
        MERCHANTS.Lightbox.$content = MERCHANTS.SendTAC.$prevLightboxContent;
        MERCHANTS.Lightbox.elements = [MERCHANTS.Lightbox.$content, MERCHANTS.Lightbox.$overlay];
    },
    validate: function(){
        var valid = true,
            $errMsg = this.$errMsg.hide();
            
        $errMsg.hide();
        this.$form.find("fieldset div.field-block").removeClass("has-error");
        
        this.$required.each(function(){
            var $this = $(this),
                $input = $this.find("input"),
                value = $input.val();
            if ($.trim(value) == "") { 
               valid = false;
               $this.addClass("has-error");
               $errMsg.show();
            }
        });
        this.$notrequired.each(function(){
           var $this = $(this),
               $next = $this.next().find("input.input-email"),
               value = $this.find("input").val();
           if ($.trim(value) != "" && 
              ($next.length) &&
              ($.trim($next.val()) == "")) {
                 valid = false;
                 $this.next().addClass("has-error");
                 $errMsg.show();
           }
        });
        this.$emails.each(function(){
           var $this = $(this),
               value = $this.val(),
               name = $this.parent().prev().find("input.input-text").val();
           if ($.trim(value) != "" && !/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/.test(value)) {
              valid = false;
              $this.parent().addClass("has-error");
              $errMsg.show();
           }
           if ($.trim(value) != "" && $.trim(name) == "") {
              valid = false;
              $this.parent().prev().addClass("has-error");
              $errMsg.show();
           }
        });
        return valid;
    },
    reset: function(){
        var valid = true,
            $errMsg = this.$errMsg.hide();
            
        $errMsg.hide();
        this.$required.removeClass("has-error");
        
        this.$form.find("input").each(function(){
            $(this).val("");
        });
        this.resetBoundText()
        return this;
    },
    bindFieldsToPreview: function(){
        this.$bound.each(function(){
            var $textSpan = $(this),
                fieldId = $textSpan.attr("class").match(/\bbind\.(\S+)\b/);
             // if no match, break
            if (fieldId == null) { return false; }
            
            // else
            // capture default values
            $textSpan.data("defaultText", $textSpan.text());
            
            var $theField = $("#" + fieldId[1]);
            
            // spans updates text when fields are changed
            $textSpan.observe($theField, "keyup change", function(e){
                $(this).text($(e.target).val());
            })
            
        });
        return this;
    },
    resetBoundText: function(){
        this.$bound.each(function(){
            var $this = $(this);
            $this.text($this.data("defaultText"));
        });
        return this;
    },
    send: function(){
        if (this.validate()) {
            // what happens here?
            this.sendSuccess();
        }
        return this;
    },
    sendSuccess: function(){
        this.$defaultView.hide();
	  sendMails(document.frm);
        this.$completeView.show();
	  window.scrollTo(0,0);
        
        // Clear form
        this.reset();
        
        // Add additional? yes : no
        this.$completeView.find("li.sendtac-add > input").click(function(e){
            e.preventDefault();
            MERCHANTS.SendTAC.$completeView.hide();
            MERCHANTS.SendTAC.$defaultView.show();
        });
        this.$completeView.find("li.sendtac-noAdd > input").click(function(e){
            e.preventDefault();
            MERCHANTS.SendTAC.close();
        });
        
        return this;
    },
    sendError: function(){
        this.$defaultView.hide();
        this.$errorView.show();
 	  window.scrollTo(0,0);
 	  window.moveTo(0,0);
        return this;
    }
};



MERCHANTS.init();

