/*

The MIT License (MIT)
Copyright (c) 2012 Jon Rohan, James M. Greene, 

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/

// Simple Set Clipboard System
// Author: Joseph Huckaby

var ZeroClipboard = {
  
  version: "1.0.7",
  clients: {}, // registered upload clients on page, indexed by id
  moviePath: 'ZeroClipboard.swf', // URL to movie
  nextId: 1, // ID of next movie
  
  $: function(thingy) {
    // simple DOM lookup utility function
    if (typeof(thingy) == 'string') thingy = document.getElementById(thingy);
    if (!thingy.addClass) {
      // extend element with a few useful methods
      thingy.hide = function() { this.style.display = 'none'; };
      thingy.show = function() { this.style.display = ''; };
      thingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };
      thingy.removeClass = function(name) {
        var classes = this.className.split(/\s+/);
        var idx = -1;
        for (var k = 0; k < classes.length; k++) {
          if (classes[k] == name) { idx = k; k = classes.length; }
        }
        if (idx > -1) {
          classes.splice( idx, 1 );
          this.className = classes.join(' ');
        }
        return this;
      };
      thingy.hasClass = function(name) {
        return !!this.className.match( new RegExp("\\s*" + name + "\\s*") );
      };
    }
    return thingy;
  },
  
  setMoviePath: function(path) {
    // set path to ZeroClipboard.swf
    this.moviePath = path;
  },
  
  dispatch: function(id, eventName, args) {
    // receive event from flash movie, send to client    
    var client = this.clients[id];
    if (client) {
      client.receiveEvent(eventName, args);
    }
  },
  
  register: function(id, client) {
    // register new client to receive events
    this.clients[id] = client;
  },
  
  getDOMObjectPosition: function(obj, stopObj) {
    // get absolute coordinates for dom element
    var info = {
      left: 0, 
      top: 0, 
      width: obj.width ? obj.width : obj.offsetWidth, 
      height: obj.height ? obj.height : obj.offsetHeight
    };

    while (obj && (obj != stopObj)) {
      info.left += obj.offsetLeft;
      info.top += obj.offsetTop;
      obj = obj.offsetParent;
    }

    return info;
  },
  
  Client: function(elem) {
    // constructor for new simple upload client
    this.handlers = {};
    
    // unique ID
    this.id = ZeroClipboard.nextId++;
    this.movieId = 'ZeroClipboardMovie_' + this.id;
    
    // register client with singleton to receive flash events
    ZeroClipboard.register(this.id, this);
    
    // create movie
    if (elem) this.glue(elem);
  }
};

ZeroClipboard.Client.prototype = {
  
  id: 0, // unique ID for us
  ready: false, // whether movie is ready to receive events or not
  movie: null, // reference to movie object
  clipText: '', // text to copy to clipboard
  handCursorEnabled: true, // whether to show hand cursor, or default pointer cursor
  cssEffects: true, // enable CSS mouse effects on dom container
  handlers: null, // user event handlers
  
  glue: function(elem, appendElem, stylesToAdd) {
    // glue to DOM element
    // elem can be ID or actual DOM element object
    this.domElement = ZeroClipboard.$(elem);
    
    // float just above object, or zIndex 99 if dom element isn't set
    var zIndex = 99;
    if (this.domElement.style.zIndex) {
      zIndex = parseInt(this.domElement.style.zIndex, 10) + 1;
    }
    
    if (typeof(appendElem) == 'string') {
      appendElem = ZeroClipboard.$(appendElem);
    }
    else if (typeof(appendElem) == 'undefined') {
      appendElem = document.getElementsByTagName('body')[0];
    }
    
    // find X/Y position of domElement
    var box = ZeroClipboard.getDOMObjectPosition(this.domElement, appendElem);
    
    // create floating DIV above element
    this.div = document.createElement('div');
    var style = this.div.style;
    style.position = 'absolute';
    style.left = '' + box.left + 'px';
    style.top = '' + box.top + 'px';
    style.width = '' + box.width + 'px';
    style.height = '' + box.height + 'px';
    style.zIndex = zIndex;

    style.left = '0px';
    style.top = '0px';
    
    if (typeof(stylesToAdd) == 'object') {
      for (addedStyle in stylesToAdd) {
        style[addedStyle] = stylesToAdd[addedStyle];
      }
    }
    
    // style.backgroundColor = '#f00'; // debug
    
    appendElem.appendChild(this.div);
    
    this.div.innerHTML = this.getHTML( box.width, box.height );
  },
  
  getHTML: function(width, height) {
    // return HTML for movie
    var html = '';
    var flashvars = 'id=' + this.id + 
      '&width=' + width + 
      '&height=' + height;
      
    if (navigator.userAgent.match(/MSIE/)) {
      // IE gets an OBJECT tag
      var protocol = location.href.match(/^https/i) ? 'https://' : 'http://';
      html += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="'+width+'" height="'+height+'" id="'+this.movieId+'" align="middle"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="false" /><param name="movie" value="'+ZeroClipboard.moviePath+'" /><param name="loop" value="false" /><param name="menu" value="false" /><param name="quality" value="best" /><param name="bgcolor" value="#ffffff" /><param name="flashvars" value="'+flashvars+'"/><param name="wmode" value="transparent"/></object>';
    }
    else {
      // all other browsers get an EMBED tag
      html += '<embed id="'+this.movieId+'" src="'+ZeroClipboard.moviePath+'" loop="false" menu="false" quality="best" bgcolor="#ffffff" width="'+width+'" height="'+height+'" name="'+this.movieId+'" align="middle" allowScriptAccess="always" allowFullScreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="'+flashvars+'" wmode="transparent" />';
    }
    return html;
  },
  
  hide: function() {
    // temporarily hide floater offscreen
    if (this.div) {
      this.div.style.left = '-2000px';
    }
  },
  
  show: function() {
    // show ourselves after a call to hide()
    this.reposition();
  },
  
  destroy: function() {
    // destroy control and floater
    if (this.domElement && this.div) {
      this.hide();
      this.div.innerHTML = '';
      
      var body = document.getElementsByTagName('body')[0];
      try { body.removeChild( this.div ); } catch(e) {;}
      
      this.domElement = null;
      this.div = null;
    }
  },
  
  reposition: function(elem) {
    // reposition our floating div, optionally to new container
    // warning: container CANNOT change size, only position
    if (elem) {
      this.domElement = ZeroClipboard.$(elem);
      if (!this.domElement) this.hide();
    }

    console.debug( this.domElement, this.div );
    
    if (this.domElement && this.div) {
      var box = ZeroClipboard.getDOMObjectPosition(this.domElement);
      console.debug( box );
      var style = this.div.style;
      style.left = '' + box.left + 'px';
      style.top = '' + box.top + 'px';
    }
  },
  
  setText: function(newText) {
    // set text to be copied to clipboard
    this.clipText = newText;
    if (this.ready) this.movie.setText(newText);
  },
  
  addEventListener: function(eventName, func) {
    // add user event listener for event
    // event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel
    eventName = eventName.toString().toLowerCase().replace(/^on/, '');
    if (!this.handlers[eventName]) this.handlers[eventName] = [];
    this.handlers[eventName].push(func);
  },
  
  setHandCursor: function(enabled) {
    // enable hand cursor (true), or default arrow cursor (false)
    this.handCursorEnabled = enabled;
    if (this.ready) this.movie.setHandCursor(enabled);
  },
  
  setCSSEffects: function(enabled) {
    // enable or disable CSS effects on DOM container
    this.cssEffects = !!enabled;
  },
  
  receiveEvent: function(eventName, args) {
    // receive event from flash
    eventName = eventName.toString().toLowerCase().replace(/^on/, '');
        
    // special behavior for certain events
    switch (eventName) {
      case 'load':
        // movie claims it is ready, but in IE this isn't always the case...
        // bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function
        this.movie = document.getElementById(this.movieId);
        if (!this.movie) {
          var self = this;
          setTimeout( function() { self.receiveEvent('load', null); }, 1 );
          return;
        }
        
        // firefox on pc needs a "kick" in order to set these in certain cases
        if (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {
          var self = this;
          setTimeout( function() { self.receiveEvent('load', null); }, 100 );
          this.ready = true;
          return;
        }
        
        this.ready = true;
        this.movie.setText( this.clipText );
        this.movie.setHandCursor( this.handCursorEnabled );
        break;
      
      case 'mouseover':
        if (this.domElement && this.cssEffects) {
          this.domElement.addClass('hover');
          if (this.recoverActive) this.domElement.addClass('active');
        }
        break;
      
      case 'mouseout':
        if (this.domElement && this.cssEffects) {
          this.recoverActive = false;
          if (this.domElement.hasClass('active')) {
            this.domElement.removeClass('active');
            this.recoverActive = true;
          }
          this.domElement.removeClass('hover');
        }
        break;
      
      case 'mousedown':
        if (this.domElement && this.cssEffects) {
          this.domElement.addClass('active');
        }
        break;
      
      case 'mouseup':
        if (this.domElement && this.cssEffects) {
          this.domElement.removeClass('active');
          this.recoverActive = false;
        }
        break;
    } // switch eventName
    
    if (this.handlers[eventName]) {
      for (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {
        var func = this.handlers[eventName][idx];
      
        if (typeof(func) == 'function') {
          // actual function reference
          func(this, args);
        }
        else if ((typeof(func) == 'object') && (func.length == 2)) {
          // PHP style object + method, i.e. [myObject, 'myMethod']
          func[0][ func[1] ](this, args);
        }
        else if (typeof(func) == 'string') {
          // name of function
          window[func](this, args);
        }
      } // foreach event handler defined
    } // user defined handler for event
  }
  
};
