Abstract.Clipboard = Class.create({
  initialize: function() {},
  
  copy: function() {},
  
  track: function(element) {
    trackClick("/characters/" + element.innerHTML.unescapeHTML());
  }
})

var Flash9Clipboard = Class.create(Abstract.Clipboard, {
  initialize: function($super) {
    this.VERSION = "9";
    this.id = '_clipboard';
    this.observe();
    $super();
  },
  
  create: function() {
    $(document.body).insert(new Element('div', {
      id: this.id, style: 'position: absolute; left: -999px; top: -999px'
    }));
  },
  
  observe: function() {
    $(document.body).observe('click', function(event) {
      var target = $(event.target);

      if (target.match('#contents span')) {
        event.stop();
        copyBuffer[event.altKey ? 'pushAndNotify' : 'replace'](event.element());
        this.track(event.target);
      }

      else if (target.match('#text_html_toggler')) {
        event.stop();
        target.toggleValue();
      }
    }.bind(this));
  },
  
  copy: function(string) {
    if (!$(this.id)) this.create();
    $(this.id).update(this._flashEmbedHTML(string));
  },
  
  _flashEmbedHTML: function(string) {
    return '<embed src="flash/clipboard.swf" FlashVars="clipboard=' + encodeURIComponent(string) + 
      '" width="0" height="0" type="application/x-shockwave-flash"></embed>';
  }
});

var Flash10Clipboard = Class.create(Abstract.Clipboard, {
  initialize: function($super) {
    this.VERSION = "10";
    this.create();
    this.embed.bind(this).defer();
    this.observe();
    $super();
  },
  
  create: function() {
    $(document.body).insert({ 
      bottom: new Element('div', { id: 'copy_button' }).
        setStyle('position: absolute; left: -99px; top: -99px; width: 1px; height: 1px;').
        update('<div id="copy_button_flash"></div>') 
    });
  },
  
  embed: function() {
    var params = { allowScriptAccess: "always", wmode: 'transparent', scale: 'exactfit' };
    swfobject.embedSWF('flash/copy_button.swf?1.1', 'copy_button_flash', '1', '1', '8', null, {}, params, {});
  },
  
  observe: function() {
    $("nav").observe('mouseover', this.onNavigationMouseOver.bind(this));
    $('contents').observe('mouseover', this.onContentsMouseOver.bind(this));
    $('nav').observe('mouseout', function(event) {
      $('text_html_toggler', 'clear_buffer').invoke('removeClassName', 'hover');
    })
  },

  onNavigationMouseOver: function(event) {
    var element;
    if (!((element = event.findElement('#formats')) || (element = event.findElement('#clear_buffer')))) return;
    this.mouseoverElement = element;
    this.positionizeCopyButton();
  },
  
  onContentsMouseOver: function(event) {
    var element;
    if (!(element = event.findElement('span'))) return;
    this.mouseoverElement = element;
    this.positionizeCopyButton();
  },
  
  positionizeCopyButton: function() {
    var flashElement, source = this.mouseoverElement, position = source.cumulativeOffset();
    
    $('copy_button').setStyle({ left: position.left.px(), top: position.top.px() });
    
    if (flashElement = $('copy_button_flash')) {
      flashElement.width  = source.getWidth();
      flashElement.height = source.getHeight();
    }
  },
  
  // These are called from within flash when the button receives rollOver and rollOut events
  onFlashButtonOver: function() {
    var element;
    if (!(element = this.mouseoverElement.downwards('a'))) return;
    element.addClassName('hover');
  },

  onFlashButtonOut: function() {
    var element;
    if (!(element = this.mouseoverElement.downwards('a'))) return;
    element.removeClassName('hover');
  },
  
  textToCopy: function(altKey) {
    var element = Clipboard.mouseoverElement;
    
    if (element == $('formats'))
      $('text_html_toggler').toggleValue();
    else if (element == $('clear_buffer'))
      copyBuffer.handleClear(); 
    else {
      copyBuffer[altKey ? 'pushAndNotify' : 'replace'](element);
      this.track(element);
    }
    
    return copyBuffer.toString();
  }
});

var IEClipboard = Class.create(Abstract.Clipboard, {
  initialize: function($super) {
    this.VERSION = "IE";
    $super();
  },
  
  copy: function(string) {
    window.clipboardData.setData('Text', string);
  }
});

var Clipboard = new ((function() {
  var ie = Prototype.Browser.IE, location = window.location.href, 
    version = swfobject.getFlashPlayerVersion().major;
  if (ie && location.startsWith('file://'))      return IEClipboard;
  else if (location.include('?flashversion=9'))  return Flash9Clipboard;
  else if (location.include('?flashversion=10')) return Flash10Clipboard;
  //else if (version < 10)                       return Flash9Clipboard;
  else                                           return Flash10Clipboard;
})())();
