var UploadLibrary = Class.create(
{
  initialize: function(container, url)
  {
    this.url = url;
    this.container = $(container);
    this.id = '_'+this.container.id;
    this.container.className = 'upload_library';
    this.container.update(
      '<div class="files">'+
        '<ul class="items">'+
        '</ul>'+
      '</div>'+
      '<div class="button_wrap">'+
        '<span id="upload'+this.id+'"></span>'+
      '</div>'+
      '<div class="progress_wrap">'+
        '<div class="progress"></div>'+
        '<div class="progress_text"></div>'+
      '</div>'+
      '<div style="clear: both"></div>'
    );
    this.ul_items = this.container.select('ul.items').first();;
    this.div_progress = this.container.select('div.progress').first();;
    this.progress_text = this.container.select('div.progress_text').first();;
    this.progress_text.update('loading...');

    this.swfu = new SWFUpload({
      upload_url: this.url+'?upload=1',
      flash_url: "lib/swfupload.swf",
      file_post_name: "filedata", 

      file_size_limit: "10 MB",
      file_types: "*.*",
      file_types_description: "All files",
      file_upload_limit: "0",

      swfupload_loaded_handler: this.swfUploadLoaded.bind(this), 
      file_dialog_start_handler: this.fileDialogStart.bind(this), 
      file_queued_handler: this.fileQueued.bind(this), 
      file_queue_error_handler: this.fileQueueError.bind(this),
      file_dialog_complete_handler: this.fileDialogComplete.bind(this),
      upload_start_handler: this.uploadStart.bind(this),
      upload_progress_handler: this.uploadProgress.bind(this),
      upload_error_handler: this.uploadError.bind(this),
      upload_success_handler: this.uploadSuccess.bind(this),
      upload_complete_handler: this.uploadComplete.bind(this),
      debug_handler: this.debug.bind(this),

      button_placeholder_id: "upload"+this.id,
      button_width: 50,
      button_height: 17,
      button_text: '<span class="button">Upload</span>',
      button_text_style: '.button { font-family: Helvetica, Arial, sans-serif; font-size: 12pt; }',
      button_text_top_padding: 0,
      button_text_left_padding: 0,
      button_window_mode: SWFUpload.WINDOW_MODE.TRANSPARENT,
      button_cursor: SWFUpload.CURSOR.HAND,

      minimum_flash_version: "9.0.28",
      swfupload_pre_load_handler: this.swfUploadPreLoad.bind(this),
      swfupload_load_failed_handler: this.swfUploadLoadFailed.bind(this),

      debug: false
    });

    this.renderContent();
  },

  /* media library API */

  rpc: function(method, cb)
  {
    new Ajax.Request(this.url+'?rpc=1', {
      method: 'post',
      requestHeaders: { Accept: 'application/json' },
      parameters: { jsonrpc: Object.toJSON({method: method, params: $A(arguments).slice(2)}) },
      onSuccess: this.rpcFinish.bind(this, cb)
    });
  },

  rpcFinish: function(cb, request)
  {
    var response = request.responseJSON;
    cb(response.retval);
  },

  renderContent: function()
  {
    this.rpc('getFiles', this.renderContentFinish.bind(this));
  },

  renderContentFinish: function(library)
  {
    this.ul_items.update('');
    $A(library).each(function(i) {
      var item = $(document.createElement('li'));
      item.appendChild(document.createTextNode(i.name));
      item.file = i;
      this.ul_items.appendChild(item);
      item.observe('mouseover', this.onItemMouseover.bindAsEventListener(this, item));
      item.observe('mouseout', this.onItemMouseout.bindAsEventListener(this, item));
      item.observe('click', this.onItemClick.bindAsEventListener(this, item));
    }, this);

    this.div_progress.style.width = '0%';
    this.progress_text.update('&lt;- select files for upload');
  },

  /* overridable hooks */

  onItemMouseover: function(event, item)
  {
    item.addClassName('hover');
  },

  onItemMouseout: function(event, item)
  {
    item.removeClassName('hover');
  },

  onItemClick: function(event, item)
  {
  },

  onError: function(message)
  {
    alert(message);
  },

  /* {{{ swfupload library hooks */

  swfUploadLoaded: function()
  {
  },

  fileDialogStart: function()
  {
  },

  fileQueued: function(file)
  {
  },

  fileQueueError: function(file, errorCode, message)
  {
    this.onError(message);
  },

  fileDialogComplete: function(numFilesSelected, numFilesQueued)
  {
    if (numFilesQueued > 0)
      this.swfu.startUpload();
  },

  uploadStart: function(file)
  {
    return true; // continue upload
  },

  uploadProgress: function(file, bytesLoaded)
  {
    var percent = Math.ceil((bytesLoaded / file.size) * 100);
    this.div_progress.style.width = percent + '%';
    this.progress_text.update(file.name.truncate(12) + ' (' + percent + ' %)');
  },

  uploadError: function(file, errorCode, message)
  {
    this.onError('Upload error '+file.name+': '+message);
  },

  uploadSuccess: function(file, serverData)
  {
    if (serverData != '[SUCCESS]')
      this.onError('ERROR: '+serverData);
  },

  uploadComplete: function(file)
  {
    if (this.swfu.getStats().files_queued > 0)
      this.swfu.startUpload();
    if (this.swfu.getStats().files_queued == 0)
      this.renderContent();
  },

  debug: function(msg)
  {
    //console.log(msg);
  },

  swfUploadPreLoad: function()
  {
    // berfore trying to load swfupload
  },

  swfUploadLoadFailed: function()
  {
    // flash load failed
    this.onError('ERROR: You need Adobe Flash to upload files. Get it at: http://get.adobe.com/flashplayer/');
  }

  /* }}} */
});
