
function ervs_mousetracker()
{
  /* private vars */
  this.storeUrl = '/cgi-bin/trackdata.pl'
  this.trackdata = new Array();
  this.sid;
  var t = new Date();
  this.start = t.getTime();
  var mtr = this; // referencing from child objects

  /* private member functions */
  function trackmouse(e)
  {
    if ( ! e ) e = window.event;
    var tt = new Date();
    var dt = tt.getTime() - mtr.start;
    var me = e.type;
    var mb = e.button;
    var mx = e.pageX;
    var my = e.pageY;
    var cref = (me == 'click') ? ((e.target) ? e.target : e.srcElement) : ' ';
    var creftext = (cref.textContent) ? cref.textContent.substring(0,80) + '..' : '';
    var ckey = ((e.shiftKey) ? 1 : 0)
      + ((e.ctrlKey) ? 2 : 0)
      + ((e.altKey) ? 4 : 0)
      + ((e.metaKey) ? 8 : 0);

    var item = new Array();
    item.push ( dt, me, mb, mx, my, ckey, cref.id, cref.href, creftext );
    /*if (me=="click")*/ mtr.trackdata.push ( item );
    return true;
  };

  function serialize(elem)
  {
    if (elem == null || elem == undefined || elem.constructor == Function) return ' ';

    switch (elem.constructor)
    {
      case String:  return elem;
      case Number:  return elem;
      case Boolean: return elem;
      case Date:    return serialize(elem.getTime());
      case RegExp:  return serialize(elem.toSource());
      case Error:   return serialize(elem.message);
      case Array:
        var content = '', i = 0;
        for (var j in elem)
        {
          if ( content != '' ) content += ',';
          content += serialize(elem[j]);
          i++;
        }
        return '{' + content + '}';
      default:
        return serialize(elem.toString());
    }
  }

  function senddata ()
  {
    this.data = mtr.trackdata;
    mtr.trackdata = new Array();
    this.req;

    if ( this.data.length > 0 )
    {
      try
      {
        this.req = new XMLHttpRequest();
      }
      catch (e)
      {
        try
        {
          this.req = new ActiveXObject('MSXML2.XMLHTTP');
        }
        catch (e)
        {
          try
          {
            this.req = new ActiveXObject('Microsoft.XMLHTTP');
          }
          catch (e)
          {
            return false;
          }
        }
      }
      this.req.open('POST', mtr.storeUrl, true);

      var self =  this;

      this.req.onreadystatechange = function()
      {
        if ( ( self.req.readyState == 4 ) && (!mtr.sid) && (self.req.status >= 200) && (self.req.status <= 299)) mtr.sid = self.req.responseText;
      };

      this.abort = function()
      {
        if (this.req)
        {
           this.req.onreadystatechange = function() { };
           this.req.abort();
           this.req = null;
         }
      };
      var postdata = "sid=" + encodeURIComponent(tracker.sid);
      postdata += "&url=" + encodeURIComponent(document.URL);
      postdata += "&viewportwidth=" + ((window.innerWidth) ? (window.innerWidth):(document.body.offsetWidth)).toString();
      postdata += "&viewportheight=" + ((window.innerHeight) ? (window.innerHeight) : (document.body.offsetHeight)).toString();
      postdata += "&trackdata=" + encodeURIComponent(serialize(this.data));
      this.req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
      this.req.setRequestHeader("Content-length", postdata.length);
      this.req.setRequestHeader("Connection", "close");

      this.req.send(postdata);
    }
  };

  function addEvent( obj, type, fn )
  {
     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 ] );
     }
     return false;
  };

  function removeEvent( obj, type, fn )
  {
     if (obj.removeEventListener) {
        obj.removeEventListener( type, fn, false );
     } else if (obj.detachEvent) {
        obj.detachEvent( "on"+type, obj[type+fn] );
        obj[type+fn] = null;
        obj["e"+type+fn] = null;
     }
     return false;
  };

  // onmousedown-Event-Handler registrieren
  addEvent(document, "mousemove", trackmouse);
  addEvent(document, "mousedown", trackmouse);
  addEvent(document, "mouseup", trackmouse);
  addEvent(document, "click", trackmouse);
  addEvent(window, "unload", senddata);

  //focus
  //blur

  var tid = setInterval ( senddata, 5000 );
};

var tracker= new ervs_mousetracker();
