(function(){
/** 
 * This notice must be included in your future own implementations.
 * 
 *     simple mouse tracking v. 1.1.4 replay mode (smt_replay.js)
 *     Last modified: April 24nd 2008
 * 
 * Copyleft (cc) 2006-2008 Luis Leiva.
 * see http://smt.speedzinemedia.com for more details
 * 
 * License: LGPL
 * 
 * This script is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License (LGPL) as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 */

// (smt) default options ------------------------------------------------------- 
var smt_options = {
  realTime: false,                                // static or dynamic mouse replay
  entryPt:  "#690",                               // entry point color
  exitPt:   "#C66",                               // exit point color
  regPt:    "#AAA",                               // registration points color 
  regLn:    "#888",                               // lines color
  regClick: "maroon",                             // clicks color
  varCir:   "teal",                               // time-depending circles
  cenPt:    "#DDD",                               // centroid
  zIndex:   1,                                    // depth of (smt) system layer
  directionVector: false,                         // show direction vector (useful if realTime: false)
  bgLayer:  false                                 // draw background layer
};

// (smt) replay system definition ----------------------------------------------
var smt_replay = {
  i: 0,                               // mouse tracking global counter var
  j: 1,                               // registration points size global counter var
  j_max: 200,                         // registration points size limit in pixels (diameter * 2)
  play: null,                         // mouse tracking identifier
  jg:   null,                         // canvas area for drawing

  getWindowSize: function(dim) {
    var w = document.documentElement.clientWidth  || document.body.clientWidth;   
    var h = document.documentElement.clientHeight || document.body.clientHeight;
    
    return (dim == "width") ? w : h;
  },

  getDocumentSize: function(dim) {
    var w = document.body.scrollWidth  || document.documentElement.offsetWidth;
    var h = document.body.scrollHeight || document.documentElement.offsetHeight;
    // if the document's height is above the fold, we use the window height instead
    var f = smt_replay.getWindowSize("height");
    if (h < f) h = f;

    return (dim == "width") ? w : h;
  },

  createCanvas: function(layer) {
    var jg    = document.createElement("div");
        jg.id                     = layer;
        jg.style.position         = "absolute";
        jg.style.top              = 0;
        jg.style.left             = 0;
        jg.style.width            = 0 + '%';
        jg.style.height           = 0 + '%';
        jg.style.zIndex           = smt_options.zIndex;
        
    var body  = document.getElementsByTagName("body")[0];
        body.appendChild(jg);
    // set the canvas area for drawing
    smt_replay.jg = new jsGraphics(layer);
  },
  
  setBgCanvas: function(layer) {
    // background layer color
    var bgColor = "#FFFFFF";
    // background layer opacity (%)
    var opacity = 60;
    // you can add some pixels to match scrollbars, depending on your browser and page's layout design
    var offset  = 0;
    // layer size                                   
    var w = smt_replay.getDocumentSize("width")  + offset + 'px';
    var h = smt_replay.getDocumentSize("height") + offset + 'px';
    
    var jg    = document.getElementById(layer);
    var depth = jg.style.zIndex;
    
    var bg    = document.createElement("div");
        bg.id                     = layer + "Bg";
        bg.style.position         = "absolute";
        bg.style.top              = 0;
        bg.style.left             = 0;
        bg.style.width            = w;
        bg.style.height           = h;
        bg.style.overflow         = "hidden";
        bg.style.backgroundColor  = "#666";
        bg.style.opacity          = opacity/100; // for W3C browsers
        bg.style.filter           = "alpha(opacity="+opacity+")"; // only for IE
        bg.style.zIndex           = depth - 1;
    
    var body  = document.getElementsByTagName("body")[0];
        body.appendChild(bg);
  },

  addEvent: function(obj, type, fn) { 
    // thanks to John Resig
  	if (obj.addEventListener)
  		obj.addEventListener(type, fn, false);
  	else if (obj.attachEvent)	{
  		obj["e"+type+fn] = fn;
  		obj[type+fn] = function() { obj["e"+type+fn](window.event); }
  		obj.attachEvent("on"+type, obj[type+fn]);
  	}
  },

  reloadPage: function() {
    // clear previous timer
    window.clearTimeout(resizeDelay);
    // timeout handler to fire after the resize event (for IE)
    var resizeDelay = setTimeout(function(){
      this.location.href = window.location.href;
    }, 10);
    // Note: window.location.reload(); does not reload the tracking layer
  },
  
  arraySum: function(array) {
  	for (var i=0,sum=0; i<array.length; sum+=array[i++]);
  	return sum;
  },
  
  // (smt) realtime drawing algorithm ------------------------------------------
  playMouse: function() {
    // draw entry point
    var p = smt_data.coordsX[smt_replay.i] * smt_replay.dr_h;
    var q = smt_data.coordsY[smt_replay.i] * smt_replay.dr_v;
    if (smt_replay.i == 0) { 
      smt_replay.jg.setColor(smt_options.entryPt);
      smt_replay.jg.fillPolygon([p,p,   p+4, p+6, p+9, p+7, p+15], 
                                [q,q+15,q+15,q+23,q+23,q+15,q+15]);
      smt_replay.jg.paint();
    }
  
    // main loop to draw mouse trail
    if (smt_replay.i < smt_data.coordsX.length)  {
      // X coords normalization
      var cXa = p;
      var cXb = smt_data.coordsX[smt_replay.i+1] * smt_replay.dr_h;
      var clX = smt_data.clicksX[smt_replay.i] * smt_replay.dr_h;
      // Y coords normalization
      var cYa = q;
      var cYb = smt_data.coordsY[smt_replay.i+1] * smt_replay.dr_v;
      var clY = smt_data.clicksY[smt_replay.i] * smt_replay.dr_v;
      // draw registration points   
      if (cXa == cXb && cYa == cYb) {
        // store variable size (circles)
        if (smt_replay.j < smt_replay.j_max) 
          smt_replay.j++;
      } else {
        smt_replay.jg.setColor(smt_options.regPt);
        if (!smt_options.directionVector)
          // static squares
          smt_replay.jg.fillRect(cXa-1, cYa-1, 3, 3);
        else {
          // direction arrows
          var a = cXa-cXb;
          var b = cYa-cYb;
          if(a>0 && b>0)
            smt_replay.jg.drawPolyline([cXb-4,cXb,cXb+4], [cYb+4,cYb,cYb+4]);
          else if(a<0 && b>0)
            smt_replay.jg.drawPolyline([cXb-4,cXb,cXb-4], [cYb-4,cYb,cYb+4]);
          else if(a<0 && b<0)
            smt_replay.jg.drawPolyline([cXb-4,cXb,cXb+4], [cYb-4,cYb,cYb-4]);
          else if(a>0 && b<0)
            smt_replay.jg.drawPolyline([cXb+4,cXb,cXb+4], [cYb-4,cYb,cYb+4]);
        }
        // variable circles
        if (smt_replay.j != 1) {
          smt_replay.jg.setColor(smt_options.varCir);
          smt_replay.jg.drawEllipse(cXa-smt_replay.j/4, cYa-smt_replay.j/4, smt_replay.j/2, smt_replay.j/2);
        }
        // reset variable circles size
        smt_replay.j = 1;
      }
      
      // draw lines
      smt_replay.jg.setColor(smt_options.regLn);
      smt_replay.jg.drawLine(cXa, cYa, cXb, cYb);
      smt_replay.jg.paint();
      
      // draw clicks
      if (cXa == clX && cYa == clY) {
        smt_replay.jg.setColor(smt_options.regClick);
        smt_replay.jg.drawRect(clX-5,clY-5,10,10);
        smt_replay.jg.paint();
      }
      // update mouse coordinates
      smt_replay.i++;
      
  	} else {
  	  // draw exit point
  	  var p = smt_data.coordsX[smt_replay.i-1] * smt_replay.dr_h;
      var q = smt_data.coordsY[smt_replay.i-1] * smt_replay.dr_v;
  	  smt_replay.jg.setColor(smt_options.exitPt);
      smt_replay.jg.fillPolygon([p,p,   p+4, p+6, p+9, p+7, p+15], 
                                [q,q+15,q+15,q+23,q+23,q+15,q+15]);
      smt_replay.jg.paint();
      // draw centroid (average mouse position) 
      smt_replay.jg.setColor(smt_options.cenPt);
      var u = Math.round((smt_replay.arraySum(smt_data.coordsX)*smt_replay.dr_h / smt_data.coordsX.length)*100)/100;
      var v = Math.round((smt_replay.arraySum(smt_data.coordsY)*smt_replay.dr_v / smt_data.coordsY.length)*100)/100;
      var l = 10; // centroid line length
      smt_replay.jg.setStroke(3);
  		smt_replay.jg.drawLine(u, v, u+l, v-l); // 1st quadrant
  		smt_replay.jg.drawLine(u, v, u-l, v-l); // 2nd quadrant
  		smt_replay.jg.drawLine(u, v, u-l, v+l); // 3rd quadrant
  		smt_replay.jg.drawLine(u, v, u+l, v+l); // 4th quadrant
  		smt_replay.jg.paint();
  
      // clear mouse tracking
      clearInterval(smt_replay.play);
  		//delete smt_replay;
  	}
  	
  },
  
  init: function() {
    var smt = "smtCanvas";
    // set the canvas layer
    smt_replay.createCanvas(smt);

    // draw the background layer if needed
    if (smt_options.bgLayer) smt_replay.setBgCanvas(smt);
    
    // get the document size
    var w = smt_replay.getWindowSize("width");
    var h = smt_replay.getWindowSize("height");
    // compute the discrepance ratio
    smt_replay.dr_h = Math.round((w / smt_data.previousWidth)*100)/100;
    smt_replay.dr_v = Math.round((h / smt_data.previousHeight)*100)/100;
  
    if (smt_options.realTime) {
      // fps are stored in smt_data object, so we can use that value here
      var interval = Math.round(1000/smt_data.fps);
      smt_replay.play = setInterval(smt_replay.playMouse, interval);
    } else {
      // static mouse tracking visualization
      var total = smt_data.coordsX.length; 
      for (var i=0; i<=total; ++i)
        smt_replay.playMouse();
    }
  }
      
};

// in this replay case it's not required to begin when the DOM content is loaded 
smt_replay.addEvent(window, "load",   smt_replay.init);
// sometimes this can be useful:
//smt_replay.addEvent(window, "resize", smt_replay.reloadPage);
/** 
 * Note that reloading a page if it is resized has some side-effect,
 * such as adding entries to a database or sending off e-mail messages. 
 * Thus, comment/uncomment the last line above at your own will. 
 */
})();
