var openClass         = 'open',
    closeClass        = 'closed',
    menuSpeed         = 500,
    captionSpeed      = 1000,
    deepestNesting    = 3,
    captionWidth      = 380,
    caption           = '',
    openMenus         = [],
    clickedElement    = {},
    landing_image_id  = Math.ceil(Math.random() * 7);

function toggleClass(menu) {
  if (menu.hasClass(openClass)) {
    menu.removeClass(openClass).
      addClass(closeClass);
  } else {
    menu.removeClass(closeClass).
      addClass(openClass);
  };
};

function isSectionMenu(menu) { return menu.hasClass('section'); };

function isMenu(menu) { return menu.hasClass('menu'); };

function isMenuOpen(menu) { return menu.hasClass(openClass); };

function addToOpenMenus(menu) {
  openMenus.push(menu)
  openMenus = _.uniq(openMenus);
};

function removeFromOpenMenus(menu) {
  var menuSelector  = menu.selector;
  var extract       = [];
  _.each(openMenus, function(openMenu) {
    extract.push(openMenu.selector);
  });
  extract = _.without(extract, menuSelector);
  openMenus = []
  _.each(extract, function(selector){
    openMenus.push($(selector));
  });
};

function openMenu(menu, openFirst) {
  menu.slideDown(menuSpeed, function() { toggleClass(menu); });
  if (openFirst) {
    menuId = $(menu).attr('id');
    loadImageFromURLChange(menuId, '1');
  };
  addToOpenMenus(menu);
};

function closeMenu(menu) {
  menu.slideUp(menuSpeed, function() { toggleClass(menu); });
  removeFromOpenMenus(menu);
};

function toggleMenu(menu, openFirst) {
  if (isMenuOpen(menu)) {
    closeMenu(menu);
  } else {
    openMenu(menu, openFirst);
  };
};

function findMenu(id) { return $('ul#' + id); };

function splitHash() { return $.address.value().substr(1, $.address.value().length).split('/'); };

function buildHash(array) { return array.join('/'); };

function setImage(image) {
  var artworkContainer = $('#artwork');
  if (image['type'] == 'video') {
    artworkContainer.css('background', 'none');
    setVideo(image);
  } else {
    artworkContainer.css('width', '100%');
    artworkContainer.css('height', '100%');
    $('video').remove();
    artworkContainer.css(
      containerStyle( image['src'],
                      image['bg-position'],
                      image['repeat'],
                      image['bg-color']
      )
    );
    $(window).unbind('resize');
  }
};

function setVideo(video) {
  var artworkContainer = $('#artwork');
  var width = video['size'][0];
  var height = video['size'][1];
  var picture = video['picture'];
  var videoContainer = $('<video></video>').attr('autoplay', 'autoplay').attr('loop', 'loop').attr('width', width).attr('height', height);
  var formats = ['.mp4', '.webm', '.ogv'];
  $.each(formats, function(i, v){
    var source = $('<source />').attr('src', video['src'] + v);
    source.appendTo(videoContainer);
  })
  $('<div></div>').css({'background':'url(' + picture + ') repeat', 'width':'100%', 'height':'100%'}).appendTo(videoContainer);
  videoContainer.appendTo(artworkContainer);
  sizeVideo();
  $(window).resize(sizeVideo);
};

function sizeVideo() {
  var video           = $('video'),
      container       = $('#artwork'),
      videoHeight     = video.height(),
      videoWidth      = video.width(),
      ratio           = (parseInt(videoWidth) / parseInt(videoHeight)),
      documentHeight  = $(document).height(),
      windowWidth     = $(window).width();

  container.width(documentHeight * ratio);
  container.height(documentHeight);
  video.removeAttr('width').
    removeAttr('height').
      width('100%').
        height('100%');
  if (Modernizr.video) {
    var videoOffset = (container.width() - windowWidth) - documentHeight;
    video.css('left', -videoOffset);
  }
};

function containerStyle(imageSource, position, repeat, color) {
  var positionAttribute     = position  ? position : 'center center',
      repeatAttribute       = repeat    ? 'repeat' : 'no-repeat',
      imageSourceAttribute  = "url('" + imageSource + "')";
  return {
    'background-image':     imageSourceAttribute,
    'background-position':  positionAttribute,
    'background-repeat':    repeatAttribute,
    'background-color':     color
  };
};

function getImage(project, imageId) {
  return images[project][imageId];
};

function loadImageFromURLChange (project, image) {
  var imageId   = image.match(/\d+/)[0],
      imageInfo = getImage(project, imageId);
  setImage(imageInfo);
  setCaption(imageInfo);
  selector    = '#' + project + ' a[data-artwork = "' + image + '"]'
  artworkItem = $(selector);
  if (!artworkItem.hasClass('visited')) { artworkItem.addClass('visited') };
  if (!artworkItem.hasClass('selected')) {
    removeSelectedText = $('.selected').text().replace(' *', '');
    $('.selected').
      text(removeSelectedText).
        removeClass('selected');
    text = artworkItem.text();
    artworkItem.text(text + " *");
    artworkItem.addClass('selected');
  };
};

function arrayDiff(a1, a2) {
  var a     = [],
      diff  = [];
  for(var i = 0; i < a1.length; i++) { a[a1[i]]=true; };
  for(var i = 0; i < a2.length; i++) { 
    if(a[a2[i]]) {
      delete a[a2[i]];
    } else {
      a[a2[i]] = true;
    }
  };
  for(var k in a) { diff.push(k); };
  return diff;
};

//TODO toggle animation
function setCaption(image) {
  caption.clearQueue();
  caption.animate({
    width: 0,
  },
  captionSpeed,
  function() {
    caption.html(image['caption']);
    caption.animate({
      width: captionWidth
    },
    captionSpeed
    );
  });
};

$.address.change(function(event) {
  var hash        = splitHash(),
      section     = hash[0],
      project     = hash[1],
      image       = hash[2],
      openMenuIds = _.map(openMenus, function(menu) {
                      return menu.attr('id');
                    });
  if (section == 'about') {
    if (section && !_.include(openMenuIds, section)) {
      toggleMenu(findMenu(section), false);
    };
    if (project) {
      loadImageFromURLChange(section, project);
    } else {
      loadImageFromURLChange(section, '1');
    };
  } else {
    var sectionProject = '';
    if (section == 'projects') {
      sectionProject = 'project_' + project;
    } else {
      sectionProject = section + '_' + project;
    };
    if (_.isEmpty(section)) { section = null; };
    if (section && !_.include(openMenuIds, section)) {
      toggleMenu(findMenu(section), false);
    };
    if (project && !_.include(openMenuIds, sectionProject)) {
      toggleMenu(findMenu(sectionProject), true);
    };
    if (image) {
      loadImageFromURLChange(sectionProject, image);
    };
  };
  if (!_.isEmpty(clickedElement)) {
    var clickedElementId  = clickedElement.next().attr('id'),
        menu              = findMenu(clickedElementId);
    if (isMenuOpen(menu)) {
      closeMenu(menu);
    };
  };
  clickedElement = {};
});

function toggleAllMenus(menus) {
  menus.slideToggle(1).addClass(closeClass);
};

function closeAllMenus(menus) {
  $('video').remove();
  menus.slideUp(menuSpeed).addClass(closeClass);
  $.address.value('');
}

function landingImage() {
  loadImageFromURLChange('landing', landing_image_id.toString());
};

$(document).ready(function(){
  $('#current-year').text(new Date().getFullYear());
  var menus = $('ul').not('#main_menu');
  caption   = $('#caption');
  toggleAllMenus(menus);
  landingImage();
  $('a.logo').click(function() {
    closeAllMenus(menus);
    landingImage();
  });
  $('a').click(function(){
    var $this = $(this);
    var menu  = $this.next('ul');
    var hash  = [];
    if (isMenu($this)) {
      var menuId =  $this.next('ul').
                      attr('id').
                        replace(/^(art_|design_|project_)/,'');
      if (!_.include(splitHash(), menuId)) { hash.push(menuId); };
    } else {
      hash.push($this.attr('data-artwork'));
    };
    $.each( $this.parents('ul').not('#main_menu'),
            function(item, value) {
              hash.push(
                $(value).attr('id').
                  replace(/^(art_|design_|project_)/,'')
              );
            });
    clickedElement = $(this);
    $.address.value(buildHash(hash.reverse()));
  });
});

$(document).scroll(function() {
  $('#artwork').css('top', window.pageYOffset);
});

