/* Delegate */
var slice = Array.prototype.slice;
function update(array, args) {
  var arrayLength = array.length, length = args.length;
  while (length--) array[arrayLength + length] = args[length];
  return array;
}
function merge(array, args) {
  array = slice.call(array, 0);
  return update(array, args);
}
$.extend(Function.prototype, {
  attach: function(context) {
    var __method = this, args = slice.call(arguments, 1);
    return function() {
      var a = merge(args, arguments);
      return __method.apply(context, a);
    }
  }
});

/* jQuery random element */
jQuery.jQueryRandom = 0;
jQuery.extend(jQuery.expr[":"], {
  random: function(a, i, m, r) {
    if (i == 0) {
      jQuery.jQueryRandom = Math.floor(Math.random() * r.length);
    };
    return i == jQuery.jQueryRandom;
  }
});

/* States */
var STATE = {
  ACTIVE: 'active',
  DYNAMIC: '_dynamic',
  COLLAPSED: 'collapsed',
};

/**
 * folio 
 **/
var folio = Class.create({
  init: function()
  {
	// make external links
	$("a[rel='external']").attr('target', '_blank');
	
	// setup
    folio.setup_lazyload();
    folio.setup_tools();
    folio.setup_projects();
    folio.setup_forms();
  },
  project_form: null,
  setup_lazyload: function()
  {
    $("#content div.in-line img").lazyload({         
      threshold : -100,
      placeholder : "/images/white.gif",
      effect: "fadeIn",
    });
  },
  setup_forms: function()
  {
    var project_form = $('div#project_index form.project');
    if (project_form.size()) folio.project_form = new folio.ProjectForm(project_form);
    
    // find extra asset forms
    $("form.asset").each(function() {
      if (! $(this).data('form')) {
        // create new form
        new folio.AssetForm(this);
      }
    })
  },
  setup_tools: function()
  {
    $("a#add_project_button").bind('click', function(e) {
      e.preventDefault();
      folio.project_form.toggle_view();
    });
    if (! $("#wrapper").hasClass('sub_level')) {
      $('h1#site_name a').bind('click', function(e) {
        e.preventDefault();
        folio.open_info(e);
      });
    }
    $('p.add_asset a').bind('click', function(e) {
      e.preventDefault();
      // alert(1);
      $(e.target).closest('div.project').find('form.asset').show();
      $(e.target).hide();
    })
  },
  setup_projects: function()
  {
    $("div.project").each(function() {
      new folio.Project(this);
    });
  },
  info: null,
  info_loading: false,
  // info_loaded: false,
  open_info: function(e)
  {
    if (this.info_loading) return;
    if (! this.info) {
      this.info_loading = true;
      $("#project_index").toggle();
      $("#tools").toggle();
      $.ajax({
        url: '/info',
        success: folio.attach_info.attach(this),
      });
    } else {
      $("#project_index").toggle();
      $("#tools").toggle();
      this.info.toggle();
    }
  },
  attach_info: function(responseText)
  {
    this.info_loading = false;
    this.info = $(responseText).find('#_info');
    $("#content").append(this.info);
  },
}, true);

/**
 * Form 
 **/
folio.create('Form', {
  className: 'Form',
  element: null,
  showing: false,
  css_display: null,
  init: function(element)
  {
    // get element
    this.element = $(element);
    
    // save object on element
    this.element.data('form', this);
    
    // get display
    this.css_display = this.element.css('display');
    
    // set dynamic state
    this.element.addClass(STATE.DYNAMIC);
    this.showing = this.element.css('display') != 'none';
    
    // setup
    this._setup();
    // this._setup_ajax();
  },
  _setup: function()
  {
    if (this.setup) this.setup();
  },
  _setup_ajax: function()
  {
    this.element.bind('submit', this._handle_submit.attach(this));
    if (this.setup_ajax) this.setup_ajax();
  },
  _handle_submit: function(e)
  {
    e.preventDefault();
    if (this.check()) {
      $.ajax({
        url: this.element.attr('action'),
        method: this.element.attr('method'),
        data: this.element.serialize(),
        success: this.handle_success.attach(this),
      });
    }
  },
  check: function()
  {
    return true;
  },
  _handle_success: function(response)
  { 
    if (this.handle_success)
      this.handle_success(response);
  },
  toggle_view: function()
  {
    if (this.showing) {
      this.showing = false;
      this.element.css({display: null});
    } else {
      this.showing = true;
      this.element.css({display: this.css_display});
    }
  },
});

/**
 * Project Form 
 **/
folio.ProjectForm = Class.create(folio.Form.prototype, {
  className: 'ProjectForm',
  setup: function() {
    //
  },
});

/**
 * Asset Form 
 **/
folio.AssetForm = Class.create(folio.Form.prototype, {
  className: 'AssetForm',
  setup: function() {
    //
    this.element.find('div.type label').bind('click', this.toggle_type.attach(this));
  },
  toggle_type: function(e)
  {
    if ($(e.target).attr('nodeName').toLowerCase() == 'input') {
      this.element.find('div.type label').removeClass(STATE.ACTIVE);
      $(e.target).closest('label').addClass(STATE.ACTIVE);
    }
  },
});

/**
 * Project
 **/
folio.create('Project', {
  className: 'Project',
  element: null,
  asset_form: null,
  assets: null,
  asset_collection: null,
  current_asset_index: 1,
  init: function(element)
  {
    // get element
    this.element = $(element);
    
    // initate with collapsed state
    this.element.addClass(STATE.COLLAPSED);
    
    // setup
    this._setup();
  },
  _setup: function()
  {
    // setup form
    this.asset_form = new folio.AssetForm(this.element.find('form.asset'));
    
    //
    if (this.asset_form.element.size()) {
      this.element.find('div.header p.tools').append(' <a href="#add_asset" class="add_asset_link">Add asset</a>');
      this.element.find('a.add_asset_link').bind('click', this.toggle_asset_form.attach(this));
    }
    
    // setup description toggle
    this.element.find('h3 a.title').bind('click', this.toggle_click_handler.attach(this));
    
    // setup sortable
    this.element.find('div.sortable').sortable({
      handle: 'img',
      tolerance: 'pointer',
      update: this.sort_update_handler.attach(this),
    });
    
    // setup slideshows
    this.asset_collection = this.element.find('div.asset_collection');
    if (! this.asset_collection.hasClass('sortable')) {
      this.assets = this.element.find('div.asset');
      if (this.asset_collection.hasClass('click-through') && this.assets.size() > 1) {
        this.maximize_assets_holder();
        this.isolate_asset(1);
        this.setup_click_through();
      } else if (this.asset_collection.hasClass('ticker') && this.assets.size() > 1) {
        this.maximize_assets_holder();
        this.isolate_asset(1);
        this.setup_ticker();
      }
    }
  },
  maximize_assets_holder: function()
  {
    var mW=mH=0;
    if (this.assets.size()) {
      this.assets.each(function() {
        var eW = $(this).outerWidth();
        var eH = $(this).outerHeight();
        if (eW > mW) mW = eW;
        if (eH > mH) mH = eH;
      });
    }
    this.asset_collection.css({
      width: mW+'px',
      height: mH+'px',
    });
  },
  setup_click_through: function() {
    this.asset_collection
	  .addClass('no-cursor')
      .bind('click', this.handle_asset_click.attach(this))
      .bind('mouseenter', this.handle_asset_mouseenter.attach(this))
      .bind('mouseleave', this.handle_asset_mouseleave.attach(this))
      .bind('mousemove', this.handle_asset_mousemove.attach(this));
    // this.asset_collection.append('<div class="log"></div>')
  },
  ticker_interval: null,
  ticker_speed: 2000,
  setup_ticker: function()
  {
    // find ticker speed
    var ms_search = this.asset_collection.attr('className').match(/ts-([0-9]+)/);
    if (ms_search && ms_search[1]) this.ticker_speed = ms_search[1];
    
    //
    this.tick();
  },
  tick: function()
  {
    if (! this.ticker_interval) this.ticker_interval = setInterval(this.tick.attach(this), this.ticker_speed);
    else this.next();
  },
  handle_asset_click: function(e)
  {
    // this.next();
    var o = this.asset_collection.offset();
    var x_offset = e.pageX - o.left;
    // var y_offset = e.pageY - o.top;
    
    if (x_offset > this.asset_collection.width()/2) {
      this.next();
    } else {
      this.prev();
    }
  },
  handle_asset_mouseenter: function(e) {
    this.handle_asset_mousemove(e);
  },
  handle_asset_mouseleave: function(e) {
    $('#prev-cursor, #next-cursor').hide();
  },
  handle_asset_mousemove: function(e) {
    var o = this.asset_collection.offset();
    var pageX = e.pageX;
    var pageY = e.pageY;
	var x_offset = pageX - o.left;
    
    if (x_offset > this.asset_collection.width()/2) {
      $('#prev-cursor').hide();
      $('#next-cursor')
        .show()
        .css({
          left: pageX-2,
          top: pageY,
        });
      this.asset_collection
        .attr('title', 'Click for next image');
    } else {
      $('#next-cursor').hide();
      $('#prev-cursor')
        .show()
        .css({
          left: pageX+2,
          top: pageY,
        });
      this.asset_collection
        .attr('title', 'Click for previous image');
    }
  },
  next: function()
  {
    this.current_asset_index++;
    if (this.current_asset_index > this.assets.size()) this.current_asset_index = 1;
    this.isolate_asset(this.current_asset_index);
  },
  prev: function()
  {
    this.current_asset_index--;
    if (this.current_asset_index < 1) this.current_asset_index = this.assets.size();
    this.isolate_asset(this.current_asset_index);
  },
  isolate_asset: function(num)
  {
    this.asset_collection.find('div.asset').hide();
    this.asset_collection.find('div.asset:nth-child('+num+')').show();
  },
  toggle_asset_form: function(e)
  {
    e.preventDefault();
    this.asset_form.toggle_view();
  },
  toggle_click_handler: function(e)
  {
    e.preventDefault();
    
    // toggle collapsed state
    this.element.toggleClass(STATE.COLLAPSED);
  },
  hide_interval: null,
  sort_update_handler: function(e, ui)
  {
    // alert(e.target);
    var order = this.element.find('div.sortable').sortable('serialize'); 
    this.element.find('div.info').load('/projects/updateassetorder/'+this.element.attr('id')+'?'+order).fadeIn(100);
    if (this.hide_interval) clearInterval(this.hide_interval);
    this.hide_interval = setInterval(this.hide_info.attach(this), 2500);
  },
  hide_info: function()
  {
    clearInterval(this.hide_interval);
    this.element.find('div.info').fadeOut(150);
  },
});

/* On load: init folio */
$(folio.init);
