(function (f) {
    window.setTimeout = f(window.setTimeout);
    window.setInterval = f(window.setInterval);
})(function (f) {
    return function (c, t) {
        // alert(c);
        var a = [].slice.call(arguments, 2);
        return f(function () {
            c.apply(this, a);
        }, t);
    };
});
Array.prototype.peek = function () {
    if (this.length == 0) {
        return null;
    }
    return this[this.length - 1];
};
if (!Array.prototype.forEach) {
    Array.prototype.forEach = function (callback, thisArg) {
        var T, k;
        if (this == null) {
            throw new TypeError(' this is null or not defined');
        }
        var O = Object(this);
        var len = O.length >>> 0;
        if (typeof callback !== "function") {
            throw new TypeError(callback + ' is not a function');
        }
        if (arguments.length > 1) {
            T = thisArg;
        }
        k = 0;
        while (k < len) {
            var kValue;
            if (k in O) {
                kValue = O[k];
                callback.call(T, kValue, k, O);
            }
            k++;
        }
    };
}

var BrowserDetect = {
    init:function () {
        this.browser = this.searchString(this.dataBrowser) || "Other";
        this.version = this.searchVersion(navigator.userAgent) ||
            this.searchVersion(navigator.appVersion) ||
            "0";
        this.OS = this.searchString(this.dataOS) || "Other";
        this.hardware = this.searchString(this.Hardware) || "Other";
    },
    searchString:function (data) {
        for (var i = 0; i < data.length; 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;
        }
    },
    searchVersion:function (dataString) {
        var index = dataString.indexOf(this.versionSearchString);
        if (index == -1)
            return;
        return parseFloat(dataString.substring(index + this.versionSearchString.length + 1));
    },
    dataBrowser:[
        {
            string:navigator.userAgent,
            subString:"AuthorViewer",
            identity:"AuthorViewer"
        },
        {
            string:navigator.userAgent,
            subString:"Chrome",
            identity:"Chrome"
        },
        {
            string:navigator.vendor,
            subString:"Apple",
            identity:"Safari",
            versionSearch:"Version"
        },
        {
            prop:window.opera,
            identity:"Opera",
            versionSearch:"Version"
        },
        {
            string:navigator.userAgent,
            subString:"Firefox",
            identity:"Firefox"
        },
        {
            string:navigator.userAgent,
            subString:"IEMobile",
            identity:"IEMoble",
            versionSearch:"MSIE"
        },
        {
            string:navigator.userAgent,
            subString:"MSIE",
            identity:"IE",
            versionSearch:"MSIE"
        },
        {
            string:navigator.userAgent,
            subString:"Android",
            identity:"Android",
            versionSearch:"Android"
        }
    ],
    dataOS:[
        {
            string:navigator.userAgent,
            subString:"Windows Phone",
            identity:"Windows Phone"
        },
        {
            string:navigator.platform,
            subString:"Win",
            identity:"Windows"
        },
        {
            string:navigator.platform,
            subString:"Mac",
            identity:"Mac"
        },
        {
            string:navigator.userAgent,
            subString:"iPhone",
            identity:"IOS"
        },
        {
            string:navigator.userAgent,
            subString:"iPod",
            identity:"IOS"
        },
        {
            string:navigator.userAgent,
            subString:"iPad",
            identity:"IOS"
        },
        {
            string:navigator.userAgent,
            subString:"AuthorViewer",
            identity:"IOS"
        },
        {
            string:navigator.platform,
            subString:"Linux",
            identity:"Linux"
        },
        {
            string:navigator.userAgent,
            subString:"Android",
            identity:"Android"
        }
    ],
    Hardware:[
        {
            string:navigator.userAgent,
            subString:"iTouch",
            identity:"iTouch"
        },
        {
            string:navigator.userAgent,
            subString:"iPad",
            identity:"iPad"
        },
        {
            string:navigator.userAgent,
            subString:"iPhone",
            identity:"iPhone"
        }
    ]
};
BrowserDetect.init();
AuthorCommons = {
    setupKeyNameMap:function () {
        Author.keyNameMap[1] = "LButton";//Left mouse button.
        Author.keyNameMap[2] = "RButton";//Right mouse button.
        Author.keyNameMap[3] = "Cancel";//CANCEL key.
        Author.keyNameMap[4] = "MButton";//Middle mouse button.
        Author.keyNameMap[8] = "Back";//BACKSPACE key.
        Author.keyNameMap[9] = "Tab";//TAB key.
        Author.keyNameMap[12] = "Clear";//CLEAR key.
        Author.keyNameMap[13] = "Return";//ENTER key.
        Author.keyNameMap[16] = "Shift";//SHIFT key.
        Author.keyNameMap[17] = "Control";//CTRL key.
        Author.keyNameMap[18] = "Menu";//MENU key.
        Author.keyNameMap[19] = "Pause";//PAUSE key.
        Author.keyNameMap[20] = "Capital";//CAPS LOCK key.
        Author.keyNameMap[27] = "Escape";//ESC key.
        Author.keyNameMap[32] = "Space";//SPACEBAR key.
        Author.keyNameMap[33] = "PageUp";//PAGE UP key.
        Author.keyNameMap[34] = "PageDown";//PAGE DOWN key.
        Author.keyNameMap[35] = "End";//END key.
        Author.keyNameMap[36] = "Home";//HOME key.
        Author.keyNameMap[37] = "Left";//LEFT ARROW key.
        Author.keyNameMap[38] = "Up";//UP ARROW key.
        Author.keyNameMap[39] = "Right";//RIGHT ARROW key.
        Author.keyNameMap[40] = "Down";//DOWN ARROW key.
        Author.keyNameMap[41] = "Select";//SELECT key.
        Author.keyNameMap[42] = "Print";//PRINT SCREEN key.
        Author.keyNameMap[43] = "Execute";//EXECUTE key.
        Author.keyNameMap[44] = "Snapshot";//SNAPSHOT key.
        Author.keyNameMap[45] = "Insert";//INS key.
        Author.keyNameMap[46] = "Delete";//DEL key.
        Author.keyNameMap[47] = "Help";//HELP key.
        Author.keyNameMap[144] = "Numlock";//NUM LOCK key.
        Author.keyNameMap[65] = "A";//A key.
        Author.keyNameMap[66] = "B";//B key.
        Author.keyNameMap[67] = "C";//C key.
        Author.keyNameMap[68] = "D";//D key.
        Author.keyNameMap[69] = "E";//E key.
        Author.keyNameMap[70] = "F";//F key.
        Author.keyNameMap[71] = "G";//G key.
        Author.keyNameMap[72] = "H";//H key.
        Author.keyNameMap[73] = "I";//I key.
        Author.keyNameMap[74] = "J";//J key.
        Author.keyNameMap[75] = "K";//K key.
        Author.keyNameMap[76] = "L";//L key.
        Author.keyNameMap[77] = "M";//M key.
        Author.keyNameMap[78] = "N";//N key.
        Author.keyNameMap[79] = "O";//O key.
        Author.keyNameMap[80] = "P";//P key.
        Author.keyNameMap[81] = "Q";//Q key.
        Author.keyNameMap[82] = "R";//R key.
        Author.keyNameMap[83] = "S";//S key.
        Author.keyNameMap[84] = "T";//T key.
        Author.keyNameMap[85] = "U";//U key.
        Author.keyNameMap[86] = "V";//V key.
        Author.keyNameMap[87] = "W";//W key.
        Author.keyNameMap[88] = "X";//X key.
        Author.keyNameMap[89] = "Y";//Y key.
        Author.keyNameMap[90] = "Z";//Z key.
        Author.keyNameMap[48] = "0";//0 key.
        Author.keyNameMap[49] = "1";//1 key.
        Author.keyNameMap[50] = "2";//2 key.
        Author.keyNameMap[51] = "3";//3 key.
        Author.keyNameMap[52] = "4";//4 key.
        Author.keyNameMap[53] = "5";//5 key.
        Author.keyNameMap[54] = "6";//6 key.
        Author.keyNameMap[55] = "7";//7 key.
        Author.keyNameMap[56] = "8";//8 key.
        Author.keyNameMap[57] = "9";//9 key.
        Author.keyNameMap[96] = "Numpad0";//0 key.
        Author.keyNameMap[97] = "Numpad1";//1 key.
        Author.keyNameMap[98] = "Numpad2";//2 key.
        Author.keyNameMap[99] = "Numpad3";//3 key.
        Author.keyNameMap[100] = "Numpad4";//4 key.
        Author.keyNameMap[101] = "Numpad5";//5 key.
        Author.keyNameMap[102] = "Numpad6";//6 key.
        Author.keyNameMap[103] = "Numpad7";//7 key.
        Author.keyNameMap[104] = "Numpad8";//8 key.
        Author.keyNameMap[105] = "Numpad9";//9 key.
        Author.keyNameMap[106] = "Multiply";//MULTIPLICATION SIGN [*] key.
        Author.keyNameMap[107] = "Add";//PLUS SIGN [+] key.
        Author.keyNameMap[108] = "Separator";//ENTER key.
        Author.keyNameMap[109] = "Subtract";//MINUS SIGN [-] key.
        Author.keyNameMap[110] = "Decimal";//DECIMAL POINT[.] key.
        Author.keyNameMap[111] = "Divide";//DIVISION SIGN [/] key.
        Author.keyNameMap[112] = "F1";//F1 key.
        Author.keyNameMap[113] = "F2";//F2 key.
        Author.keyNameMap[114] = "F3";//F3 key.
        Author.keyNameMap[115] = "F4";//F4 key.
        Author.keyNameMap[116] = "F5";//F5 key.
        Author.keyNameMap[117] = "F6";//F6 key.
        Author.keyNameMap[118] = "F7";//F7 key.
        Author.keyNameMap[119] = "F8";//F8 key.
        Author.keyNameMap[120] = "F9";//F9 key.
        Author.keyNameMap[121] = "F10";//F10 key.
        Author.keyNameMap[122] = "F11";//F11 key.
        Author.keyNameMap[123] = "F12";//F12 key.
        Author.keyNameMap[124] = "F13";//F13 key.
        Author.keyNameMap[125] = "F14";//F14 key.
        Author.keyNameMap[126] = "F15";//F15 key.
        Author.keyNameMap[127] = "F16";//F16 key.
        Author.keyNameMap[186] = ";";//; key.
        Author.keyNameMap[187] = "=";//= key.
        Author.keyNameMap[188] = ",";//, key.
        Author.keyNameMap[189] = "-";//- key.
        Author.keyNameMap[190] = ".";//. key.
        Author.keyNameMap[191] = "/";/// key.
        Author.keyNameMap[192] = "`";// ` key.
        Author.keyNameMap[219] = "[";//[ key.
        Author.keyNameMap[220] = "\\";//\ key.
        Author.keyNameMap[221] = "]";//] key.
        Author.keyNameMap[222] = "'";//' key.
    },
    getActionInfoFromElementID:function (fromID) {
        var match = fromID.match(Author.ActionTypeReg);

        if (match) {
            return  {
                ActionType:match[1],
                ActionID:(match.length > 2 ? match[2] : null),
                ComponentType:(match.length > 4 ? match[4] : null)
            };
        }
        else {
            return null;
        }
    },
    confirmExit:function () {
        return "Are you sure you want to exit this module?";
    },
    getBrowserInfo:function () {

        return " [HTML " + BrowserDetect.browser + " " + BrowserDetect.version + " / " + BrowserDetect.OS + "," + BrowserDetect.hardware + "]";
    }
}


