var PortfolioViewer = new Class({

  options: {
    interval: 6000,
    cat_duration: 1000,
    item_duration: 1500
  },

  categories: [],
  current_category: null,
  current_item: [],
  tabs: [],
  nav_numbers: [],
  last_category: null,
  last_item: [],
  pending_id: null,
  containers_fx: [],
  numbers_fx: [],
  pitems_fx: [],
  preload_images: null,
  image_preload: [],
  item_timeout: null,

  initialize: function(categories, category_id, item_id)
  {
    this.categories = categories;
    this.preloadImages();

    this.current_category = category_id;

    if (!this.current_category) {
      this.current_category = 0;
    }
    this.current_item[this.current_category] = item_id;
    if (!this.current_item[this.current_category]) {
      this.current_item[this.current_category] = 0;
    }

    // create fx and add events for containers, items, tabs and numbers
    this.categories.each(function(items, index) {
      var container = $('portfolio_items_'+index);
      var numbers = $('portfolio_nav_'+index);
      this.containers_fx[index] = new Fx.Tween(container, {duration: this.options.cat_duration});
      this.numbers_fx[index] = new Fx.Tween(numbers, {duration: this.options.cat_duration});
      this.tabs[index] = $('portfolio_tab_'+index);
      this.tabs[index].addEvent('click', function(e) {
        e = new Event(e).stop();
        var ids = e.target.getAttribute('id').split('_');
        this.showCategory(parseInt(ids[2]));
      }.bind(this));

      this.pitems_fx[index] = [];
      this.nav_numbers[index] = [];
      items.each(function(item, item_index) {
        var item_wrapper = $('portfolio_item_'+index+'_'+item_index);
        this.pitems_fx[index][item_index] = new Fx.Tween(item_wrapper, {duration: this.options.item_duration});
        this.nav_numbers[index][item_index] = $('portfolio_nav_item_'+index+'_'+item_index);
        this.nav_numbers[index][item_index].addEvent('click', function(e) {
          e = new Event(e).stop();
          var ids = e.target.getAttribute('id').split('_');
          this.showItem(parseInt(ids[4]));
        }.bind(this))

      }.bind(this));
    }.bind(this));

    this.showCategory(this.current_category);

  },

  showCategory: function(category_id)
  {
    if (category_id != this.current_category)
    {
      // hide the previous category
      this.containers_fx[this.current_category].cancel();
      this.containers_fx[this.current_category].start('opacity', 0);
      this.numbers_fx[this.current_category].cancel();
      this.numbers_fx[this.current_category].start('opacity', 0);

      // show the new category
      this.containers_fx[category_id].cancel();
      this.containers_fx[category_id].start('opacity', 1);
      this.numbers_fx[category_id].cancel();
      this.numbers_fx[category_id].start('opacity', 1);

      this.last_category = this.current_category;
      this.current_category = category_id;

      this.tabs[this.last_category].removeClass('selected');
      this.tabs[this.current_category].addClass('selected');

      if (!this.current_item[this.current_category]) {
        this.current_item[this.current_category] = 0;
      }
    }
    this.showItem(this.current_item[this.current_category]);
  },

  showItem: function(item_id)
  {
    clearTimeout(this.item_timeout);
    this.item_timeout = null;

    if ($chk(this.pending_id)) {
      item_id = this.pending_id;
    }

    // make sure the image is loaded
    if (!$chk(this.image_preload[this._image_index(item_id)])) {
      if (this.pending_id == null) {
        this.pending_id = item_id;
        $('portfolio_item_'+this.current_category+'_'+item_id).setStyle('visibility', 'hidden');
      }
      this.item_timeout = setTimeout(this.showItem.bind(this), 100);
    }
    // don't change it if they want to see the same one
    else {
      this.pending_id = null;
      if (!$chk(this.last_item[this.current_category]) || item_id != this.current_item[this.current_category]) {

        this.pitems_fx[this.current_category][this.current_item[this.current_category]].cancel();
        this.pitems_fx[this.current_category][this.current_item[this.current_category]].start('opacity', 0);
        this.nav_numbers[this.current_category][this.current_item[this.current_category]].removeClass('selected');

        if (this.pitems_fx[this.current_category][item_id]) {
          this.pitems_fx[this.current_category][item_id].cancel();
        }
        this.pitems_fx[this.current_category][item_id].start('opacity', 0, 1);

        this.last_item[this.current_category] = this.current_item[this.current_category];
        this.current_item[this.current_category] = item_id;

        this.nav_numbers[this.current_category][this.current_item[this.current_category]].addClass('selected');

      }

      // show the next image automatically if we have more than 1
      if (this.categories[this.current_category].length > 1) {
        this.item_timeout = setTimeout(this.nextItem.bind(this), this.options.interval);
      }
    }
  },

  nextItem: function()
  {
    // work out the next item to show
    var next_id = this.current_item[this.current_category]+1;
    if (next_id == this.categories[this.current_category].length) {
      next_id = 0;
    }
    this.showItem(next_id);
  },

  preloadImages: function()
  {
    var img_array = [];
    this.categories.each(function(items) {
      img_array.combine(items);
    });
    this.preload_images = new Asset.images(img_array, {
      onProgress: function(counter, index) {
        this.image_preload[index] = true;
      }.bind(this)
    });

  },

  _image_index: function(item_id)
  {
    var idx = item_id;
    for (var i = 0; i < this.current_category; i++) {
      idx += this.categories[i].length;
    }
    return idx;
  }

});
PortfolioViewer.implement(new Options);

