/**
 * Class that provide browser detection.
 *
 * @author http://www.quirksmode.org/js/detect.html
 * @author Loops <pierrot at nvision dot lu>
 */
function BrowserDetect()
{
  
  /**
   * The browser identity
   *
   * @var string
   */
  this.browser = 'unknown browser';
  
  /**
   * The version identity
   *
   * @var string
   */
  this.version = 'unknown version';
  
  /**
   * The version string searched
   *
   * @var string
   */
  this.versionSearchString = '';
  
  /**
   * The version identity
   *
   * @var string
   */
  this.OS = 'unknown OS';
  
  /**
   * An array of browser detection data
   * Note that browser are detected in them order of appearance.
   *
   * @var array
   */
  this.dataBrowser = [
    {
      string: navigator.userAgent,
      subString: "OmniWeb",
      versionSearch: "OmniWeb/",
      identity: "OmniWeb"
    },
    {
      string: navigator.vendor,
      subString: "Apple",
      identity: "Safari"
    },
    {
      prop: window.opera,
      identity: "Opera"
    },
    {
      string: navigator.vendor,
      subString: "iCab",
      identity: "iCab"
    },
    {
      string: navigator.vendor,
      subString: "KDE",
      identity: "Konqueror"
    },
    {
      string: navigator.userAgent,
      subString: "Firefox",
      identity: "Firefox"
    },
    {
      string: navigator.vendor,
      subString: "Camino",
      identity: "Camino"
    },
    {    // for newer Netscapes (6+)
      string: navigator.userAgent,
      subString: "Netscape",
      identity: "Netscape"
    },
    {
      string: navigator.userAgent,
      subString: "MSIE",
      identity: "Explorer",
      versionSearch: "MSIE"
    },
    {
      string: navigator.userAgent,
      subString: "Gecko",
      identity: "Mozilla",
      versionSearch: "rv"
    },
    {     // for older Netscapes (4-)
      string: navigator.userAgent,
      subString: "Mozilla",
      identity: "Netscape",
      versionSearch: "Mozilla"
    }
  ];
  
  /**
   * The operating system detection data
   * Note that operating system are detected in them order of appearance.
   *
   * @var integer
   */
  this.dataOS = [
    {
      string: navigator.platform,
      subString: "Win",
      identity: "Windows"
    },
    {
      string: navigator.platform,
      subString: "Mac",
      identity: "Mac"
    },
    {
      string: navigator.platform,
      subString: "Linux",
      identity: "Linux"
    }
  ];
  
  /**
   * void init()
   *
   * Initialize the detection
   *
   * @param  none
   * @return void
   */
  this.init = function()
  {
    this.browser = this.searchString( this.dataBrowser ) || "unknown browser";
    this.version = this.searchVersion( navigator.userAgent )
                || this.searchVersion( navigator.appVersion )
                || "unknown version";
    this.OS      = this.searchString( this.dataOS ) || "unknown OS";
  };

  /**
   * void searchString( array )
   *
   * Launch a string search on an array of data
   *
   * @param  array   data   an array of data
   * @return string  the detected identity
   */
  this.searchString = function( data )
  {
    for( var i = 0, iMax = data.length; i < iMax; i++ )
    {
      var dataString = data[i].string;
      var dataProp   = data[i].prop;
      this.versionSearchString = data[i].versionSearch || data[i].identity;
      if( dataString )
      {
        if( dataString.indexOf( data[i].subString ) !== -1 )
        {
          return data[i].identity;
        }
      }
      else if( dataProp )
      {
        return data[i].identity;
      }
    }
  };

  /**
   * void searchVersion()
   *
   * Launch a version search  on a string.
   *
   * @param  string  dataString   the string data
   * @return string  the detected identity
   */
  this.searchVersion = function( dataString )
  {
    var index = dataString.indexOf( this.versionSearchString );
    if( index !== -1 )
    {
      return parseFloat( dataString.substring( index + this.versionSearchString.length + 1 ) );
    }
  };

  /**
   * void right()
   *
   * Move the element to right
   *
   * @param  none
   * @return void
   */
  this.right = function()
  {
    if( ! ( this.currentAction & 2 ) )
    {
      window.clearTimeout( this.timeout );
      this.slide( this.currentLeft, this.getStep( 1 ) );
      this.currentAction = 2;
    }
  };

  /**
   * void checkMoves()
   *
   * Check avaible movements
   *
   * @param  none
   * @return void
   */
  this.checkMoves = function()
  {
    if( this.currentLeft > this.maxLeft - this.step )
    {
      this.toRight.style.display = 'none';
    }
    else
    {
      this.toRight.style.display = 'block';
    }
    if( this.currentLeft < this.step )
    {
      this.toLeft.style.display = 'none';
    }
    else
    {
      this.toLeft.style.display = 'block';
    }
  };

  /**
   * void slide()
   *
   * Slide method
   *
   * @param  integer  from  the current left position
   * @param  integer  to    the wanted left position
   * @return void
   */
  this.slide = function( from , to )
  {
    var dir = ( to - from ) / Math.abs( to - from );
    var next = from + ( dir * this.speed );
    if( ( dir > 0 && next >= to ) || ( dir < 0 && next <= to ) )
    {
      /* Stop the slide */
      this.toSlide.style.left = '-' + to + 'px';
      this.currentLeft = to;
      window.clearTimeout( this.timeout );
      this.currentAction = 0;
    }
    else
    {
      /* Continue the slide */
      this.toSlide.style.left = '-' + next + 'px';
      this.currentLeft = next;
      this.timeout = window.setTimeout( function(){ selfRef.slide( next , to ) } , this.timer );
    }
    this.checkMoves();
  };

  /* Automatically launch detection */
  this.init();
};

/* Automatically create a global instance of BrowserDetect */
var BrowserDetected = new BrowserDetect();
