function HomeNavigation(node, options) {
  this.data = null;
  this.landingIndex = 0;
  this.startWidth = 338;
  this.openWidth = 611;
  this.closeWidth = 201;
  this.menuLeftStart = 200;
  this.menuLeft = null;
  this.menuTopStart = 154;
  this.menuTop = null;
  this.spacing = 2;
  this.landing = null;
  this.level = 0;
  this.genderImages = false;
  this.easing = "easeOutCirc";
  this.container =
    $("<div/>").appendTo($(node))
      .css({
        width: this.openWidth * 3 + "px",
        height: $(node).outerHeight() + "px"
      });

  this.genderImage = {
	men: ctxPath + "/images/pi/genderButtonMen.png",
    women: ctxPath + "/images/pi/genderButtonWomen.png"
  };

  $.extend(this, options);
}

HomeNavigation.prototype = {
  load: function(url) {
    if (window.location.search) {
      url += "?param=1";
    }
    var $this = this;
    $pi.preLoadAllImages([this.genderImage.men, this.genderImage.women], function() {
      $this.genderImages = true;
    });

    $.getJSON(url, function(data) {
      $this.data = data;
      $this.showNextLandingItem();
    });
  },

  getLandingItem: function(item, callback) {
    var imageIndex = Math.floor(Math.random() * item.images.length);
    var $item = $("<div/>")
      .addClass("landingItem")
      .css({width: this.startWidth + "px"})
      .data("json", item.items);

	var src = item.images[imageIndex];
	if (src.match(/[0-9]+\.[0-9]+/)) {
		src = src.replace(/[0-9]+\.[0-9]+/, "611.410");
	} else {
		var dot = src.lastIndexOf(".");
		src = src.substring(0, dot) + ".611.410" + src.substring(dot);
	}

    $pi.preLoadImage(src, function(image) {
      $item.css({
        "background-image": "url(" + image.src + ")"
      });

      callback($item);
    });

    return $item;
  },

  getNavItem: function(item) {
    var $item = $("<div/>")
      .addClass("navItem")
      .addClass("lvl" + this.level)
      .data("level", this.level)
      .hover(function() {
        var level = $(this).data("level");
        $(".lvl" + level).css({
          opacity: .85
        });
        $(this).css({
          opacity: 1
        });
      }, function() {

      });

    if (item.items) {
      $item.data("json", item.items);
    }
    
    if (item.title == "men" || item.title == "women") {
      var image = new Image();
      image.src = this.genderImage[item.title.toLowerCase()];
      $item.addClass("image")
        .css({
          "background-image": "url(" + image.src + ")",
          width: image.width + "px",
          height: image.height + "px"
        });
    } else {
      if (item.items && item.items.length > 0) {
        $item.text(item.title);
      } else {
        $("<a/>").attr("href", item.url).text(item.title).appendTo($item);
      }
    }

    return $item;
  },

  showNextLandingItem: function() {
    var $this = this;
    if (this.landingIndex >= this.data.length) {
      this.addLandingItemListeners();
      return;
    }
    
    this.getLandingItem($this.data[$this.landingIndex++], function(item) {
      if ($this.landingIndex == 1) {
        item.addClass("first");
      }
      
      item.appendTo($this.container)
        .css({
          left: "1024px",
          opacity: 0
        })
        .animate({
          opacity: 1,
          left: 0
        }, 600, $this.easing, function() {
          $pi.pulseItem(item, {}, function() {
            $this.showNextLandingItem();
          })
        });
    });
  },

  addLandingItemListeners: function() {
    var $this = this;
    $(".landingItem").mouseenter(function() {
      var ti = $(this);
      if (!ti.data("open")) {
        $(".landingItem").stop().not(ti)
          .data("open", false)
		  .animate({
            width: $this.closeWidth + "px"
          }, 600, $this.easing);

        ti.data("open", true)
          .animate({
            width: $this.openWidth + "px"
          }, 600, $this.easing, function() {
			$this.level = 0;
            $this.landing = $(this);
            $this.showMenuItems($(this).data("json"));
          });
		
		$this.clearMenuItems();
      }
    });
	
	setTimeout(function() {
		$(".landingItem:first").mouseenter();
	}, 250);
  },

  clearMenuItems: function() {
    $(".navItem").remove();
    this.menuLeft = null;
  },
  
  showMenuItems: function(items) {
    if (!items) return;
    
    var $this = this;
    var maxWidth = 0;
    this.menuTop = this.menuTopStart;
    if (this.menuLeft == null) {
      this.menuLeft = this.landing.position().left + this.menuLeftStart;
    }

    var height = this.getItemHeight(items, this.level);
    var prevHeight = this.getLevelHeight(this.level - 1);
    var prevPos = $(".lvl" + (this.level - 1)).position() || {left:0, top:0};
    var middle = prevPos.top + prevHeight / 2;

    for (i in items) {
      var $item = this.getNavItem(items[i]);

      if (items[i].items) {
        $item.data("json", items[i].items);
      }

      $item
        .appendTo(this.container)
        .css({
          left: this.menuLeft + "px",
          top: this.menuTop + "px"
        });

      if (!$item.hasClass("image")) {
        $item.css({
          height: height + "px",
          "line-height": height + "px"
        });
      }

      if (items[i].type == "all") {
        $item.addClass("all");
        $item.css({
          height: height * .75 + "px"
        })
        $item.css({
          top: (this.menuTop - $item.outerHeight() - this.spacing) + "px"
        });
      } else {
        this.menuTop += $item.outerHeight() + 2;
      }

      var pos = $item.position();
      if ($item.hasClass("image")) {
        $item.css({
          left: pos.left - 100 + "px",
          opacity: 0
        })
        .delay(i * 100)
        .animate({
          left: pos.left + "px",
          opacity: .85
        }, 300, function() {
          $this.addMouseenter($(this));
        });
      } else {
		if (!$this.simpleAnimate) {
          $item.css({
            top: pos.top - (middle - pos.top) / 2 + "px",
            left: pos.left + 25 + "px"
          });
		}

		$item.css({opacity: .1});

        $item.data("pos", pos);
        // The animations to show the items are delayed untill all positions
        // are set.
      }
      maxWidth = Math.max(maxWidth, $item.outerWidth());
    }

    $(".lvl" + this.level).each(function() {
      var pos = $(this).data("pos");
      if (pos) {

        // moved the animate out of the loop because I was seeing a little
        // lag between the items. This seems to start the animations closer
        // together now
        $(this).animate({
          top: pos.top + "px",
          left: pos.left + "px",
		  opacity: .85
        }, 300, $this.easing, function() {
          $this.addMouseenter($(this));
        });

        $(this).removeData("pos");
      }
    });

    this.menuLeft += maxWidth + this.spacing;
  },

  addMouseenter: function($item) {
    var $this = this;
    $item.mouseenter(function() {
      var level = $(this).data("level");
	  if ($this.level - level == 1) {
		$this.simpleAnimate = true;
	  } else {
		$this.simpleAnimate = false;
      }
      if ($this.level > level) {
        for (i = $this.level; i > level; i--) {
          $(".lvl" + i).remove();
        }
        var pos = $(this).position();
        $this.menuLeft = pos.left + $(this).outerWidth() + 2;
      }

      $this.level = level + 1;
      $this.showMenuItems($(this).data("json"));
    });
  },

  getLevelHeight: function(level) {
    var height = 0;
    var count = 0;
    $(".lvl" + level).each(function() {
      if (!$(this).hasClass("all")) {
        height += $(this).outerHeight();
        count++;
      }
    });

    height += (count - 1) * this.spacing; // the margin between items

    return height;
  },

  getItemHeight: function(items, level) {
    // return (10 <= h <= 20)
    var length = this.hasViewAll(items) ? items.length - 1 : items.length;
    var prevLevelHeight = Math.max(this.getLevelHeight(level - 1),this.getLevelHeight(0));
    var height = (prevLevelHeight - length * 10 - (length - 1) * this.spacing) / length;
    //height = Math.floor(height);
    if (this.level > 1 && height > 23) height = 23;
    if (height < 10) height = 10;
    return height;
  },

  hasViewAll: function(items) {
    for (i in items) {
      if (items[i].type == "all") return true;
    }
    return false;
  }
}
