var $j = jQuery.noConflict();


var linkGallery = {
  lgPreview: function (el) {
    // removes all hover classes and adds to the current
    $j('.gallery-link').removeClass('hover');
    $(el).addClassName('hover');
  },
  lgDisplay: function (el) {
    // displays the new screenshot attached to the id of the event
    if ($j(el).hasClass('selected')) {
      return false;
    }
    $j('#feature-gallery .screenshot').fadeOut('');
    var target = el.id.replace('-target', '');
    $j("#" + target).fadeIn('');
    $j('.gallery-link').removeClass('selected');
    $j(el).addClass('selected');
  },
  lgDefaultize: function () {
    // drops all hover elements and returns to origional
    $j('.gallery-link').removeClass('hover');
    $j('.gallery-link.selected').addClass('hover');
  },
  init: function () {
    $j('.gallery-link').click(function () {
      linkGallery.lgDisplay(this);
      return false;
    });
    $j('.gallery-link').hover(

    function () {
      linkGallery.lgPreview(this);
      return false;
    }, function () {
      linkGallery.lgDefaultize(this);
      return false;
    });
  }
};

var hcUtils = {
  // asynchronously loads scripts into the head
  // This works well as is... but could be more elaborate
  asyncLoad: function (script) {
    head = document.getElementsByTagName("head")[0] || document.documentElement;
    $j(script).insertBefore(head.firstChild);
  },
  // fancybox is a lighbox tool.
  // this loads the files asnychronously.
  // needs:   add the classname 'include-fancybox'
  // wrapped around the images you want to use
  // and link the images to the correct large image
  fancyboxInit: function () {
    if ($j(".include-fancybox")) {
      hcUtils.asyncLoad('<script src="/javascripts/jquery.fancybox-1.3.1.pack.js" type="text/javascript"></script>');
      hcUtils.asyncLoad('<link href="/stylesheets/fancybox.css" media="screen" rel="stylesheet" type="text/css" />');
      $j(".include-fancybox a:has(img)").attr('rel', 'gallery').fancybox({
        'transitionIn': 'elastic',
        'transitionOut': 'elastic',
        'speedIn': 300,
        'speedOut': 200,
        'overlayShow': false,
        'titlePosition': 'over',
        'titleFormat': function (title, currentArray, currentIndex, currentOpts) {
          return '<span id="fancybox-title-over">Image ' + (currentIndex + 1) + ' / ' + currentArray.length + ' ' + title + '</span>';
        }
      });
      // function call for the embedded video
      $j(".video-object-link").fancybox({
        'transitionIn': 'elastic',
        'transitionOut': 'elastic',
        'speedIn': 300,
        'speedOut': 200,
        'overlayShow': false,
        'titleShow': false,
        'centerOnScroll': true,
        'scrolling': 'no'
      });
      // adding the small zoom icons to the gallery images
      var zoomImg = "<img src='http://img.howcast.com/images/info/mobile/zoom-icon.png' class='zoom' />";
      $j(zoomImg).insertBefore(".include-fancybox a[rel=gallery] img");
    }
  },
  // used on the mobile site for tab panel
  // click on a link in the tab and a new pane shows up
  easyTabs: function () {
    //if this is not the first tab, hide it
    $j(".tab-targets .tab:not(:first)").hide();
    //to fix u know who
    $j(".tab-targets .tab:first").show();
    $j(".jq-tabs li:first").addClass("selected");
    //when we click one of the tabs
    $j(".jq-tabs li a").click(function () {
      $j(".jq-tabs li").removeClass("selected");
      //get the ID of the element we need to show
      stringref = $j(this).attr("href").split('#')[1];
      $j(this).parent('li').addClass("selected");
      //hide the tabs that doesn't match the ID
      $j('.tab-targets .tab:not(#' + stringref + ')').hide();
      //fix
      if (jQuery.browser.msie && jQuery.browser.version.substr(0, 3) === "6.0") {
        $j('.tab-targets .tab#' + stringref).show();
      } else {
        //display our tab fading it in
        $j('.tab-targets .tab#' + stringref).fadeIn();
        //stay with me
        return false;
      }
    });
  },
  // moveTab takes each tab (which is positioned relative)
  // 
  moveTab: function () {
    $j('.peekaboo .tab').hover(function () {
      $j(this).stop().animate({
        top: '0px'
      }, 'fast');
    }, function () {
      $j(this).stop().animate({
        top: '50px'
      }, 'fast');
    });
  },
  // cssScrollTo finds the classname:
  // "jquery-scrollto" and finds the position
  // of it's target (the anchor of the link) and 
  // creates a scroll function instead of the choppy default action
  cssScrollToFunction: function () {
    $j('.jquery-scrollto').click(function () {
      var targetId = hcUtils.getTarget(this);
      var pos = parseInt($j(targetId).offset().top);
      $j('html, body').animate({
        scrollTop: pos
      }, 'slow');
      return false;
    });
  },
  // cssExpandCollapseFunction:  it searches for the classname
  // "jquery-expand-collapse" and attches itself to that link
  // the link should have the text in this manner:
  // <a href="#id-of-element-to-show/hide" class="jquery-expand-collapse"><span>Expand</span><span class="hide">Collapse</span></a>
  // the function will also add the correct expand icon
  cssExpandCollapseFunction: function () {
    // prepare links
    var link = $j('.jquery-expand-collapse');
    link.addClass('expand-icn');
    $j('.jquery-expand-collapse').click(function () {
      var targetId = hcUtils.getTarget(this);
      if ($j(targetId).css("display") === "none") {
        $j(targetId).show('normal');
        $j(this).addClass("collapse-icn").removeClass("expand-icn").html("Collapse");
      } else {
        $j(targetId).hide('fast');
        $j(this).addClass("expand-icn").removeClass("collapse-icn").html("Expand to Read More");
      }
      return false;
    });
  },
  // cssToggleFunction:   it automatically searches the page for
  // a class of "jquery-toggle" and grabs the href and uses it 
  // to toggle view of the target element
  // link_to "share this", "#target-id", :class => "target-toggle"
  cssToggleFunction: function () {
    $j('.jquery-toggle').click(function () {
      var targetId = hcUtils.getTarget(this);
      $j(targetId).toggle('normal');
      return false;
    });
  },
  // When AJAX links point at a target div, they should store the target in
  // their href attribute, and the event listener should use this method to
  // extract it.
  getTarget: function (el) {
    return $j(el).attr('href');
  },
  centerOnElement: function (ele, target) {
    // aligns centers on another element's center
    ele = $j(ele);
    target = $j(target);
    target.css({
      "left": "0px"
    });
    ele.offLeft = ele.offset().left + (ele.width() / 2);
    target.offLeft = target.offset().left + (target.width() / 2);
    var diff = (ele.offLeft - target.offLeft);
    target.css({
      "left": diff + "px"
    });
  },
  getPath: function (suffix) {
    var regex = /\/$/;
    var path = location.pathname;
    path = path.match(regex) ? path + suffix : path + "/" + suffix;
    return path;
  },
  trackEvents: function (suffix) {
    // grab the location
    var path = hcUtils.getPath(suffix);
    // test for google analytics first.     
    if (typeof pageTracker !== 'undefined') {
      pageTracker._trackPageview(path);
    }
  },
  headerActions: function () {
    // create dropdowns for category and my acount links
    if ($j('#category-hover-link')) {
      $j('#category-hover-link').hover(

      function () {
        if (this.timer) {
          clearTimeout(this.timer);
        }
        this.timer = setTimeout(function () {
          $j('#category-ddm-target').fadeIn('fast');
          hcUtils.centerOnElement("#category-hover-link > img", "#category-ddm-target > img");
        }, 420);
        hcUtils.trackEvents('category-hover-link');
      }, function () {
        if (this.timer) {
          clearTimeout(this.timer);
        }
        this.timer = setTimeout(function () {
          $j('#category-ddm-target').fadeOut('fast');
        }, 420);
      });
    }
    //  suckerfish style hover animation..   extend this to use a unique class
    $j("#user-ddm-target li").hover(

    function () {
      $j(this).addClass("hover");
    }, function () {
      $j(this).removeClass("hover");
    });
    // automatically focus on the search box.
    if ($j('#srch') && !location.hash) {
      $j('#srch').focus();
    }
  },
  // end headerActions
  init: function () {
    hcUtils.headerActions();
    hcUtils.cssToggleFunction();
    hcUtils.cssScrollToFunction();
    hcUtils.cssExpandCollapseFunction();
    //$j('.peekaboo .tab').hover(function(){hcUtils.moveTab(this,"0px");hcUtils.moveTab(this,"50px");});
    hcUtils.moveTab();
    hcUtils.easyTabs();
    hcUtils.fancyboxInit();
  } // end init
};

var teamTools = {
  // hovering over an item changes the image and pops 
  // up their bio
  //
  init: function () {
    $j(".team-thumbs .member .img").live('mouseover mouseout', function(event){
      if(event.type == 'mouseover') {
        teamTools.changeImage($j(this).find("img:first"), $j(this).find("img:first").next("img"));
        teamTools.popBio($j(this).parent(".member"));
      } else {
        teamTools.changeImage($j(this).find("img:first").next("img"), $j(this).find("img:first"));
        teamTools.popBio($j(this).parent(".member"), "remove");
      }
    });
  },
  // changes the thumbnail from the first
  // visible thumbnail to the second/hidden thubmnail
  //
  changeImage: function (el, target) {
    $j(el).addClass("hide");
    $j(target).removeClass("hide");
  },
  // opens the bio for a team member.
  // grabs the first paragraph and pops it up
  // then positions it according to the thumbnail
  // 
  popBio: function (el, action) {
    var bioBox = $j(el).find("p:first");
    var thumbnail = $j(el).find("img:visible:first");
    var thumbnailOffset = thumbnail.offset();
    var bioBoxLeft = thumbnailOffset.left - ((bioBox.outerWidth() - thumbnail.outerWidth()) / 2);
    var viewport = $j(document).width();
    var arrowClassname = "cirrus-up-arrow";
    var arrowHtml = '<img src="/images/cirrus-up-arrow.png" class="' + arrowClassname + '"/>';
    var bioBoxClassname = 'shoutout-box';
    // does the bioBox position cut off to the left?
    if (bioBoxLeft < 0) {
      bioBoxLeft = 10;
    }
    // does the bioBox position cut off to the right?
    if (bioBoxLeft + bioBox.outerWidth() > viewport) {
      bioBoxLeft = viewport - bioBox.outerWidth() - 10;
    }
    var bioBoxCss = {
      "position": "absolute",
      "left": (bioBoxLeft),
      "top": (thumbnailOffset.top + 122)
    };
    var arrowCss = {
      "position": "absolute",
      "left": (thumbnailOffset.left - bioBoxLeft) + (thumbnail.outerWidth() / 2)
    };
    // is there a bioBox already existing?  remove it
    // else create and display the bioBox
    if ($j("." + bioBoxClassname).length !== 0) {
      $j("." + bioBoxClassname).fadeOut().remove();
    } else {
      // create an "instance" of the bioBox and do magic goodstuffz
      var bioBoxDOM = bioBox.clone();
      bioBoxDOM.css(bioBoxCss).append(arrowHtml).appendTo("body").addClass(bioBoxClassname);
      teamTools.positionArrow(bioBoxDOM, arrowClassname, arrowCss );
      bioBoxDOM.fadeIn("fast");
    }
  },
  positionArrow: function(bioBoxDOM, arrowClassname, position) {
    var arrow = $j(bioBoxDOM).find("." + arrowClassname);
    arrow.css(position);
  }
};

$j(document).ready(function () {
  teamTools.init();
});
$j(document).ready(function () {
  hcUtils.init();
  $j().elCarousel({playTime: 5000});
  $j().simpleCarousel();
});
$j(document).ready(function () {
  linkGallery.init();
});


/*  PLUGINS */
/*
*	simpleCarousel plugin v0.1
*		Dave Gregory
* this is a very simple carousel that 
* has next and previous buttons and will
* move an ordered list back and forth
* next / prev links disable at end / begin of list
*/
(function($) {
  // plugin definition
  $.fn.simpleCarousel = function(options) {
    // default values (which are overridden by options)
    var defaults = {
         carouselContainer: '#carousel-controls',
         controlsContainer: '#icon-controls'
    };
    // override defaults with options.
    // dont use "defaults.varName"
    // instead use "options.varName"
    var options = $.extend(defaults, options);
    var target, controls, clipWidth, targetWidth, itemWidth, direction, targetMovement, itemIndex, itemSelector;
    // Start the Process
    init();
    // creates all needed variables, globals
    // and calls the event listeners
    function init() {
      target = $(options.carouselContainer + " ul");
      controls = $(options.controlsContainer + " a");
      itemSelector = target.find("li");
      itemWidth = itemSelector.filter(":eq(2)").outerWidth(true);
      targetWidth = itemSelector.length * itemWidth;
      target.css("position", "relative");
      itemIndex = 0;
      // start the process
      event();
      checkLinks();
    }
    // creates the event listeners to the controls
    // when clicked, it detects direction and calls the move process
    function event() {
      controls.click(function(){
        if ($(this).hasClass("disabled")) {return false;};
        direction = $(this).hasClass("prev") ? "left" : "right";
        startMoveProcess();
      });
      $("#carousel-controls").bind("elCarousel.move", function(){
        if (controls.filter(".prev").hasClass("disabled")) {return false;};
        direction = "left";
        startMoveProcess();
      });
    }
    // master controller to call methods needed.
    // calculate, do the move, and clean up processing in one
    function startMoveProcess() {
      calculatePos();
      move();
      checkLinks();
    }
    // Does the actual move, and calls the method to 
    // enable the first icon as the selected pane
    function move() {
      target.animate({"left": targetMovement + "px"}, 400, function(){clickSelected();});
    }
    // calculate the position of the icons and where they need be
    function calculatePos() {
      currentPos = parseInt(target.css("left"));
      clipWidth = target.closest("div").width();
      if (direction === "left") {
        itemIndex += 1;
        // this detects if at the end of the list and acts accordingly
        targetMovement = (Math.abs(currentPos) + itemWidth) > (targetWidth - clipWidth) ? currentPos : currentPos - itemWidth;
      // this is for "right" direction
      } else {
        itemIndex -= 1;
        // detects the beginning of the list and acts accordingly
        targetMovement = currentPos == 0 ? currentPos : currentPos + itemWidth;
      }
    }
    function checkLinks() {
      controls.removeClass("disabled");
      if (itemSelector.length == itemIndex + 1) {
        controls.filter(".prev").addClass("disabled");
      };
      if (itemIndex == 0) {
        controls.filter(".next").addClass("disabled");
      }
    }
    function clickSelected() {
      itemSelector.filter(":eq(" + itemIndex + ")").find("a").click();
    }
    return this;  // assume it works for chaining
  };
  // private functions
  function getTarget(el) {
    return $(el).attr('href');
  }
})(jQuery);


/*
*	elCarousel plugin v0.1
*		Dave Gregory
* a carousel that autoplays and allows
* for clicking on each item as they move 
* from pane to pane
*/
(function($) {
  // plugin definition
  $.fn.elCarousel = function(options) {
    // default values (which are overridden by options)
    var defaults = {
         controlEl: '#carousel-controls',
         playTime: 7500
    };
    var options = $.extend(defaults, options);  // allow options
    var autoPlay, direction, controlArray, currentLink, currentTarget, currentHref, selectedTarget, targetWidth, forceDirection;
    // Initializer
    if ($('#featured-videos-carousel').length > 0) {
      setVars();
      updateControls();
      event();
      timer();
    };
    function setVars() {
      autoPlay = true;  // set play to true to begin with
      direction = "right";
      controlArray = $(options.controlEl + " a.video-link");
      currentLink = $(controlArray).get(0);
      $(currentLink).addClass('selected');
      selectedLink = currentLink;
      currentTarget = getTarget(currentLink);
      currentHref = $(currentLink).attr("href");
      selectedTarget = currentTarget;
      lastTarget = $(options.controlEl + " li").filter(":last").find("a").attr("href");
      targetWidth = $(currentTarget).outerWidth(true);
      updateControls();
    }
    // creates the event listeners to the controls
    function event() {
      $(options.controlEl + ' a').click( function(el) {
        // clicking on the current link does nothing
        if ($(this).hasClass("selected")) {return false;}
        // test for the type of link
        if ($(this).is('.video-link')) {
          selectedLink = $(this);
        } else {
          // when prev/next, do special work
          var href = $(this).attr('href');
          selectedLink = $(this).siblings('a[href|=' + href + ']');
          if ($(this).is('#prev-link')) {
            forceDirection = "left";
          } else {
            forceDirection = "right";
          }
        }
        autoPlay = false;
        controlPane(selectedLink);
        return false;
      });
    }
    // starts the autoplay interval and checks for stoppage
    function timer() {
      var repeater = setInterval(function () {autoPlay ? controlPane() : clearInterval(repeater);}, defaults.playTime);
    }
    // the master function that calls all others
    function controlPane(el) {
      // if (click) {selectedLink = click element} else {selectedLink = next element}
      selectedLink = el ? el : nextLink(currentLink);
      selectedTarget = getTarget(selectedLink);
      updateControls();
      // create element and put it locally
      var linkCover = '<div class="link-cover" style="position:absolute;left:0pt;top:0pt;width:100%;height:100%;z-index:999;"></div>';
      $(linkCover).appendTo(options.controlEl);
      fetchPane();
      calcDirection();
      insertPane();
      animate();
      if (lastTarget === selectedTarget) {autoPlay = false; return false;}
    }
    // update the selected link and prev / next
    function updateControls() {
      // create selected
      $(controlArray).removeClass("selected");
      $(selectedLink).addClass("selected");
      // change prev next links
      var selectedIdx = $(controlArray).index(selectedLink);
      var nextIdx = (selectedIdx + 1) % controlArray.length;
      var nextEl = $(controlArray).get(nextIdx);
      var nextHref = $(nextEl).attr('href');
      $('#next-link').attr('href',nextHref);
      var prevIdx = ((selectedIdx - 1) + controlArray.length) % controlArray.length;
      var prevEl = $(controlArray).get(prevIdx);
      var prevHref = $(prevEl).attr('href');
      $('#prev-link').attr('href',prevHref);
    }
    // if (element NOT exist) {go get from ajax};
    function fetchPane() {
      $(selectedTarget).removeClass('hide');
    }
    // find the position of selectedLink and change dir var accordingly
    function calcDirection(container) {
      if (autoPlay == true | forceDirection == "right") { return direction = "right";}
      if (forceDirection == "left") { return direction = "left";}
      var currentIdx = $(controlArray).index(currentLink);
      var selectedIdx = $(controlArray).index(selectedLink);
      direction = (currentIdx > selectedIdx) ? "left" : "right";
    }
    // insert the selectedTarget according to direction and unhide
    function insertPane() {
      if (direction == "right") {
        $(currentTarget).after($(selectedTarget));
      } else {
        $(currentTarget).before($(selectedTarget));
      }
    }
    // animates (slide) according to direction
    function animate() {
      // need current target
      var px = "-" + targetWidth + "px";
      if (direction == "right") {
        $(currentTarget).animate({marginLeft:px}, "slow", function() {cleanUp();});
      } else {
        $(selectedTarget).css("margin-left",px).animate({marginLeft:0}, "slow", function() {cleanUp();});
      }
    }
    // clean up all the loose ends, prep for next event
    function cleanUp() {
      $(options.controlEl + ' div.link-cover').remove();
      $(currentTarget).addClass("hide").css("margin-left","0px");
      currentTarget = selectedTarget;
      currentLink = selectedLink;
    }
    // 
    function nextLink(el) {
      // trigger something here
      $(options.controlEl).trigger("elCarousel.move");
      var elIdx = $(controlArray).index(el);
      var nextIdx = (elIdx + 1) % controlArray.length;
      return $(controlArray).get(nextIdx);
    }
    return this;  // is this needed for chaining?
  };
  // private functions
  function getTarget(el) {
    return $(el).attr('href');
  }
  function prevLink(el) {
    // is this at the begin of the jquery array?
    return $(el).prev('a.video-link');
  }
})(jQuery);

