
// Simple JavaScript Templating
// John Resig - http://ejohn.org/ - MIT Licensed
(function(){
    var cache = {};

    this.tmpl = function tmpl(str, data){
        // Figure out if we're getting a template, or if we need to
        // load the template - and be sure to cache the result.
        var fn = !/\W/.test(str) ?
            cache[str] = cache[str] ||
            tmpl(document.getElementById(str).innerHTML) :

        // Generate a reusable function that will serve as a template
        // generator (and which will be cached).
        new Function("obj",
                     "var p=[],print=function(){p.push.apply(p,arguments);};" +

                     // Introduce the data as local variables using with(){}
                     "with(obj){p.push('" +

                     // Convert the template into pure JavaScript
                     str
                     .replace(/[\r\t\n]/g, " ")
                     .split("<#").join("\t")
                     .replace(/((^|%>)[^\t]*)"/g, "$1\r")
          .replace(/\t=(.*?)#>/g, "',$1,'")
          .split("\t").join("');")
          .split("#>").join("p.push('")
          .split("\r").join("\\'")
      + "');}return p.join('');");

    // Provide some basic currying to the user
    return data ? fn( data ) : fn;
  };
})();


(function($) {
	var site = window.site = {
		data : {
			// js data
		},
		func : {
			// commonly used site specfic functions
		},
		obj : {
			// site specfic objects
			ShareThis: {
                open: function(){
                    var $elem = $("#main-bd-inner > div.grid > div.gu-last"),
                        pos = $elem.offset();
                    $("#ShareThis-iframe, #ShareThis")
                        .appendTo($("body"))
                        .css({
                            "left": pos.left + 10,
                            "top": pos.top
                        }).show();
                    $("#ShareThis")
                        .kbNavigationBlock();
                },
                close: function(){
                    var $ShareThis = $("#ShareThis, #ShareThis-iframe");
                    $ShareThis.stop().fadeOut(200, function(){
                        $ShareThis.find("input, textarea").val("");
                        $('#EmailFriendForm .error').hide().html('');
                        $('#EmailFriendConfirmation').hide();
                        $('#EmailFriendForm').show();
                    });
                },
                submit: function(){

                }
            }
		}
	};
})($);

// on body load
$(function() {
    // init

    /* External links open in new windows */
    $("a[rel='external']").bind("click.external", function(){
        window.open(this.href);
        return false;
    });

    // Not all browsers apply focus to the target of a hash url
    // so we work around this problem for the skip-to link.
    if (jQuery.browser && (jQuery.browser.webkit || jQuery.browser.opera)) {
        $('#skip-link a').click(function () {
            var selector = "a, area, object, :input:enabled";
            $('#skip-to-main-content')
            .nextAll()
            .each(function (i, el) {
                el = $(el)
                .filter(selector)
                .add($(selector, el))
                .filter(':visible')
                .eq(0);
                if (el.length > 0) {
                    el.focus();
                    return false;
                }
            });
        });
    }

    /* Handle hover states for buttons and images */
   $("input.js-hasHover, img.js-hasHover").each(function(){
       var $this = $(this);
       $this.bind("mouseenter mouseleave focusin focusout", function(e){
           $this.toggleClass("hover")
                .attr("src", $this.attr("src").replace(/_(off|on)\./, (e.type == "mouseenter" || e.type === "focusin" ? "_on." : "_off.")));
       });
   });

    /* Share this buttons */
   $("input.js-share-product").click(function(){
       site.obj.ShareThis.open();
       return false;
   });
   $("#ShareThis a.js-close").click(function(){
       site.obj.ShareThis.close();
       return false;
   });

	/* generic show/hide toggler */
	$("a.js-toggler").live("click", function(){
	    var $this = $(this),
              $subject = $($this.attr("href").match(/(#\w+)$/)[0]); // expects the href to be an id
        $this.toggleClass("selected");
        $subject.toggleClass("toggle-on");
        return false;
    } );

    /* Show quicklook overlay */
    $(".quick-look").click(function() {
    quickViewCommands[0]=$(this).children("#quick-lookUrl").text();
        if( $("#widget-quickview").size() == 0 )
        { loadQuickView('show','body', this); }
    });

    /* Product grid overlay */
    $("div.products > div.grid").find("div.product").each(function(){
        var $this = $(this);
        var $meta = $this.find("div.meta");
        var $overlay = $this.find("div.overlay");
        var $quicklook = $this.find("a.quick-look");
        var tspeed = 0;


        $this.bind('mouseenter mouseleave', function(e) {  // hover events
          if (!(jQuery.browser.msie && jQuery.browser.version.match(/^[8]\./))) {
            $overlay.stop().fadeTo(tspeed, ((e.type === 'mouseenter') ? 1 : 0.001));
          } else {
            // ie8 has a known issue regarding opacity on elements with absolute positioning.
            // We degrade ui to avoid this issue.
            $overlay.show().css({
              'margin-left': ((e.type === 'mouseleave') ? '-100%' : 0)
            });
          }
          $meta.stop().fadeTo(tspeed, (e.type === 'mouseenter') ? 0 : 1);
        })
        .kbhover() // trigger mouse event for analogous keyboard events
        .trigger("mouseleave")  // initial fx state should be hoverout
        ;
        tspeed = "medium";

        if($this.parent().parent().is(".showDetails")) {
          return;
        };

        $("div.outfits").css("position", "relative");
    });

    /* Primary Navigation hide/show behavior */
    $("#nav-site > ul.list-l1")
        .data("delay", 500)
        .data("opened", null)
        .children("li").each(function(){
            var $this = $(this),
                getSelected = function(){ return $this.parent().children("li.selected").find("div.wrapper-l2"); },
                $l2 = $this.find("div.wrapper-l2"),
                $secondary = $l2.find(".list-l2 > li"),
                $parent = $this.parent(),
                $siblings = $this.siblings(),
                $all = $siblings.andSelf(),
                rate = 400;

            if($this.is(":not(.selected)")){
                $l2.css({ "opacity": 0 });    // We're directly animating opacity because there's wonkyness with jQuery's fadeIn/Out
                                   }

                     $this.click(function(e){
                         clearTimeout($this.data("timer"));
                         show();
                         $this.siblings().removeClass("active-off").removeClass("selected").removeClass("hover").end().addClass("selected");
                         if ($(e.target).is(":not(.label-l2)")) { return false; }
                     });

                     var show = function(){
                         $all.each(function(){
                             clearTimeout($(this).data("timer"));
                         });
                         $this.addClass("hover");
                         $parent.data("opened", $this);
                         if ($this.is(":not(.selected)")) {
                             var $selected = getSelected();
                             // fading-in element should be at max z-index for usability's sake
                             $l2.css({ "z-index": 10, "display": "block" }).stop().animate( { "opacity": 1 }, rate, function(){ if ($.browser.msie) { this.style.removeAttribute("filter"); } });
                             $selected.parent().addClass("active-off");
                             $selected.css("z-index", 1).stop().animate({ "opacity": 0 }, rate, function(){ $selected.css("display", "none") });
                         }
                     }
                     var hide = function(){
                         $this.removeClass("hover");
                         if ($this.is(":not(.selected)")) {
                             var $selected = getSelected();
                             // hide when done, to avoid triggering mouse events
                             $l2.css("z-index", 1).stop().animate({"opacity": 0}, rate,  function(){ $l2.css("display", "none") } );
                             if($parent.data("opened") == $this){
                                 $selected.parent().removeClass("active-off");
                                 $selected.css({"z-index": 10, "display": "block" }).stop().animate({"opacity": 1}, rate);
                                 $parent.data("opened", null);
                             }
                         }
                     }


                     $this
                     .data("timer", null)
                     .hover(
                         function(){ // over
                             clearTimeout($this.data("timer"));
                             $this.data("timer", setTimeout(show, $parent.data("delay")));
                         },
                         function(){ // out
                             clearTimeout($this.data("timer"));
                             $this.data("timer", setTimeout(hide, $parent.data("delay")));

                         }
                     );
        
                     $this.kbhover(); // trigger mouse event for analogous keyboard events

                     $secondary.each(function(){
                         var $this = $(this);
                         $this.hover(
                             function(){ $this.addClass("hover"); },
                             function(){ $this.removeClass("hover"); }
                         );
                         $this.kbhover(); // trigger mouse event for analogous keyboard events
                       });
                    });
    /* End Primary Nav code */
    /* updated for image on of search submit button */
    /* Setup any buttons */
    $(".js-imageButton").each(function() {
		var baseImage = $(this).attr("src").split("_");
		var offPath = baseImage[0]+"_"+baseImage[1] + "_off.gif";
		var onPath =  baseImage[0]+"_"+baseImage[1] + "_on.gif";
		new lib.obj.button({
		    off: offPath,
		    hover: onPath,
		    buttonSelector: this,
		    buttonCollectionSelector : ".js-imageButton"
		});
    });
    /* --------------- */

    /* Setup any Generic Popups */
    $(".js-genericPopup").click(function(evt) {
	var $this = $(this),
            returnFocus = document.activeElement,
            popupWidth = $this.attr("data-width") || 685,
            iframeSRC = $this.attr("href");
        iframeHeight = $this.attr("data-height") || 500;
	lib.layer.create("#genericLayerContent", {
	    closeSelector : ".js-closeLayer",
	    url : "/ann/custserv/popupFrame.jsp",
	    keepCentered : false,
	    callback : function() {
                $("#genericLayerContent").bind("mousedown", function(e){ beginPopupDrag(this, e) });
		$("#genericLayerContent iframe").attr("src", iframeSRC);
                $("#genericLayerContent").animate({"width": popupWidth}, 0);
                $("#genericLayerContent iframe").animate({"height": iframeHeight}, 0);
		lib.layer.center("#genericLayerContent");
                $("#genericLayerContent").kbNavigationBlock(returnFocus);
	    }
	});
	evt.preventDefault();
    });
    /* ------------------- */

    /* Setup any Generic Popups */
    $(".js-profilePopup").click(function(evt) {
	var $this = $(this),
            returnFocus = document.activeElement,
            popupWidth = $this.attr("data-width") || 685,

            iframeSRC = $this.attr("href");
        iframeHeight = $this.attr("data-height") || 450;
	lib.layer.create("#genericLayerContent", {
	    closeSelector : ".js-closeLayer",
	    url : "/ann/custserv/profilePopupFrame.jsp",
	    keepCentered : false,
	    callback : function() {
                $("#genericLayerContent").bind("mousedown", function(e){ beginPopupDrag(this, e) });
		$("#genericLayerContent iframe").attr("src", iframeSRC);
                $("#genericLayerContent").animate({"width": popupWidth}, 0);
                $("#genericLayerContent iframe").animate({"height": iframeHeight}, 0);
		lib.layer.center("#genericLayerContent");
                $("#genericLayerContent").kbNavigationBlock(returnFocus);
	    }
	});
	evt.preventDefault();
    });
    /* ------------------- */

    /* Setup any Small Generic Popups  */
    $(".js-genericPopupSmall").click(function(evt) {
	var $this = $(this),
            returnFocus = document.activeElement,
            popupWidth = $this.attr("data-width") || 430,
            iframeSRC = $this.attr("href");
        iframeHeight = $this.attr("data-height") || 480;
	lib.layer.create("#genericLayerContent", {
	    closeSelector : ".js-closeLayer",
	    url : "/custserv/generic_layer.html",
	    keepCentered : false,
	    callback : function() {
                $("#genericLayerContent").bind("mousedown", function(e){ beginPopupDrag(this, e) });
		$("#genericLayerContent iframe").attr("src", iframeSRC);
                $("#genericLayerContent").animate({"width": popupWidth}, 0);
                $("#genericLayerContent iframe").animate({"height": iframeHeight}, 0);
		lib.layer.center("#genericLayerContent");
                $("#genericLayerContent").kbNavigationBlock(returnFocus);
	    }
	});
	evt.preventDefault();
    });
    /* ------------------- */

    /* set up default text for search box, newsletter field, additional delivery instructions  */
    lib.input.defaultText("#SiteSearch", {defaultText: "KEYWORD OR ITEM #"}) ;
    lib.input.defaultText("#FooterSignup", {defaultText: "SIGN UP FOR EMAIL UPDATES"}) ;
    lib.input.defaultText("#delivText", {defaultText: ""});
    /* character limit for gift box message, additional delivery instructions */
    lib.input.setMaxCharacters("#gift-msg", {limit: 120, results: "#gift-msg-count"});
    lib.input.setMaxCharacters("#delivText", {limit: 30, results: "#add-instr-count"});

    /* Radio buttons on refinements trigger click behavior */
    $("#Filter .radioGroup").each( function(){
        var $this = $(this),
            $radio = $this.find("input"),
            href = $this.find("a").attr("href");
        $radio.bind("focus", function(){
            window.location.href = href;
        });
    });

    /* Addresses IE clickthrough issue on product grid */
    if($.browser.msie){
        $(".product .thumb img").click(function(){ window.location = $(this).parent().parent().find("a.clickthrough").attr("href") })
    }

    
    setTimeout(function () {
      $('body').fixMissingHref();
    }, 50);
    $('body').ajaxSuccess(function (e, xhr, settings) {
      setTimeout(function () {
        $('body').fixMissingHref();
      }, 50);
    });
});

(function ($) {
  "use strict";

  // the kbhover() jQuery plugin triggers the analogous hover effect on the jQuery element
  // when a focus event occurs on it or one of it's children. This provides the same user user 
  // experience for keyboard navigation as for mouse navigation.
  $.fn.kbhover = function () {
    var selector = "a, area, object, :input:enabled";
    return this.each(function (i, el) {
      $(selector, el).add($(el).is(selector) ? el : null).bind("focusin focusout", function (event) {
        $(el).trigger(event.type === "focusin" ? "mouseenter" : "mouseleave");
      });
    });
  };

  // Add default (NOP) href attribute on any anchor missing an href
  $.fn.fixMissingHref = function () {
    $("a", this).each(function () {
      $(this).attr('href', function (i, o) { return (o ? o : 'javascript:void(0);'); });
    });
    return this;
  };

  // Create a keyboard navigation cycle by placing navigation sentinal
  // links before and after the innerhtml of each jQuery element. When a 
  // sentinal gains focus, an event handler will pass focus to the opposite
  // sentinal, keeping focus between the sentinal pairs.  Note that the last 
  // tab direction determines how the keyboard user passes through a sentinal.
  // 
  // Note that this effectively creates a keyboard trap unless the caller
  // provides an exit link.  If the exit link uses the site default css class,
  // then the keyboard focus will be returned to returnFocus element in
  // click. returnFocus defaults to the active element.
  //
  // Focus is initially sent to the first sentinal in the first jQuery object.
  (function () {
    var forwardTab = true,
        mousedown = function (e) {
          forwardTab = true;
        },
        keypress = function (e) {
          if (e.which === 9 || e.keyCode === 9) {
            forwardTab = (e.shiftKey) ? false : true;
          }
        },
        html = '<div class="focus-link-container"><a href="javascript:void(0);"></a></div>'
        ;
  
    $.fn.kbNavigationBlock = function (returnFocus) {
      returnFocus = returnFocus || document.activeElement;
      $(this).each(function () {
        var that = this;
        $(this)
        .prepend($(html).find('a').addClass('focus-link-first').end())
        .append($(html).find('a').addClass('focus-link-last').end())
        .unbind('mousedown', mousedown)
        .unbind('keydown', keypress)
        .bind('mousedown', mousedown)
        .bind('keydown', keypress)
        .find(".focus-link-first", this)
        .focus(function () {
          if (forwardTab === false) {
            $(".focus-link-last", that).focus();
          }
        })
        .end()
        .find(".focus-link-last", this)
        .focus(function () {
          if (forwardTab === true) {
            $(".focus-link-first", that).focus();
          }
        })
        .end()
        .find(".js-close, .closeLink, .js-closeLayer")
        .click(function () {
          $(that).unbind('mousedown', mousedown);
          $(that).unbind('keydown', keypress);
          $(returnFocus).focus();
        })
        .end()
        ;
      })
      .find(".focus-link-first:first")
      .focus();
      return this;
    };

    // add support for activeElement on older browsers
    if (typeof document.activeElement === 'undefined') {
        try {
            document.activeElement = null;
            document.addEventListener("focus", function () {
                try {
                    document.activeElement = e.target === document ? null : e.target;
                } catch(e1) {
                    throw(e1);
                }
            }, true);
        } catch(e2) {
        }
    } 

  }());
}(jQuery));

