Voy.Env = Class.create();
Object.extend( Voy.Env, 
  {
    Resolution: Class.create(),
    Browser: Class.create(),
    OS: Class.create(),
    Acrobat: Class.create()
  }
);
Voy.Env.Version = Class.create();
Object.extend( Voy.Env.Version.prototype, 
  {
    initialize: function( versionArray ) {
      this.versionArray = Voy.isDefined( versionArray ) ? $A( versionArray ) : $A();
      this.major = '';
      this.minor = '';
      this.rev = '';
      var self = this;
      var minorSet = false;
      versionArray.each( function(item, index) { 
        switch (index) {
          case 0:
            self.major = item;
            break;
          case 1:
            if ( item != '.' ) {
              self.minor = item;
              minorSet = true;
            }
            break;
          case 2:
            if ( ! minorSet ) {
              self.minor = item;
            } else {
              self.rev += item;
            }
          case 3:
            break;
          default:
            self.rev += item;
        }
      }); 
    },
    asString: function() {
      return this.versionArray.join( '' );
    }
  }
);
Object.extend( Voy.Env.Version, {
  getVersionArray: function( versionString ) {
    var versionArray = $A();
    var currentChar;
    if ( Voy.isDefined( versionString ) ) {
      var currentCharX = "";
  	  for ( var i = 0; i < versionString.length; i++ ) {
  	    currentChar = versionString.charAt( i );
  	    if (currentChar == ".") {
  	      versionArray.push( currentCharX );
          versionArray.push( currentChar );
  	      currentCharX = "";
  	    } else {
          currentCharX = currentCharX + currentChar;
  	    }
	    }
  	  if (currentCharX!="") { versionArray.push( currentCharX ); }
    }
    return versionArray;
  }
});
Object.extend( Voy.Env.Resolution, 
  {
    width: screen.width,
    height: screen.height,
    asString: function() {
      return Voy.Env.Resolution.width + 'x' + Voy.Env.Resolution.height;
    }
  }
);
Object.extend( Voy.Env.Browser, 
  {
    _browser: null,
    _version: null,
    _flashVersion: null,
    javaScriptEnabled: function() {
      return true; // would not be able to see these results otherwise ;)
    },
    cookiesEnabled: function() {
      return navigator.cookieEnabled;
    },
    browserName: function() {
      if ( Voy.isNull( Voy.Env.Browser._browser ) ) {
        Voy.Env.Browser._browser = Voy.Env.Browser.getBrowser();
      }
      return Voy.Env.Browser._browser.identity || 'unsupported browser';
    },
    version: function() {
      if ( Voy.Env.Browser._version == null ) {
        if ( Voy.isNull( Voy.Env.Browser._browser ) ) {
          Voy.Env.Browser._browser = Voy.Env.Browser.getBrowser();
        }
        var versionArray = Try.these( function() {return Voy.Env.Browser.getVersion( Voy.Env.Browser._browser, navigator.appVersion )},
                                      function() {return Voy.Env.Browser.getVersion( Voy.Env.Browser._browser, navigator.userAgent )} 
                                    ) || [ 'unsupported version' ];
        Voy.Env.Browser._version = new Voy.Env.Version( versionArray );
      }
      return Voy.Env.Browser._version;
    },
    getVersion: function( browser, searchIn ) {
      var searchFor = browser.versionSearch || browser.identity;
      var index = searchIn.indexOf( searchFor );
      if ( index == -1 ) { 
        throw exception;
      };
      var version = $A();
      for ( var i = index + searchFor.length + 1; i < searchIn.length; i++ ) {
        var currentChar = searchIn.charAt( i );
        if ( currentChar == '.' || ! isNaN( parseInt( currentChar ) ) ) {
          version.push( currentChar );
        } else {
          break;
        }
      }
      if ( Voy.isDefined( browser.buildVersionMatrix ) ) {
        var buildVersion = version.join( '' );
        browser.buildVersionMatrix.each( function( matrixItem ) {
          if ( matrixItem.build == buildVersion ) {
            version = Voy.Env.Version.getVersionArray( matrixItem.version );
          }
        });
      }
      return version;
    },
    getBrowser: function() {
      var browsers = Voy.Env.Browser.browsers;
      for ( var i = 0; i < browsers.length; i++ ) {
        var identifier = browsers[ i ].identifier;
        var property = browsers[ i ].property;
        if ( Voy.isDefined( identifier ) ) {
          if ( identifier.toLowerCase().indexOf( browsers[ i ].subString.toLowerCase() ) != -1 ) {
            return browsers[ i ];
          }
        } else if ( Voy.isDefined( property ) ) {
          return browsers[ i ];
        }
      }
    },
    browsers: [
      { identifier: navigator.userAgent,
        subString: "Safari",
        identity: "Safari",
        versionSearch: "Safari",
        buildVersionMatrix: $A([
                         {build:'85.5',     version:'1.0',   osVersion:'10.2.8'},
                         {build:'85.7',     version:'1.0.2', osVersion:'10.2.8'},
                         {build:'85.8',     version:'1.0.3', osVersion:'10.2.8'},
                         {build:'85.8.1',   version:'1.0.3', osVersion:'10.2.8'},
                         {build:'100',      version:'1.1',   osVersion:'10.3'},
                         {build:'100.1',    version:'1.1.1', osVersion:'10.3.2'},
                         {build:'125.7',    version:'1.2.2', osVersion:'10.3.4'},
                         {build:'125.8',    version:'1.2.2', osVersion:'10.3.4'},
                         {build:'125.9',    version:'1.2.3', osVersion:'10.3.5'},
                         {build:'125.11',   version:'1.2.4', osVersion:'10.3.6'},
                         {build:'125.12',   version:'1.2.4', osVersion:'10.3.6'},
                         {build:'312',      version:'1.3',   osVersion:'10.3.9'},
                         {build:'312.3',    version:'1.3.1', osVersion:'10.3.9'},
                         {build:'312.3.1',  version:'1.3.1', osVersion:'10.3.9'},
                         {build:'312.5',    version:'1.3.2', osVersion:'10.3.9'},
                         {build:'312.6',    version:'1.3.2', osVersion:'10.3.9'},

                         {build:'412',      version:'2.0',   osVersion:'10.4'},
                         {build:'412.2',    version:'2.0',   osVersion:'10.4.2'},
                         {build:'412.2.2',  version:'2.0',   osVersion:'10.4.2'},
                         {build:'412.5',    version:'2.0.1', osVersion:'10.4.2'},
                         {build:'416.12',   version:'2.0.2', osVersion:'10.4.3'},
                         {build:'416.13',   version:'2.0.2', osVersion:'10.4.3'},
                         {build:'417.8',    version:'2.0.3', osVersion:'10.4.5'},
                         {build:'417.9.2',  version:'2.0.3', osVersion:'10.4.5'},
                         {build:'417.9.3',  version:'2.0.3', osVersion:'10.4.6'},
                         {build:'419.3',    version:'2.0.4', osVersion:'10.4.7'},
                         {build:'522.12',   version:'3.02',  osVersion:'10.4.10'},
                         {build:'525.22',   version:'3.1.2', osVersion:'10.4.11'},

                         {build:'523.1',    version:'3.0.4', osVersion:'10.5'},
                         {build:'523.1',    version:'3.0.4', osVersion:'10.5.1'},

                         {build:'522.13.1', version:'3.0.2', osVersion:'XP/Vista'},
                         {build:'525.21',   version:'3.1.2', osVersion:'XP/Vista'}
                       ])
                       // http://developer.apple.com/internet/safari/uamatrix.html
                       // http://www.seehowitruns.org/pages/web_browsers.php?records=45&search=Safari&field=browser_name
                       // https://addons.mozilla.org/en-US/firefox/search?q=user+agent&cat=all
                         // http://chrispederick.com/work/useragentswitcher/
      },
      { property: window.opera,
        identity: "Opera"
      },
      { identifier: navigator.vendor,
        subString: "KDE",
        identity: "Konqueror"
      },
      { identifier: navigator.userAgent,
        subString: "Firefox",
        identity: "Firefox"
      },
      { identifier: navigator.vendor,
        subString: "Camino",
        identity: "Camino"
      },
      { identifier: navigator.userAgent,
        subString: "Netscape",
        identity: "Netscape"
      },
      { identifier: navigator.userAgent,
        subString: "MSIE",
        identity: "Internet Explorer",
        versionSearch: "MSIE"
      },
      { identifier: navigator.userAgent,
        subString: "Gecko",
        identity: "Mozilla",
        versionSearch: "rv"
      },
      { identifier: navigator.userAgent,
        subString: "Mozilla",
        identity: "Netscape",
        versionSearch: "Mozilla"
      }
    ],
    flashEnabled: function() {
      if ( Voy.isNull( Voy.Env.Browser._flashVersion ) ) {
        Voy.Env.Browser._flashVersion = Voy.Env.Browser.getFlashVersion();
      }
      return ! Voy.isNull( Voy.Env.Browser._flashVersion );
    },
    flashVersion: function() { 
      if ( Voy.isNull( Voy.Env.Browser._flashVersion ) ) {
        Voy.Env.Browser._flashVersion = Voy.Env.Browser.getFlashVersion();
      }
      return Voy.Env.Browser._flashVersion;
    },
    getFlashVersion: function() {// altered, but highly leveraged from swfobject.js
      var versionArray;
      var flashVersionString;
      
      flashVersionString = Try.these(
          function() {  
            var flashVersion, activeXObject;
            activeXObject = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash.10' );
            if ( ! Voy.isNull( activeXObject ) ) {
              flashVersion = activeXObject.GetVariable( '$version' ).split( ' ' )[ 1 ].replace( /,/g, '.' );
            }
            return flashVersion;
          },
          function() {  
            var flashVersion, activeXObject;
            activeXObject = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash.9' );
            if ( ! Voy.isNull( activeXObject ) ) {
              flashVersion = activeXObject.GetVariable( '$version' ).split( ' ' )[ 1 ].replace( /,/g, '.' );
            }
            return flashVersion;
          },
          function() {  
            var flashVersion, activeXObject;
            activeXObject = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash.8' );
            if ( ! Voy.isNull( activeXObject ) ) {
              flashVersion = activeXObject.GetVariable( '$version' ).split( ' ' )[ 1 ].replace( /,/g, '.' );
            }
            return flashVersion;
          },
        function() {  
		      var flashVersion, activeXObject;
          activeXObject = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash.7' );
	        if ( ! Voy.isNull( activeXObject ) ) {
	          flashVersion = activeXObject.GetVariable( '$version' ).split( ' ' )[ 1 ].replace( /,/g, '.' );
	        }
	        return flashVersion;
	      },
	      function() {
          var flashVersion; 
          var activeXObject = null;
          try {
            activeXObject = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash.6' );
            flashVersion = '6.0.21';
            activeXObject.AllowScriptAccess = 'always';
          } catch( e ) {
          }
          if ( ! Voy.isNull( activeXObject ) ) {
            return flashVersion;
          } else {
            throw exception;
          }
	      },
	      function() {
          var flashVersion, activeXObject;
	        activeXObject = new ActiveXObject( 'ShockwaveFlash.ShockwaveFlash' );
	        if ( ! Voy.isNull( activeXObject ) ) {
	          flashVersion = activeXObject.GetVariable( '$version' ).split( ' ' )[ 1 ].replace( /,/g, '.' );
	        }
          return flashVersion;
	      },
	      function() {
	        var flashVersion;
	        var plugin = navigator.plugins[ 'Shockwave Flash' ];
	        if( plugin && plugin.description ) {
	          flashVersion = plugin.description.replace( /([a-zA-Z]|\s)+/, '' ).replace( /(\s+r|\s+b[0-9]+)/, '.' )
	        }
	        return flashVersion;
	      }
	    );
      versionArray = Voy.Env.Version.getVersionArray( flashVersionString );
      return new Voy.Env.Version( versionArray );
    },
    isMSIE: function() {
      return (
        Voy.Env.Browser.browserName()=="MSIE" ||
        Voy.Env.Browser.browserName().substr(0,8)=="Internet"
      )
    },
    isFirefox: function() {
      return Voy.Env.Browser.browserName()=="Firefox";
    },
    isSafari: function() {
      return Voy.Env.Browser.browserName()=="Safari";
    },
    isOpera: function() {
      return Voy.Env.Browser.browserName()=="Opera";
    },
    isKonqueror: function() {
      return Voy.Env.Browser.browserName()=="Konqueror";
    },
    isCamino: function() {
      return Voy.Env.Browser.browserName()=="Camino";
    },
    isMozilla: function() {
      return Voy.Env.Browser.browserName()=="Mozilla";
    },
    isNetscape: function() {
      return Voy.Env.Browser.browserName()=="Netscape";
    }
  }
);
Object.extend( Voy.Env.OS,
  {
    _os: null,
    osName: function() {
      if ( Voy.Env.OS._os == null ) {
        Voy.Env.OS._os = Voy.Env.OS.getOS();
      }
      return Voy.Env.OS._os.identity || 'unsupported os';
    },
    version: function() {
      if ( Voy.Env.OS._os == null ) {
        Voy.Env.OS._os = Voy.Env.OS.getOS();
      }
      return Voy.Env.OS.getVersion( Voy.Env.OS._os );
    },
    getOS: function() {
      var oses = Voy.Env.OS.oses;
      for ( var i = 0; i < oses.length; i++ ) {
        var identifier = oses[ i ].identifier;
        var property = oses[ i ].property;
        if ( Voy.isDefined( identifier ) ) {
          if ( identifier.toLowerCase().indexOf( oses[ i ].subString.toLowerCase() ) != -1 ) {
            return oses[ i ];
          }
        } else if ( Voy.isDefined( property ) ) {
          return oses[ i ];
        }
      }
    },
    getVersion: function( os ) {
      var osVersion = null;
      os.versions.each( function( version ) {
        version.subStrings.each( function( subString ) {
          if ( navigator.userAgent.toLowerCase().indexOf( subString.toLowerCase() ) >= 0 ) {
            osVersion = version.name;
            throw $break;
          }
        });
        if ( osVersion != null ) {
          throw $break;
        }
      });
      if ( osVersion == null ) {
        osVersion = "unsupported version";
      }
      return osVersion;
    },
    oses : [
      { identifier: navigator.platform,
        subString: "Win",
        identity: "Windows",
        versionSearch: navigator.userAgent,
        versions: $A([
          { name: "Windows 98", subStrings: $A( [ "win98", "windows 98" ] ) },
          { name: "Windows ME", subStrings: $A( [ "Win 9x 4.90" ] ) },
          { name: "Windows 2000", subStrings: $A( [ "windows nt 5.0", "windows 2000" ] ) },
          { name: "Windows XP", subStrings: $A( [ "windows nt 5.1", "windows xp" ] ) },
          { name: "Windows Vista", subStrings: $A( [ "windows nt 6", "windows vista" ] ) }
        ])
      },
      { identifier: navigator.platform,
        subString: "Mac",
        identity: "Mac",
        versionSearch: navigator.userAgent,
        versions: $A([
          { name: "Mac OS X", subStrings: $A( [ "mac os x" ] ) },
          { name: "Mac PowerPC", subStrings: $A( [ "mac_powerpc" ] ) },
          { name: "Mac", subStrings: $A( [ "mac" ] ) }
        ])
      },
      { identifier: navigator.platform,
        subString: "Linux",
        identity: "Linux",
        versionSearch: navigator.userAgent,
        versions: $A([
          { name: "Ubuntu", subStrings: $A( [ "Ubuntu" ] ) }
        ])
      }
    ]  
  }
);
Object.extend( Voy.Env.Acrobat, {
    _version: null,
    enabled: function() {
      if ( Voy.isNull( Voy.Env.Acrobat._version ) ) {
        Voy.Env.Acrobat.getVersion();
      }
      return ( ! Voy.isNull( Voy.Env.Acrobat._version ) && Voy.Env.Acrobat._version.asString() != 'not installed' );
    },
    version: function() {
      if ( Voy.isNull( Voy.Env.Acrobat._version ) ) {
        Voy.Env.Acrobat.getVersion();
      }
      return Voy.Env.Acrobat._version;
    },
    getVersion: function() {
      Voy.Env.Acrobat._version = Try.these(
        function() { if ( ! Voy.isNull( new ActiveXObject( 'AcroPDF.PDF.1' ) ) ) { return new Voy.Env.Version( Voy.Env.Version.getVersionArray( 'Installed' ) ); } },
        function() { if ( ! Voy.isNull( new ActiveXObject( 'PDF.PdfCtrl.1' ) ) ) { return new Voy.Env.Version( Voy.Env.Version.getVersionArray( '4.0' ) ); } },
        function() { if ( ! Voy.isNull( new ActiveXObject( 'PDF.PdfCtrl.2' ) ) ) { return new Voy.Env.Version( Voy.Env.Version.getVersionArray( '2.0' ) ); } },
        function() { if ( ! Voy.isNull( new ActiveXObject( 'PDF.PdfCtrl.3' ) ) ) { return new Voy.Env.Version( Voy.Env.Version.getVersionArray( '3.0' ) ); } },
        function() { if ( ! Voy.isNull( new ActiveXObject( 'PDF.PdfCtrl.4' ) ) ) { return new Voy.Env.Version( Voy.Env.Version.getVersionArray( '4.0' ) ); } },
        function() { if ( ! Voy.isNull( new ActiveXObject( 'PDF.PdfCtrl.5' ) ) ) { return new Voy.Env.Version( Voy.Env.Version.getVersionArray( '5.0' ) ); } },
        function() { if ( ! Voy.isNull( new ActiveXObject( 'PDF.PdfCtrl.6' ) ) ) { return new Voy.Env.Version( Voy.Env.Version.getVersionArray( '6.0' ) ); } },
		function () {
		  var version = '0.0';
		  if (navigator.plugins && navigator.plugins.length) {
			for ( var i = 0; i < navigator.plugins.length; i++ ) {
				if ( navigator.plugins[i].filename.indexOf('nppdf32') != -1 ) {
					version=parseFloat(navigator.plugins[i].description.split('Version ')[1]);
					if ( isNaN( version ) ) { // assume 8.1--they have Acrobat, we just don't know what version they have
	                  version = '8';
                    }
		            else if ( version.toString().indexOf('5.') != -1) {
                      version = '5';
                    }
                    else if ( version.toString().substr(0,1) == '6' ) {
                      version = '6';
                    }
                    else if ( version.toString().substr(0,1) == '7' ) {
                      version = '7';
                    }
                    else
                    {
                      version = 'Installed';
                    }
                }
			}
			return new Voy.Env.Version( Voy.Env.Version.getVersionArray( version ) );
		  }
          if ( Voy.Env.OS.version() == 'Mac OS X' ) { // one last check to see if it is OS X before indicating PDF is not installed
            return new Voy.Env.Version( [''] );
          }
          return new Voy.Env.Version( ['not installed'] );
        }
      );
    }
  }
);
