
(function() {



  /**
   * Provides requestAnimationFrame in a cross browser way.
   * http://paulirish.com/2011/requestanimationframe-for-smart-animating/
   */

  if ( !window.requestAnimationFrame ) {

    window.requestAnimationFrame = ( function() {

      return window.webkitRequestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.oRequestAnimationFrame ||
      window.msRequestAnimationFrame ||
      function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {

        window.setTimeout( callback, 1000 / 60 );

      };

    } )();

  }


  /*  =Utilities
  ----------------------------------------------- */

  // Create a pseudo-console, if a real one doesn't exist
  // (to prevent console statements from halting this script).
  var console = window.console || {};
  if (!console.log)   console.log   = function() {};
  if (!console.dir)   console.dir   = function() {};
  if (!console.error) console.error = function() {};

  // Indicate to the CSS that JavaScript is enabled and what browser is in use.
  var isMSIE = /*@cc_on!@*/false;
  var isFirefox = (navigator && navigator.userAgent && String(navigator.userAgent).toLowerCase().indexOf("firefox") >= 0);
  var version = -1;
  if (isMSIE) version = parseFloat(navigator.appVersion.split("MSIE")[1]) || -1;
  if (isFirefox) version = String(navigator.userAgent).toLowerCase().split("firefox/")[1].charAt(0);

  var html = document.getElementsByTagName("html");
  if (html != null && html.length > 0) {
    html = html[0];

    if (isMSIE) {
      if (version <= 8) {
        html.className = html.className + " lte-ie8";
      }
      if (version <= 7) {
        html.className = html.className + " lte-ie7";
      }
    }

    if (isFirefox) {
      if (version <= 3) {
        html.className = html.className + " lte-firefox3";
      }
    }

    // KUDOS: http://diveintohtml5.org/everything.html
    function supportsSVG() {
      return !!(document.createElementNS && document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect);
    }
    if (!supportsSVG()) {
      html.className = html.className + " sans-svg";
    }

    // It's probably best to stop here, if it's IE6 or older.
    if (isMSIE && version < 7) return;

    html.className = html.className + " scriptable";
  }

  function getArray(list) {
    var a = [];
    for (var index = 0; index < list.length; index++) {
      a.push(list[index]);
    }
    return a;
  };
  function addListener(element, eventName, handler, useCapture) {
    if (element.addEventListener) {
      element.addEventListener(eventName, handler, useCapture || false);
    } else {
      element.attachEvent("on" + eventName, handler);
    }
  };
  function preventDefault(e) {
    if (e.preventDefault) e.preventDefault();
    e.returnValue = false; // For IE
  };

  function getMetaContent(name) {
    var elements = document.getElementsByTagName("meta");
    for (var index = 0; index < elements.length; index++) {
      if (elements[index].getAttribute("name") == name) {
        return String(elements[index].getAttribute("content"));
      }
    }
    return;
  };

  var shiftPressed = false;
  addListener(document, "keydown", function(e) {
    if (e && (e.keyCode == 16)) {
      shiftPressed = true;
      //reportColor();
    }
  });
  addListener(document, "keyup", function(e) {
    if (e && (e.keyCode == 16)) {
      shiftPressed = false;
    }
  });

  function getOneElementByClassName(contextElement, className) {

    // getElementsByClassName
    if (contextElement.getElementsByClassName) {
      var elements = contextElement.getElementsByClassName(className);
      return elements[0];
    }

    // For browsers that don't suport getElementsByClassName
    var elements = contextElement.getElementsByTagName("*");
    var length = elements.length;
    for (var index = 0; index < length; index++) {
      if (hasClassName(elements[index], className)) {
        return elements[index];
      }
    }
    return;
  };
  function getAllElementsByClassName(contextElement, className) {

    // getElementsByClassName
    if (contextElement.getElementsByClassName) {
      return getArray(contextElement.getElementsByClassName(className));
    }

    // For browsers that don't suport getElementsByClassName
    var elements = contextElement.getElementsByTagName("*");
    var length = elements.length;
    var list = [];
    for (var index = 0; index < length; index++) {
      if (hasClassName(elements[index], className)) {
        list.push(elements[index]);
      }
    }
    return list;
  }

  // KUDOS: Prototype JS (http://www.prototypejs.org/)
  function addClassName(element, className) {
    if (hasClassName(element, className)) return;
    var existingClassName = (element.className == null || element.className == "") ? "" : element.className + " ";
    element.className = existingClassName + className;
  };
  function removeClassName(element, className) {
    element.className = strip(element.className.replace(
      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), " "));
  };
  function hasClassName(element, className) {
    var elementClassName = element.className;
    return (elementClassName.length > 0 && (elementClassName == className ||
      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
  };
  function strip(str) {
    return str.replace(/^\s+/, "").replace(/\s+$/, "");
  };

  function getAncestor(contextElement, tagName) {
    tagName = String(tagName).toLowerCase();
    var ancestor = contextElement.parentNode;
    while(ancestor && String(ancestor.nodeName).toLowerCase() != tagName) {
      ancestor = ancestor.parentNode;
    }
    if (!ancestor) return;
    if (String(ancestor.nodeName).toLowerCase() == tagName) return ancestor;
  };

  // KUDOS: http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
  function getViewportDimensions() {
    var width  = 0;
    var height = 0;

    try {
      // Gecko, WebKit & Opera
      if (window.innerWidth) {
        width  = window.innerWidth;
        height = window.innerHeight;
      } else {

        // IE
        if (document.documentElement &&
          document.documentElement.clientWidth &&
          document.documentElement.clientWidth > 0) {
          width  = document.documentElement.clientWidth;
          height = document.documentElement.clientHeight;

        // IE (Quirks-mode)
        } else {
          width  = document.body.clientWidth;
          height = document.body.clientHeight;
        }
      }
    } catch(e) {}

    return {
      width : width,
      height: height
    };
  };

  var domLoaded = false;
  function onDomLoaded() {
    domLoaded = true;
    setTimeout(function() {
      addClassName(html, "loaded");
    }, 250);
    
    var homePage = document.getElementById("home-page");
    if (!homePage) setTimeout(function() {
      var content = document.getElementById("content");
      if (content) new scrollToElement(content);
    }, 1000);

    // ShareThis
    var workPage = document.getElementById("work-page");
    if (workPage) {

      var share = getOneElementByClassName(document.body, "addthis_button");
      if (share) {
        // Only use the AddThis feature in modern browsers.
        // (old versions of IE seem to have trouble with it, in combination with the HTML5 shim).
        if (!isMSIE || version >= 9) {
          var se = document.createElement("script"); se.type = "text/javascript"; se.async = true;
          se.src = "//s7.addthis.com/js/250/addthis_widget.js";
          var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(se, s);
        }
      }

    }
  }
  window.onDomLoaded = onDomLoaded;

  function available(element) {
    // If the next element has loaded, or if the parent of this
    // element is available, then we know this element is available.
    return (element && (domLoaded || element.nextSibling || available(element.parentNode)));
  };


  /* =Project Description
  ----------------------------------------------- */
  var ProjectDescription = function(element) {
    if (!element) return;

    var showTimer;
    var hideTimer;
    var hidden = false;
    var rendered = false;
    var mouseOverDescription = false;
    var header;

    function initialize() {
      render();

      var availableSpace = getViewportDimensions().height - document.getElementById("header").offsetHeight - element.offsetHeight;
      element.style.bottom = Math.round(availableSpace / 2/3) + "px";
    };
    function update() {
      var button = document.createElement("a");
      button.href="#toggle-description";
      button.className = "hide";
      var buttonInner = document.createElement("span");
      button.appendChild(buttonInner);
      buttonInner.innerHTML = "Close";
      element.appendChild(button);

      addListener(button, "click", function(e) {
        if (showTimer) clearTimeout(showTimer);
        preventDefault(e);
        if (!hidden) hide();
      });
      addListener(element, "click", function(e) {
        var target = e.target;
        if (!target && e.srcElement) target =  e.srcElement; // For IE
        if (target === button || getAncestor(target, "a")) return;
        if (showTimer) clearTimeout(showTimer);
        if (hidden) {
          show();
          preventDefault(e);
        }
      }, true);

      var information = document.createElement("div");
      information.className = "information-icon";
      element.appendChild(information);
      var inner = document.createElement("div");
      information.appendChild(inner);

      addClassName(document.body, "description-scriptable");

      autoHide();
    };
    function autoHide() {
      // Auto-hide the description after a few seconds
      if (hideTimer) clearTimeout(hideTimer);
      //if (hidden) show();
      hideTimer = setTimeout(function() {
        if (!hidden && !mouseOverDescription) hide();
      }, 15000);
    };
    function autoShow() {
      if (showTimer) clearTimeout(showTimer);
      showTimer = setTimeout(show, 2000);
    };
    function render() {
      if (rendered) return;
      rendered = true;

      update();

      addListener(element, "mouseover", function(e) {
        mouseOverDescription = true;
        if (window.onMouseover) window.onMouseover();
      });
      addListener(element, "mouseout", function(e) {
        mouseOverDescription = false;
        if (window.onMouseout) window.onMouseout();
      });

      hide();
      autoShow();

      // Handle the case where the page width changes significantly
      // (i.e. switch between "tiny" and "widescreen" styles).
      addListener(window, "resize", onResize);
      setTimeout(onResize, 100);
    }
    function onResize(e) {
      if (hidden) element.style.left = "-" + (element.offsetWidth - 20) + "px";
      if (!header) header = document.getElementById("header");
      removeClassName(element, "static");
      element.style.top = "auto";

      var contentMargin = 15;
      var imageNavItemMargin = 5;
      var margin = (contentMargin * 2) - imageNavItemMargin;

      if (navList) {
        var upperLimit = header.offsetHeight + navList.offsetHeight + margin;
        if (element.offsetTop < upperLimit) {
          addClassName(element, "static");
          element.style.top = (navList.offsetHeight + margin) + "px";
        }
      }
    };
    function show() {
      element.style.left = "0";
      removeClassName(element, "hidden");
      hidden = false;
    };
    function hide() {
      if (showTimer) clearTimeout(showTimer);
      if (hidden) return;
      element.style.left = "-" + (element.offsetWidth - 20) + "px";
      setTimeout(function() {
        addClassName(element, "hidden");
      }, 100);
      hidden = true;
    };

    initialize();

    return {
      hide: hide,
      show: show,
      update: update,
      onResize: onResize,
      autoHide: autoHide,
      autoShow: autoShow
    };
  };


  /* =Image Navigation
  ----------------------------------------------- */
  var ImageNavigation = function(element) {
    if (!element) return;

    var imageDimensions = {};

    var imagesSection = getOneElementByClassName(element, "images");
    if (imagesSection) {

      var images = getArray(imagesSection.getElementsByTagName("li"));
      var cursor = 0;

      imageNav = document.createElement("nav");
      var imageList = imagesSection.getElementsByTagName("ul")[0];
      imageList.parentNode.insertBefore(imageNav, imageList);

      var position = 0;
      function showImage(targetIndex) {
        var targetImage = images[targetIndex];
        for (var index = 0; index < images.length; index++) {
          //addClassName(images[index], "hidden");
          removeClassName(navItems[index], "active");
        }
        if (targetImage) {
          //removeClassName(targetImage, "hidden");
          position = 0 - targetImage.offsetTop;

          // Strangly, the position is off by 30 pixels in IE7.
          if (isMSIE && version < 8) {
            position -= 30;
          }

          images[0].parentNode.style.top = position + "px";
        }
        cursor = targetIndex;
      };
      function updateImagePosition() {
        var targetImage = images[cursor];
        if (targetImage) {
          position = 0 - targetImage.offsetTop;

          // The position is off by 30 pixels in IE7 *sigh*
          if (isMSIE && version < 8) {
            position -= 30;
          }

          images[0].parentNode.style.top = position + "px";
        }
      };

      // Next / Previous
      var nextPrevious = document.createElement("ul");
      nextPrevious.className = "next-previous";
      imageNav.appendChild(nextPrevious);

      function onMouseover(e) {
        onMouseStop();
        if (hideColorTimer) clearTimeout(hideColorTimer);
      };
      window.onMouseover = onMouseover;
      function hideColor() {
        addClassName(document.body, "reset");
        removeClassName(document.body, "dark");
        removeClassName(document.body, "light");
        colorActive = false;
      };
      var hideColorTimer;
      var colorActive = false;
      function onMouseout(e) {
        if (hideColorTimer) clearTimeout(hideColorTimer);
        hideColorTimer = setTimeout(hideColor, 1000);
      };
      window.onMouseout = onMouseout;

      if (images.length > 0) {
        var nextButton;
        var previousButton;
        (function() {
          var item = document.createElement("li");
          nextPrevious.appendChild(item);
          var button = document.createElement("a");
          item.appendChild(button);
          button.href = "#next";
          button.className = "next";
          var label = document.createElement("span");
          label.appendChild(document.createTextNode("Next"));
          button.appendChild(label);
          addListener(button, "mouseover", onMouseover);
          addListener(button, "mouseout", onMouseout);
          addListener(button, "click", function(e) {

            button._offset = undefined;
            var myCursor = cursor;
            myCursor++;
            if (myCursor > navItems.length - 1) {
              var items = document.getElementById("work").getElementsByTagName("li");
              var nextIndex = 0;
              for (var index = 0; index < items.length; index++) {
                if (hasClassName(items[index].getElementsByTagName("a")[0], "active")) {
                  nextIndex = index + 1;
                  break;
                }
              }
              if (nextIndex > items.length - 1) nextIndex = 0;
              window.location = items[nextIndex].getElementsByTagName("a")[0].href;
              preventDefault(e);
              return;
            }
            showImage(myCursor);
            addClassName(navItems[cursor], "active");
            if (description) description.hide();
            preventDefault(e);
            rerender();
          });
          nextButton = button;

        })();
        (function() {
          var item = document.createElement("li");
          nextPrevious.appendChild(item);
          var button = document.createElement("a");
          item.appendChild(button);
          button.href = "#previous";
          button.className = "previous";
          var label = document.createElement("span");
          label.appendChild(document.createTextNode("Previous"));
          button.appendChild(label);
          addListener(button, "mouseover", onMouseover);
          addListener(button, "mouseout", onMouseout);
          addListener(button, "click", function(e) {

            button._offset = undefined;
            var myCursor = cursor;
            myCursor--;
            if (myCursor < 0) {
              var items = document.getElementById("work").getElementsByTagName("li");
              var nextIndex = 0;
              for (var index = 0; index < items.length; index++) {
                if (hasClassName(items[index].getElementsByTagName("a")[0], "active")) {
                  nextIndex = index - 1;
                  break;
                }
              }
              if (nextIndex < 0) nextIndex = items.length - 1;
              window.location = items[nextIndex].getElementsByTagName("a")[0].href;
              preventDefault(e);
              return;
            }
            showImage(myCursor);
            addClassName(navItems[cursor], "active");
            if (description) description.hide();
            preventDefault(e);
            rerender();
          });
          previousButton = button;

        })();

        function onMouseMove(e) {
          var target = e.target;
          if (!target && e.srcElement) target =  e.srcElement; // For IE

          removeClassName(nextButton, "inactive");
          removeClassName(previousButton, "inactive");
          var iconSize = 35;

          // Position the icon obove the mouse, centered horizontally.
          if (!target._offset) target._offset = getCumulativeOffset(target);
          var x = Math.round(e.clientX - target._offset.left - (iconSize / 2));
          var y = Math.round(e.clientY - target._offset.top - iconSize + 3);

          // Prevent the icon from being cropped as it nears the edge of the other button (i.e. the center of the image).
          if (target === previousButton && (x + iconSize) >= target.offsetWidth) {
            x = target.offsetWidth - iconSize;
          } else if (target === nextButton && x <= 0) {
            x = 0;
          }

          // Position the icon
          target.style.backgroundPosition = x + "px " + y + "px";

          // Position the label
          var label = target.firstChild;
          if (label.style) {
            if (target.className.indexOf("next") >= 0) {
              label.style.top  = Math.round(y + ((iconSize - label.offsetHeight) / 2)) + "px";
              label.style.left = Math.round(x - (label.offsetWidth + 5)) + "px";
            } else {
              label.style.top  = Math.round(y + ((iconSize - label.offsetHeight) / 2)) + "px";
              label.style.left = Math.round(x + (iconSize + 5)) + "px";
            }
          }

          lastX       = x;
          lastY       = y;
          lastButton  = target;

          if (mouseTimer) clearTimeout(mouseTimer);
          mouseTimer = setTimeout(function() {
            addClassName(nextButton, "inactive");
            addClassName(previousButton, "inactive");
          }, 1000);

          onMouseStop();
        };
        var mouseTimer;
        var lastX;
        var lastY;
        var lastButton;
        var canvas;

        var pageNames = document.location.href.split("/");
        var pageName = pageNames[pageNames.length - 2]; // Example: navellier

        function isDark(data) {
          var value = Number(data[0]) + Number(data[1]) + Number(data[2]);
          var max = 255 * 3;
          return ((value / max) < 0.5);
        };
        
        var request = null;/* XMLHttpRequest */;  // Ajax request object
        function sendRequest(key, value) {
          // IE7+, Firefox, Chrome, Opera, Safari
          if (window.XMLHttpRequest) {
            request = new XMLHttpRequest();
          // IE6, IE5
          } else {
            request = new ActiveXObject("Microsoft.XMLHTTP");
          }

          params = "key=" + key + "&value=" + value;

          request.onreadystatechange = onResponse;

          request.open("POST", "/color/", true);

          // Send the proper header information along with the request
          request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

          request.send(params);
        };
        function onResponse() {
          if (request.readyState != 4) return;

          try {
            // If the request was successfull
            if (request.status == 200) {
              request = null;
              return;
            }

          } catch(error) {
            if (window.console && window.console.log) window.console.log(error);
          }
        };

        var lastColor;
        var requestTimer;
        var colorReporter;
        function setColor(color) {
          try {
            lastColor = color;

            var data = color.replace("rgb(", "").replace(")", "").split(",");

            document.getElementById("header").style.backgroundColor = "transparent";
            document.body.style.backgroundColor = color;

            removeClassName(document.body, "reset");

            if (isDark(data)) {
              addClassName(document.body, "dark");
              removeClassName(document.body, "light");
            } else {
              removeClassName(document.body, "dark");
              addClassName(document.body, "light");
            }
          } catch(e) {}
        };

        function reportColor() {
          return; // Disable this for now.
          if (!colorReporter) {
            colorReporter = document.createElement("div");
            colorReporter.className = "color-reporter";
            document.body.appendChild(colorReporter);
          }
          
          if (colorReporter) colorReporter.innerHTML = document.body.style.backgroundColor;
        };
        window.reportColor = reportColor;

        function supportsCanvas() {
          return !!document.createElement('canvas').getContext;
        }

        function onMouseStop() {
          try {

            if (!supportsCanvas()) return;

            var currentImage = images[cursor].getElementsByTagName("img");
            if (currentImage && currentImage.length && currentImage.length > 0) {
              currentImage = currentImage[0];
            }

            if (currentImage && currentImage.nodeName && currentImage.nodeName.toLowerCase() == "img") {

              if (shiftPressed) {
                var img = new Image();
                img.src = currentImage.src;

                var context = document.getElementById("color-picker").getContext("2d");
                context.drawImage(img, 0, 0, currentImage.offsetWidth, currentImage.offsetHeight);
                if (lastButton) data = context.getImageData(lastX + lastButton.offsetLeft, lastY + lastButton.offsetTop, 1, 1).data;
              }
              if (shiftPressed && data) {
                setColor( "rgb(" + data[0] + "," + data[1] + "," + data[2] + ")");
              } else {
                var color = getMetaContent("background-color");
                if (color) setColor(color);
                colorActive = true;
              }

            }

          } catch(e) {
             console.error(e);
          }
        }
        addListener(nextButton, "mousemove", onMouseMove);
        addListener(previousButton, "mousemove", onMouseMove);

        function updateVideos() {
          for (var index = 0; index < images.length; index++) {
            var firstImage = images[index].firstChild;
            while (firstImage.nodeType != 1 && firstImage.nextSibling) {
              firstImage = firstImage.nextSibling;
            }

            var imageWidth = firstImage.offsetWidth;
            var imageHeight = firstImage.offsetHeight;
            if (imageHeight <= 0 || imageWidth <= 0) {
              // If we haven't been trying for more than ten seconds
              if (renderTries++ < 100) {
                // Wait 1/10 second, and try again
                setTimeout(rerender, 100);
                return;
              }
            }

            // Preserve the aspect ratio of iframe elements (i.e. video embedded from third parties).
            if (firstImage.nodeName.toLowerCase() == "iframe") {
              if (!firstImage.id) firstImage.id = firstImage.parentNode.id + "-content";
              if (!imageDimensions[firstImage.id]) imageDimensions[firstImage.id] = {
                width: firstImage.width,
                height: firstImage.height,
                ratio: firstImage.height / firstImage.width
              };
              if (!firstImage._defaultWidth) firstImage._defaultWidth = firstImage.width;
              firstImage.width = "100%";
              if (firstImage.offsetWidth > firstImage._defaultWidth) firstImage.width = firstImage._defaultWidth;
              firstImage.height = Math.round(firstImage.offsetWidth * imageDimensions[firstImage.id].ratio);
            }
          }
        };

        var renderTries = 0;
        var renderTimer;
        function rerender() {

          /* BEGIN KLUDGE (to handle case where first image has not yet loaded) */
          // If we haven't been trying for more than ten seconds
          if (renderTries++ < 100) {
            // Wait 1/10 second, and try again
            clearTimeout(renderTimer);
            renderTimer = setTimeout(rerender, 100);
          }
          var firstImage = images[cursor].firstChild;
          while (firstImage.nodeType != 1 && firstImage.nextSibling) {
            firstImage = firstImage.nextSibling;
          }
          var imageWidth = firstImage.offsetWidth;
          var imageHeight = firstImage.offsetHeight;
          if (imageHeight > 0 && imageWidth > 0) {
            clearTimeout(renderTimer);
            renderTries = 0;
          } else {
            return;
          }
          /* END KLUDGE */

          updateVideos();
          if (window.updateProjectImages) window.updateProjectImages();
          updateNextPrevious();
          updateImagePosition();
        };
        function updateNextPrevious() {
          var firstImage = images[cursor].firstChild;
          while (firstImage.nodeType != 1 && firstImage.nextSibling) {
            firstImage = firstImage.nextSibling;
          }

          var imageWidth = firstImage.offsetWidth;
          var imageHeight = firstImage.offsetHeight;

          var buttonWidth = (imageWidth / 2);
          var buttonHeight = imageHeight;
          if (firstImage.nodeName.toLowerCase() != "img") {
            buttonWidth = (imageWidth / 4);
            buttonHeight = (imageWidth / 2);
          }

          previousButton.style.top    = ((imageHeight - buttonHeight) / 2) + "px";
          previousButton.style.left   = "0";
          previousButton.style.height = buttonHeight + "px";
          previousButton.style.width  = buttonWidth + "px";

          nextButton.style.top    = ((imageHeight - buttonHeight) / 2) + "px";
          nextButton.style.left   = (imageWidth - buttonWidth) + "px";
          nextButton.style.height = buttonHeight + "px";
          nextButton.style.width  = buttonWidth + "px";
        };

        // Handle the case where the page width changes significantly
        // (i.e. switch between "tiny" and "widescreen" styles).
        (function() {
          var resizeTimer;
          function onResize(e) {
            if (typeof(temp) == "function") temp();
            clearTimeout(resizeTimer);
            resizeTimer = setTimeout(rerender, 100);
          }
          addListener(window, "resize", onResize);
          setTimeout(onResize, 100);
        })();
      }

      // Numbers
      navList = document.createElement("ul");
      navList.className = "numbered";
      var navItems = [];
      imageNav.appendChild(navList);
      imageNav.setAttribute("id", "image-nav");

      for (var index = 0; index < images.length; index++) {
        (function() {
          var item = document.createElement("li");
          addListener(item, "mouseover", onMouseover);
          addListener(item, "mouseout", onMouseout);
          navItems.push(item);
          navList.appendChild(item);
          var link = document.createElement("a");
          var linkIndex = index;
          var nextID = "image-" + String(index + 1);  // Start with one, instead of zero.
          images[index].setAttribute("id", nextID);
          link.href = "#" + nextID;
          link.appendChild(document.createTextNode(index + 1));
          item.appendChild(link);
          addListener(link, "click", function(e) {
            showImage(linkIndex);
            addClassName(link.parentNode, "active");
            rerender();
            if (description) description.hide();
            preventDefault(e);
          });
          if (index == 0) addClassName(item, "active");
        })();
      }

      // Don't hide color when mousing over the header.
      var header = document.getElementById("header");
      addListener(header, "mouseover", function() {
        if (colorActive) {
          onMouseover();
        }
      });
      addListener(header, "mouseout", function() {
        if (colorActive) {
          onMouseout();
        }
      });
    }
  };


  /* =Scroll to Content
  ----------------------------------------------- */
  function getCumulativeOffset(element) {
    var top = 0;
    var left = 0;
    do {
      top     += element.offsetTop  || 0;
      left    += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return {
      top: top,
      left: left
    };
  };
  function getScrollOffsets() {
    var top  = 0;
    var left = 0;

    try {
      if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
        top  = document.body.scrollTop;
        left = document.body.scrollLeft;
      }
    } catch(e) {}

    return {
      top : top,
      left: left
    };
  };
  function scrollToElement(element, callback) {
    if (!element) return;

    var scrollTimer;
    var duration = 5;
    var lastScrollTop;

    function scrollTowards(targetY) {
      var scroll = getScrollOffsets();
      var scrollTop = scroll.top;

      // Handle case where user scrolls up
      if (lastScrollTop && scroll.top < lastScrollTop) {
        if (scrollTimer) clearTimeout(scrollTimer);
        if (callback) callback();
        return;
      }

      var increment = Math.abs(scroll.top - targetY) / duration;

      // If we're getting close (or if we've scrolled as far as we can), jump straight to it and stop.
      var stop = false;
      if (increment < 1) {
        increment = Math.abs(scroll.top - targetY);
        stop = true;
      }
      window.scrollTo(scroll.left, scroll.top + Math.ceil(increment));
      if (lastScrollTop == scroll.top) {
        stop = true;
      }
      if (!stop && scroll.top < targetY) {
        requestAnimationFrame(function() {
          scrollTowards(targetY);
        });
      } else {
        if (callback) callback();
      }

      lastScrollTop = scrollTop;
    };

    function initialize() {
      if (scrollTimer) clearTimeout(scrollTimer);
      scrollTimer = setTimeout(function() {
        var y = getCumulativeOffset(element).top;
        var scroll = getScrollOffsets();
        scrolling = false;
        if (getViewportDimensions().height + scroll.top < y) {
          lastScrollTop = undefined;
          var targetY = getCumulativeOffset(element).top;

          var footer = document.getElementById("footer");
          if (footer) {
            var maxScrollableDistance = Math.abs(footer.offsetTop + footer.offsetHeight - getViewportDimensions().height);

            if (maxScrollableDistance < targetY) {
              targetY = maxScrollableDistance;
            }
          }

          scrollTowards(targetY, y, scroll);
        } else {
          if (callback) callback();
        }
      }, 100);
    };

    initialize();
  };


  /* =What
  ----------------------------------------------- */
  (function() {

    var tries = 0;

    function initialize() {
      var target = document.getElementById("what");

      if (available(target)) {
        tries = 0;
        setTimeout(function() {

          var next = getOneElementByClassName(target, "next");
          var link = next.getElementsByTagName("a");
          if (link && link.length && link.length > 0) {
            link = link[0];
            addListener(target, "click", function(e) {
              window.location.href = link.href;
            });
            addListener(target, "mouseover", function() {
              addClassName(link, "hover");
            });
            addListener(target, "mouseout", function() {
              removeClassName(link, "hover");
            });
            target.style.cursor = "pointer";
          }

        }, 100);
      } else {
        // If we haven't been trying for more than ten seconds
        if (tries++ < 100) {
          // Wait 1/10 second, and try again
          setTimeout(initialize, 100);
        }
      }
    };

    initialize();

  })();


  /* =What We Do
  -----------------------------------------------
  Turn the content area into a giant button that goes to the next stage.
  ----------------------------------------------- */
  (function() {

    var tries = 0;

    function initialize() {
      var content = document.getElementById("content");
      var what    = document.getElementById("what");

      if (available(content) && available(what)) {
        tries = 0;

        if (document.getElementById("brand-page") ||
            document.getElementById("services-page")) {
          setTimeout(function() {

            var next = getOneElementByClassName(what, "next");
            var link = next.getElementsByTagName("a");
            if (link && link.length && link.length > 0) {
              link = link[0];
              addListener(what, "click", function(e) {
                window.location.href = link.href;
              });
              addListener(what, "mouseover", function() {
                addClassName(link, "hover");
              });
              addListener(what, "mouseout", function() {
                removeClassName(link, "hover");
              });
              what.style.cursor = "pointer";
            }

          }, 100);
        } else {
          var next = getOneElementByClassName(what, "next");
          var link = next.getElementsByTagName("a");
          var mouseTimer;
          if (link && link.length && link.length > 0) {
            link = link[0];
            addListener(content, "click", function(e) {
              window.location.href = link.href;
            });

            var next = getOneElementByClassName(what, "next");
            if (next) {
              next = next.getElementsByTagName("a");
              if (next && next.length > 0) {
                next = next[0];
              }
            }
            next.style.textDecoration = "none";
            next = next.cloneNode(true);
            next.innerHTML = "Next";
            content.appendChild(next);
            next.id = "what-next";

            function onMouseMove(e) {
              removeClassName(next, "inactive");
              var target = e.target;
              if (!target && e.srcElement) target =  e.srcElement; // For IE

              var iconSize = 35;

              if (!next._offsetWidth) next._offsetWidth = next.offsetWidth;

              // Position the icon obove the mouse, centered horizontally.
              var x = Math.round(e.clientX - next._offsetWidth + (iconSize / 2));
              var y = Math.round(e.clientY - iconSize + 3);

              next.style.left = x + "px ";
              next.style.top  = y + "px";

              if (mouseTimer) clearTimeout(mouseTimer);
              mouseTimer = setTimeout(function() {
                addClassName(next, "inactive");
              }, 1000);
            };

            addListener(document.body, "mousemove", onMouseMove);

            content.style.cursor = "pointer";
          }
        }

      } else {
        // If we haven't been trying for more than ten seconds
        if (tries++ < 100) {
          // Wait 1/10 second, and try again
          setTimeout(initialize, 100);
        }
      }
    };

    initialize();

  })();


  /* =Project
  ----------------------------------------------- */
  var description;
  var imageNavigation;
  var navList;

  function initDescription() {
    var tries = 0;

    function initialize() {
      var project = document.getElementById("project");

      if (available(project)) {
        tries = 0;
        setTimeout(function() {

          if (!description) {
            var descriptionElement = getOneElementByClassName(project, "description");
            description = new ProjectDescription(descriptionElement);
            window.descriptionObj = description;
          } else {
            description.update();
            setTimeout(description.onResize, 10);
          }

        }, 100);
      } else {
        // If we haven't been trying for more than ten seconds
        if (tries++ < 100) {
          // Wait 1/10 second, and try again
          setTimeout(initialize, 100);
        }
      }
    };

    initialize();
  };

  function initImages() {
    var tries = 0;

    function initialize() {
      var projectElement = document.getElementById("project");

      if (available(projectElement)) {
        tries = 0;

        setTimeout(function() {
          imageNavigation = new ImageNavigation(projectElement);
        }, 100);

        var imageContainer = getOneElementByClassName(projectElement, "images");

        var content = document.getElementById("content");
        if (imageContainer) {
          function updateProjectImages() {
            var images = imageContainer.getElementsByTagName("img");
            for (var index = 0; index < images.length; index++) {
              var image = images[index];
              if (content.offsetWidth <= 500) {
                image.src = String(image.src).replace("/images/work/", "/images/small/work/");
              } else {
                image.src = String(image.src).replace("/images/small/work/", "/images/work/");
              }
            }
          };
          updateProjectImages();
          window.updateProjectImages = updateProjectImages;
        }

        addClassName(imageContainer, "ready");

      } else {
        // If we haven't been trying for more than ten seconds
        if (tries++ < 100) {
          // Wait 1/10 second, and try again
          setTimeout(initialize, 100);
        }
      }
    };

    initialize();
  };

  initImages();
  initDescription();


  /* =Page
  ----------------------------------------------- */
  (function() {
    var tries = 0;

    function getStyle(element, style) {
        var value = element.style[style];
        if (!value && element.currentStyle) {
            value = element.currentStyle[style];
        }
        if (!value) {
            var css = document.defaultView.getComputedStyle(element, null);
            value = css ? css[style] : null;
        }
        return value;
    };

    function initialize() {
      var container = document.getElementById("container");

      if (available(container)) {
        tries = 0;

        var workPage = document.getElementById("work-page");
        var header = document.getElementById("header");
        var homeWork = document.getElementById("home-work");
        var content = document.getElementById("content");
        var footer = document.getElementById("footer");

        if (header && content && footer) {
          var lastContentHeight;
          function compare() {
            var availableHeight = (container.offsetHeight - header.offsetHeight); // - footer.offsetHeight;
            if (homeWork) availableHeight -= homeWork.offsetHeight;
            var defaultHeight = content.offsetHeight;
            //console.log("defaultHeight: " + defaultHeight);
            //console.log("availableHeight: " + availableHeight);
            if (defaultHeight < availableHeight) {
              var padding = parseInt(getStyle(content, "paddingTop")) + parseInt(getStyle(content, "paddingBottom"));
              var contentHeight = (availableHeight - padding);
              content.style.height = contentHeight + "px";

            // In IE7, if the content is taller than the viewport, it doesn't resize properly.
            } else if (isMSIE && version <= 8) {
              if (document.getElementById("studio")) {
                //document.body.insertBefore(document.createTextNode("contentHeight: " + contentHeight), document.body.firstChild);
                content.style.height = document.getElementById("studio").offsetHeight + "px";
              }
            }
          }
          function scaleContent(delay) {
            if (workPage) return;
            content.style.height = "auto";
            compare();
          }
          addListener(window, "resize", scaleContent);
          addListener(window, "loaded", scaleContent);
          window.scaleContent = scaleContent;
          scaleContent();
          setTimeout(scaleContent, 100);        // Just in case.
        }

      } else {
        // If we haven't been trying for more than ten seconds
        if (tries++ < 100) {
          // Wait 1/10 second, and try again
          setTimeout(initialize, 100);
        }
      }
    };

    initialize();
  })();


  /* =Jump to Work
  ----------------------------------------------- */
  (function() {
    var tries = 0;

    function initialize() {
      var jump = document.getElementById("work-jump");
      var work = document.getElementById("work");

      if (available(jump) && available(work)) {
        tries = 0;
        setTimeout(function() {

          addListener(jump, "click", function(e) {
            new scrollToElement(work);
            preventDefault(e);
          });

        }, 100);
      } else {
        // If we haven't been trying for more than ten seconds
        if (tries++ < 100) {
          // Wait 1/10 second, and try again
          setTimeout(initialize, 100);
        }
      }
    };

    initialize();
  })();


  /* =TestimonialRotator
  ----------------------------------------------- */
  var TestimonialRotator = function(items) {
    if (!items) return;

    var animationTimer;
    var autoTimer;
    var duration = 0.15;
    var intervalTime = 50;
    var numIntervals = duration * 1000 / intervalTime;
    var cursor = 0;
    var depth = 0;

    var autoDelay = 8;    // Seconds

    var maxHeight = 0;

    function initialize() {
      if (items.length <= 1) return;  // If there's only one ad, do nothing.

      for (var index = 0; index < items.length; index++) {
        if (items[index].offsetHeight > maxHeight) maxHeight = items[index].offsetHeight;
        items[index].style.display = "none";
      }

      cursor = Math.floor(Math.random() * items.length);
      items[cursor].style.display = "block";
      items[cursor].style.zIndex = ++depth;

      // Prevent the testimonials from resizing their container, as they rotate.
      items[cursor].style.height = maxHeight + "px";

      delayAutoNext();
      addListener(items[cursor].parentNode, "mousemove", onUserAction);
    };

    function onUserAction(e) {
      delayAutoNext();
    };

    function delayAutoNext(seconds) {
      if (seconds == null) seconds = autoDelay;
      if (autoTimer) clearTimeout(autoTimer);
      autoTimer = setTimeout(autoNext, seconds * 1000);
    };

    function autoNext() {
      next();
      delayAutoNext();
    };

    function next() {
      items[cursor].style.display = "none";
      cursor++;
      if (cursor >= items.length) cursor = 0;
      var item = items[cursor];
      item.style.height = maxHeight + "px";
      item.style.display = "block";
      item.style.opacity = 0;
      item.style.zIndex = ++depth;

      if (animationTimer) clearInterval(animationTimer);
      animationTimer = setInterval(function() {
        var current = Number(item.style.opacity);
        var interval = (1 - current) / numIntervals;
        var opacity = current + interval;
        if ((1 - opacity) <= 0.05) {
          opacity = 1;
          if (animationTimer) clearInterval(animationTimer);
        }
        item.style.opacity = opacity;
      }, intervalTime);
    };

    initialize();
  };
  (function() {

    var tries = 0;

    function initialize() {
      var target = document.getElementById("testimonials");

      if (available(target)) {
        tries = 0;
        var list = getAllElementsByClassName(target, "testimonial");
        new TestimonialRotator(list);
      } else {
        // If we haven't been trying for more than ten seconds
        if (tries++ < 100) {
          // Wait 1/10 second, and try again
          setTimeout(initialize, 100);
        }
      }
    };

    initialize();

  })();


  /* =Internet Explorer 7 Fixes
  ----------------------------------------------- */
  // Simulate CSS dynamic content.

  if (isMSIE && version < 8) {

    (function() {

      var tries = 0;

      function initialize() {
        var target = document.getElementById("footer");

        if (available(target)) {
          tries = 0;

          function before(selector, content) {
            var results = Sizzle(selector);
            if (results && results.length) {
              for (var index = 0; index < results.length; index++) {
                results[index].innerHTML = '<span style=\"padding-right: 0.25em\">' + content + '</span>' + results[index].innerHTML;
              }
            }
          };

          function after(selector, content) {
            var results = Sizzle(selector);
            if (results && results.length) {
              for (var index = 0; index < results.length; index++) {
                results[index].innerHTML = results[index].innerHTML + '<span style=\"padding-left: 0.25em\">' + content + '</span>';
              }
            }
          };

          after("#intro .more", "→");
          after("#news .more", "→");
          after("#blog .more", "→");
          after("#feed .more", "→");
          after("#what .next", "→");
          after("#news-page #studio .story-inner div.main a p", "»");
          before("#contact-page #studio .story-inner .back a", "←");

        } else {
          // If we haven't been trying for more than ten seconds
          if (tries++ < 100) {
            // Wait 1/10 second, and try again
            setTimeout(initialize, 100);
          }
        }
      };

      initialize();

    })();

  }

})();

