/*
 * Verifier test that checks the users OS and browser version of viewer compatibility
 *
 * Hackery Notes:
 *   this test checks if the user is running a mac version, and if it is, calles BaseTest.setMac(true)
 */

var TestBrowser = function(name) {
    this.superclass = BaseTest;
    this._initialize(name);
}

extend(TestBrowser.prototype, new BaseTest(), {
    start : function() {
        var params = new TestParameters();

        try {
            // check browser version
            BrowserDetect.init();

            // known browsers
            var IE_BROWSER = "Explorer";
            var FIREFOX_BROWSER = "Firefox";
            var SAFARI_BROWSER = "Safari";
            var CHROME_BROWSER = "Chrome";

            // supported browser versions
            var supportedBrowsers = [FIREFOX_BROWSER, IE_BROWSER, SAFARI_BROWSER];
            var supportedBrowserVersions = {};
            supportedBrowserVersions[IE_BROWSER] = [7, 8];
            supportedBrowserVersions[FIREFOX_BROWSER] = [3, 3.5];
            supportedBrowserVersions[SAFARI_BROWSER] = [];

            var supportedBrowsersString = this.stringifyBrowserList(supportedBrowserVersions);

            var knownLimitedBrowsers = {};
            knownLimitedBrowsers[CHROME_BROWSER] = [];

            var knownUnsupported = {};
            knownUnsupported[IE_BROWSER] = [6];
            knownUnsupported[FIREFOX_BROWSER] = [2];

            var browser = BrowserDetect.browser;
            var browserVersion = BrowserDetect.version;
            var browserDeets = {browser: browser, version: browserVersion};

            params.merge({browser: browser, browserVersion: browserVersion, supportedBrowsersString: supportedBrowsersString, browserString: navigator.userAgent || navigator.vendor || navigator.opera});

            // test if we know this browser isn't compatible
            if(this.browserListContains(browserDeets, knownUnsupported))
                return this.notifyFailure("CHECKBROWSER", "UNSUPPORTED", params.merge({supportedBrowsersString: supportedBrowsersString}));

            // test if we know this browser has known limitations
            var browserKnownLimited = this.browserListContains(browserDeets, knownLimitedBrowsers);
            if(browserKnownLimited)
                this.notifyWarning("BROWSER_KNOWN_LIMITATIONS", null, params);

            // test if this browser isn't explicitely known in any of the above sets, then warn
            if(!this.browserListContains(browserDeets, supportedBrowserVersions) && !browserKnownLimited)
                this.notifyWarning("BROWSER_UNKNOWN", null, params);

            this.notifySuccess(null, params);
        } catch (e) {
            this.notifyFailure("CHECKBROWSER", "EXCEPTION", params.merge({exception : e}));
        }
    },

    notifyWarning: function(code, msg, params) {
        var newParams = {};
        newParams["WARNING_" + code] = code;

        params.merge(newParams);

        // call super notifyWarning method
        this.superclass.prototype.notifyWarning.apply(this, arguments);
    },

    /**
     * Turn the list of browser version defs into a readable string.
     *
     * @param browserList
     */
    stringifyBrowserList: function(browserList) {
        var supportedBrowsersString = "";
        for(var browserName in browserList) {
            if (supportedBrowsersString.length > 0) supportedBrowsersString += ", ";

            var versions = browserList[browserName];
            var hasVersions = versions && versions.length > 0;

            supportedBrowsersString += browserName;

            if(hasVersions)
                supportedBrowsersString += (" versions " + versions.join(", "));
        }

        return supportedBrowsersString;
    },

    browserListContains: function(deets, browserList) {
        var browser = deets.browser;
        var version = deets.version;

        var supportedVersions = browserList[browser];
        if(supportedVersions) {
            if(supportedVersions.length == 0)
                return true; // no specific browser versions specified in map

            return Mixamo.Array.contains(supportedVersions, version);
        }

        return false;
    }
})

var TestOS = function(name) {
    this._initialize(name);
}

extend(TestOS.prototype, new BaseTest(), {
    start: function() {
        var params = new TestParameters();

        try {
            // supported os-es
            var supportedOSes = ["Windows", "MacOS"];

            var os = BrowserDetect.OS;

            // check os
            var OSName = "Unknown OS";
            if (navigator.appVersion.indexOf("Win") != -1) OSName = "Windows";

            if (navigator.appVersion.indexOf("Mac") != -1) {
                OSName = "MacOS";
                this.setMac(true); // hackery
            }

            if (navigator.appVersion.indexOf("X11") != -1) OSName = "UNIX";
            if (navigator.appVersion.indexOf("Linux") != -1) OSName = "Linux";

            params.merge({osname: OSName, os: os});

            if (supportedOSes.indexOf(OSName) < 0)
                return this.notifyFailure("CHECKOS", "UNSUPPORTED", params)

            this.notifySuccess(null, params);   
        } catch (e) {
            this.notifyFailure("CHECKOS", "EXCEPTION", params.merge({exception : e}));
        }
    }
})