(function($){
  
  var overlay;
  var viewer;
  var lightbox;
  var mode = 'off';
  var current;
  var mask;
  var menu;
  var profile;
  var next_page_link;
  var prev_page_link;
  
  var work_page = function(thumb){
    var work = thumb.parent();
    return Math.floor(work.position().top/mask.height());
  }
  
  var current_page = function(){
    return -menu.position().top/mask.height();
  }
  
  var total_pages = function(){
    return Math.ceil($('.work_preview').filter(':not(.off)').length / 6);
  }
  
  var minned = function(n, min){
    min = !min ? 0 : min;
    return n < 0 ? 0 : n;
  }
  
  var video_listener = ChromelessPlayer.createListener();
  video_listener.onStateChange = function(s){
    if(s == 'playing' || s == 'buffering'){
      $('#pause_button').show();
      $('#play_button').hide();
    }else{
      $('#play_button').show();
      $('#pause_button').hide();
    }
  }
  video_listener.onProgress = function(p){
    $('#load_progress').css({width:(p*100)+'%'});
  };
  video_listener.onPlayback = function(p){
    $('#playback_progress').css({width:p+'%'});
  }
  
  var filetype = function(str){
    if(str == undefined) return 'other';
    if(/\.(jpeg|jpg)$/i.test(str)){
      type = 'image';
    }else if(/\.(flv|f4v|mp4|m4v)$/i.test(str)){
      type = 'video';
    }else{
      type = 'other';
    }
    return type;
  }
  
  //set up the overlay  
  $.fn.configurePages = function(){
    if(total_pages() > 1){
      // next_page_link.fadeIn('fast');
      // prev_page_link.fadeIn('fast');
      next_page_link.click(function(e){
        e.preventDefault();
        menu.showWorkPage(current_page() + 1);
      });
      prev_page_link.click(function(e){
        e.preventDefault();
        menu.showWorkPage(current_page() - 1);
      });
      menu.bind('menu.page_changed', function(e, p){
        if(p == 0){
          prev_page_link.fadeOut('fast');
        }else{
          prev_page_link.fadeIn('tast');
        }
        if(p == total_pages()-1){
          next_page_link.fadeOut('fast');
        }else{
          next_page_link.fadeIn('fast');
        }
      }).trigger('menu.page_changed',[0]);
    }else{
      next_page_link.fadeOut('fast');
      prev_page_link.fadeOut('fast');
    }
  }
  
  $.fn.prepareOverlay = function(){
    overlay = $('<div id="work_overlay"></div>');
    overlay
      .css({
        position: 'fixed',
        width: '100%',
        height: '100%',
        background: '#000',
        opacity: 0.8,
        top: '0',
        left: '0',
        display: 'none',
        'z-index' : '49'
      })
      .click(function(e){
        e.preventDefault();
        e.stopPropagation();
        $(this).lightsUp();
      });
      viewer = $("<div id='work_viewer'></div>");
      viewer.css({
        position: 'absolute',
        background: '#000',
        'z-index': '50'
      });
      $('body')
        .append(overlay)
        .append(viewer);
  }
  
  $.fn.workViewer = function(container){
    if(!container) container = '.profile';
    $(document).prepareOverlay();
    //put the overlay in the DOM
    profile = $(container).eq(0);
    
    menu = $('.work_samples').eq(0);
    mask = $('<div id="work_sample_mask"></div>').css({
      'height' : '184px',
      'overflow' : 'hidden'
    });
    menu.css({
      'height' : 'auto',
      'overflow' : 'visible',
      'position' : 'relative'
    }).wrap(mask);
    mask = $('#work_sample_mask');
      
    prev_page_link = $('<a id="work_page_prev_link" href="#"><span>-</span> back</a>');
    next_page_link = $('<a id="work_page_next_link" href="#">more <span>+</span></a>');
    profile.append(prev_page_link);
    profile.append(next_page_link);
    prev_page_link.hide()
    next_page_link.hide()
    profile.configurePages();
    
      
    this.click(function(e){
      e.preventDefault();
      $(this).showWork();
    });
    
    
    var categories = new Array;
        
    this.each(function(i, e){
      var $element = $(e);
      $element.siblings().hide();
      var classes = $element.parent().attr('class').split(' ');
      $.merge(categories, $.grep(classes, function(a){ return a != 'work_preview' && $.inArray(a, categories) == -1}));
      var i;
      if(filetype($element.attr('href')) == 'image'){
        i = new Image();
        i.src = $element.attr('href');
      }
      var j;
      if(filetype($element.attr('preview')) == 'image'){
        j = new Image();
        j.src = $element.attr('preview');
      }
    });
    
    if(categories.length > 0){
      if(categories.length > 1) categories.unshift('All');
      $menu = $('<div id="work_filter"></div>)').append('<span id="filter_label">View:</span>');
      
      $.each(categories, function(index, item){
        var filter_switch = $('<a href="#">'+item.replace(/_/, ' ')+'</a>');
        $menu.append(filter_switch);
        filter_switch.click(function(e){
          e.preventDefault();
          var filter = $(this);
          if(!filter.hasClass('current')){
            $menu.find('a').removeClass('current');
            filter.addClass('current');
            $('#work_sample_mask').fadeOut('fast', function(){
              if(item == 'All'){
                $('.work_preview')
                  .show().removeClass('off');
              }else{
                $('.work_preview')
                  .hide().addClass('off')
                  .filter('.'+item).removeClass('off').show();
              }
              profile.configurePages();
              profile.showWorkPage(0);
              $(this).fadeIn('normal');
            });
          }
        });
      });
      $menu.find('a:not(:last)').after('<span>&bull;</span>');
      
      profile.append($menu);
      $menu
        .find('a:first')
        .addClass('current');
    }
    
    return this;
  }
  
  $.fn.hasNext = function(){
    return this.parent().nextAll(':not(.off)').filter(':first').find('a').length > 0;
  }
  
  $.fn.hasPrev = function(){
    return this.parent().prevAll(':not(.off)').filter(':first').find('a').length > 0;
  }
  
  $.fn.nextWork = function(){
    var $next = this.parent().nextAll(':not(.off)').filter(':first').find('a').eq(0);
    if($next.length > 0) $next.showWork();
  }
  
  $.fn.previousWork = function(){
    var $prev = this.parent().prevAll(':not(.off)').filter(':first').find('a').eq(0);
    if($prev.length > 0) $prev.showWork();
  }
  
  var is_visible = function(thumb){
    var work = thumb.parent();
    if(work.position().top >= mask.height() - menu.position().top || work.position().top < -menu.position().top){
      return false;
    }else{
      return true;
    }
  }
  
  $.fn.showWorkPage = function(page, options){
    if(page < 0 || page > total_pages() - 1) return;
    if(!options) options = {};
    options = $.extend({
      duration: 'fast'
    }, options);
    menu.trigger('menu.page_will_change', [page]);
    menu.animate({
      'top': (mask.height() * -page) + 'px'
    }, options.duration, function(){
      menu.trigger('menu.page_changed', [page])
    });
  }
  
  $.fn.showWork = function(options, single){
    current = this;
    if(!single && !is_visible(current)){
      menu.one('menu.page_changed', function(){
        current.showWork(options, single);        
      }).showWorkPage(work_page(current));
      return;
    }
    var close_button = $("<span class='work_viewer_close_button'>close <strong>+</strong></span>");
    var title = $('<span class="work_viewer_title">' + this.attr('title') + '</span>');
    var player_controls = $('<span id="work_player_controls"><span id="play_button"></span><span id="pause_button"></span><span id="player_progress"><span id="load_progress"></span><span id="playback_progress"></span></span></span>');
    var player_container = $("<div id='work_player_container'></div>")
    var href = this.attr('href');
    var preview = this.attr('preview');
    var type = filetype(href);
    var slideshow_controls = $('<span id="work_player_slideshow_controls"><span id="prev_button">P</span><span id="next_button">N</span></span>');
    var slideshow_status = $('<span id="work_player_slideshow_status"></span>');
    viewer
      .one('viewer.init', function(){
        var src = (type == 'video') ? preview : href;
        viewer.append('<img id="player_preview_image" src="' + src + '" alt="' + title + '" style="width: 100%; height: 100%; position: absolute;" />');
        var timer;
        var img_loader = $('#player_preview_image').hide();
        if(img_loader[0].complete){
          img_loader.show();
        }else{
          timer = setInterval(function(){
            if(img_loader[0].complete){
              clearInterval(timer);
              img_loader.fadeIn('fast');
            }
          }, 30);
        }
      })
      .one('viewer.on', function(){
        viewer
          .append(close_button)
          .append(title)
          .append(player_controls)
          .append(slideshow_controls)
          .append(slideshow_status);
        slideshow_controls.css({
          'position' : 'absolute',
          'left' : '0',
          'bottom' : '-3px'
        }).hide();
        slideshow_status.css({
          'position' : 'absolute',
          'left' : '100px',
          'right' : '100px',
          'bottom' : '-1.5em',
          'text-align' : 'center'
        }).hide();
        player_controls.css({
          'position' : 'absolute',
          'bottom' : '-3px',
          'left' : '0',
          'cursor' : 'default'
        }).hide();
        close_button
          .css({
            'position' : 'absolute',
            'top' : '-1.5em',
            'right' : '0',
            'cursor' : 'pointer'
          })
          .one('click', function(e){
            e.preventDefault();
            $(this).lightsUp();
          });
        title.css({
          'position' : 'absolute',
          'bottom' : '-1.5em',
          'right' : '0'
        });
      
        viewer.append(player_container);
        //if it's a video, setup the video player
        if(type == 'video'){
          
          player_container.flash({
            src: '/flash/ChromelessPlayer.swf',
            width: viewer.width(),
            height: viewer.height(),
            wmode: 'transparent',
            background: '#000000',
            flashvars: {
              'video' : href,
              'width' : viewer.width(),
              'height' : viewer.height(),
              'auto_play' : 'yes',
              'guid' : video_listener.guid
            }
          });
          player_controls.show();
          $('#play_button').click(function(){
            $('#work_player_container').find('embed')[0].play();
          }).show();
          $('#pause_button').click(function(){
            $('#work_player_container').find('embed')[0].pause();
          }).hide();
          $(window).focus();
        }else if(type=='image'){
          var slides = current.parent().find('a');
          if(slides.length > 1){
            slideshow_status.text(current.slideIndex() + ' of ' + current.slideTotal()).show();
            slideshow_controls.show();
            slideshow_controls.find('#prev_button').click(function(){
              current.prevWorkSlide();
            });
            slideshow_controls.find('#next_button').click(function(){
              current.nextWorkSlide();
            });
          }
        }
      })
      .one('viewer.fade_out', function(){
        if(type=='video'){
          try{
            $('#work_player_container').find('embed')[0].pause();
          }catch(err){
            
          }
          $('#work_player_container').remove();
          player_container.remove();
        }
        player_controls.remove();
        title.remove();
        close_button.remove();
      })
      .one('viewer.off', function(){
        viewer.html('');
      });
      
    if(type=='image'){
      options = $.extend(options, {
        'auto_size_image' : href
      });
    }
    this.showViewer(options);
    return this;
    
  }
  
  $.fn.slideIndex = function(){
    return $.inArray(this[0], this.parent().find('a')) + 1;
  }
  
  $.fn.slideTotal = function(){
    return this.parent().find('a').length;
  }
  
  $.fn.changeSlide = function(){
    var $this = this;
    
    $('#player_preview_image').fadeOut('fast', function(){
      
      var loading = $('<div class="loading_spinner"></div>').appendTo(viewer).css({opacity:0.75});
      
      var tmp_img = new Image;
      $(tmp_img).load(function(){
        loading.remove();
        var options = {
          'width' : tmp_img.width,
          'height' : tmp_img.height,
          'top' : ($(document).scrollTop() + (minned(overlay.height() - tmp_img.height) / 2)) + 'px',
          'left' : ($(document).scrollLeft() + (minned(overlay.width() - tmp_img.width) / 2)) + 'px'
        };
        viewer.animate(options, 'fast');
        $('#player_preview_image').attr('src', $this.attr('href')).fadeIn('fast');
        $('#work_player_slideshow_status').text($this.slideIndex() + ' of ' + $this.slideTotal());
      });
      tmp_img.src = $this.attr('href');
      
    });
  }
  
  $.fn.nextWorkSlide = function(){
    var $this = $(this);
    var $a = $this.next('a');
    if($a.length > 0){
      current = $a;
      current.changeSlide();
    }
  }
  
  $.fn.prevWorkSlide = function(){
    var $this = $(this);
    var $a = $this.prev('a');
    if($a.length > 0){
      current = $a;
      $a.changeSlide()
    }
  }
  
  $.fn.showViewer = function(options){
    var $this = this;
        
    if(!options) options = {}
    options = $.extend({
      'width' : 640,
      'height' : 480
    }, options);
    
    if(options['auto_size_image']){
      var img = new Image();
      var loading = $('<div class="loading_spinner"></div>').appendTo($this.parent()).css({opacity:0.75});
      $(img).load(function(){
        loading.remove();
        $this.showViewer({
          width:this.width,
          height:this.height
        });
      });
      img.src = options['auto_size_image'];
      return;
    }
    
    var starting_css = {
      'top' : this.offset().top + 'px',
      'left' : this.offset().left + 'px',
      'width' : this.width() + 'px',
      'height' : this.height() + 'px',
      'opacity' : 0.5
    }
    
    var ending_css = {
      'top' : ($(document).scrollTop() + (minned(overlay.height() - options.height) / 2)) + 'px',
      'left' : ($(document).scrollLeft() + (minned(overlay.width() - options.width) / 2)) + 'px',
      'width' : options.width + 'px',
      'height' : options.height + 'px',
      'opacity' : 1
    }
    
    var resizer = function(e){
      viewer.css({
        'left' : ($(document).scrollLeft() + (minned(overlay.width() - viewer.width()) / 2)) + 'px',
        'top' : ($(document).scrollTop() + (minned(overlay.height() - viewer.height()) / 2)) + 'px'
      });
    }
    
    overlay.one('overlay.on', function(){
      viewer
        .trigger('viewer.init')
        .css(starting_css)
        .show()
        .animate(ending_css, 'fast', function(){
          viewer.trigger('viewer.on');
          $(window).bind('resize', resizer).bind('scroll', resizer);
        });
      overlay.one('overlay.fade_out', function(){
        viewer.trigger('viewer.fade_out');
        viewer.fadeOut('fast', function(){
          viewer.trigger('viewer.off')
          $(window).unbind('resize', resizer).bind('scroll', resizer);
        });
      })
    });
    this.lightsDown();
    return this;
  }
  
  var overlay_key_listener = function(e){
    if(e.which == 27 || e.which == 32){
      e.preventDefault();
      $(document).lightsUp();
    }
    if(e.which == 39){
      e.preventDefault();
      if(current.slideTotal() > 0 && current.slideIndex() != current.slideTotal()){
        current.nextWorkSlide();
      }else if(current.hasNext()){
        viewer.one('viewer.off', function(){
          current.nextWork();
        });
        overlay.trigger('overlay.fade_out');
      }
    }
    if(e.which == 37){
      e.preventDefault();
      if(current.slideTotal() > 0 && current.slideIndex() > 1){
        current.prevWorkSlide();
      }else if(current.hasPrev()){
        viewer.one('viewer.off', function(){
          current.previousWork();
        });
        overlay.trigger('overlay.fade_out');
      }
    }
  }
  
  $.fn.lightsUp = function(){
    
    var completed = function(){
      mode = 'off';
      overlay.trigger('overlay.off');
      $(document).unbind('keydown', overlay_key_listener);
    }
    if(mode == 'on'){
      overlay.trigger('overlay.fade_out');
      overlay.fadeOut(completed);      
    }else{
      completed();
    }
    return this;
  }
  
  // turn down the lights then let us know you're done
  $.fn.lightsDown = function(){
    var completed = function(){
      mode = 'on';
      overlay.trigger('overlay.on');
      $(document).bind('keydown', overlay_key_listener);
    }
    if(mode == 'off'){
      overlay.fadeIn('fast', completed);
    }else{
      completed();
    }
    return this;
  }
  
  
  $.fn.showSingleWork = function(){
    var $this = $(this);
    $this.prepareOverlay();
    $this.showWork({}, true);
  };
  
})(jQuery);

jQuery(document).ready(function(){
  var loader = new Image;
  loader.src = "/images/ajax-loader.gif";
  if(jQuery('.profile').length > 0){
    jQuery('.profile .work_samples a:first-child').workViewer();    
  }
});