# Source: utils/Utils.js

    /* jshint supernew: true */

    /**
    * @author       Richard Davey <rich@photonstorm.com>
    * @copyright    2014 Photon Storm Ltd.
    * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
    */

    /**
    * @class Phaser.Utils
    * @static
    */
    Phaser.Utils = {

        /**
         * Transposes the elements of the given Array.
         *
         * @method transposeArray
         * @param {array} array - The array to transpose.
         * @return {array} The transposed array.
         */
        transposeArray: function (array) {

            var result = new Array(array[0].length);

            for (var i = 0; i < array[0].length; i++)
            {
                result[i] = new Array(array.length - 1);

                for (var j = array.length - 1; j > -1; j--)
                {
                    result[i][j] = array[j][i];
                }
            }

            return result;

        },

        /**
         * Rotates the given array.
         * Based on the routine from http://jsfiddle.net/MrPolywhirl/NH42z/
         *
         * @method Phaser.Utils.rotateArray
         * @param {array} matrix - The array to rotate.
         * @param {number|string} direction - The amount to rotate. Either a number: 90, -90, 270, -270, 180 or a string: 'rotateLeft', 'rotateRight' or 'rotate180'
         * @return {array} The rotated array
         */
        rotateArray: function (matrix, direction) {

            if (typeof direction !== 'string')
            {
                direction = ((direction % 360) + 360) % 360;
            }

            if (direction === 90 || direction === -270 || direction === 'rotateLeft')
            {
                matrix = Phaser.Utils.transposeArray(matrix);
                matrix = matrix.reverse();
            }
            else if (direction === -90 || direction === 270 || direction === 'rotateRight')
            {
                matrix = matrix.reverse();
                matrix = Phaser.Utils.transposeArray(matrix);
            }
            else if (Math.abs(direction) === 180 || direction === 'rotate180')
            {
                for (var i = 0; i < matrix.length; i++)
                {
                    matrix[i].reverse();
                }

                matrix = matrix.reverse();
            }

            return matrix;

        },

        /**
        * Get a unit dimension from a string.
        *
        * @method Phaser.Utils.parseDimension
        * @param {string|number} size - The size to parse.
        * @param {number} dimension - The window dimension to check.
        * @return {number} The parsed dimension.
        */
        parseDimension: function (size, dimension) {

            var f = 0;
            var px = 0;

            if (typeof size === 'string')
            {
                //  %?
                if (size.substr(-1) === '%')
                {
                    f = parseInt(size, 10) / 100;

                    if (dimension === 0)
                    {
                        px = window.innerWidth * f;
                    }
                    else
                    {
                        px = window.innerHeight * f;
                    }
                }
                else
                {
                    px = parseInt(size, 10);
                }
            }
            else
            {
                px = size;
            }

            return px;

        },

        /**
        * A standard Fisher-Yates Array shuffle implementation.
        * @method Phaser.Utils.shuffle
        * @param {array} array - The array to shuffle.
        * @return {array} The shuffled array.
        */
        shuffle: function (array) {

            for (var i = array.length - 1; i > 0; i--)
            {
                var j = Math.floor(Math.random() * (i + 1));
                var temp = array[i];
                array[i] = array[j];
                array[j] = temp;
            }

            return array;

        },

        /**
        * Javascript string pad http://www.webtoolkit.info/.
        * pad = the string to pad it out with (defaults to a space)
        * dir = 1 (left), 2 (right), 3 (both)
        * @method Phaser.Utils.pad
        * @param {string} str - The target string.
        * @param {number} len - The number of characters to be added.
        * @param {number} pad - The string to pad it out with (defaults to a space).
        * @param {number} [dir=3] The direction dir = 1 (left), 2 (right), 3 (both).
        * @return {string} The padded string
        */
        pad: function (str, len, pad, dir) {

            if (typeof(len) == "undefined") { var len = 0; }
            if (typeof(pad) == "undefined") { var pad = ' '; }
            if (typeof(dir) == "undefined") { var dir = 3; }

            var padlen = 0;

            if (len + 1 >= str.length)
            {
                switch (dir)
                {
                    case 1:
                        str = new Array(len + 1 - str.length).join(pad) + str;
                        break;

                    case 3:
                        var right = Math.ceil((padlen = len - str.length) / 2);
                        var left = padlen - right;
                        str = new Array(left+1).join(pad) + str + new Array(right+1).join(pad);
                        break;

                    default:
                        str = str + new Array(len + 1 - str.length).join(pad);
                        break;
                }
            }

            return str;

        },

        /**
        * This is a slightly modified version of jQuery.isPlainObject. A plain object is an object whose internal class property is [object Object].
        * @method Phaser.Utils.isPlainObject
        * @param {object} obj - The object to inspect.
        * @return {boolean} - true if the object is plain, otherwise false.
        */
        isPlainObject: function (obj) {

            // Not plain objects:
            // - Any object or value whose internal [[Class]] property is not "[object Object]"
            // - DOM nodes
            // - window
            if (typeof(obj) !== "object" || obj.nodeType || obj === obj.window)
            {
                return false;
            }

            // Support: Firefox <20
            // The try/catch suppresses exceptions thrown when attempting to access
            // the "constructor" property of certain host objects, ie. |window.location|
            // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
            try {
                if (obj.constructor && !({}).hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf"))
                {
                    return false;
                }
            } catch (e) {
                return false;
            }

            // If the function hasn't returned already, we're confident that
            // |obj| is a plain object, created by {} or constructed with new Object
            return true;
        },

        /**
        * This is a slightly modified version of http://api.jquery.com/jQuery.extend/
        * @method Phaser.Utils.extend
        * @param {boolean} deep - Perform a deep copy?
        * @param {object} target - The target object to copy to.
        * @return {object} The extended object.
        */
        extend: function () {

            var options, name, src, copy, copyIsArray, clone,
                target = arguments[0] || {},
                i = 1,
                length = arguments.length,
                deep = false;

            // Handle a deep copy situation
            if (typeof target === "boolean")
            {
                deep = target;
                target = arguments[1] || {};
                // skip the boolean and the target
                i = 2;
            }

            // extend Phaser if only one argument is passed
            if (length === i)
            {
                target = this;
                --i;
            }

            for (; i < length; i++)
            {
                // Only deal with non-null/undefined values
                if ((options = arguments[i]) != null)
                {
                    // Extend the base object
                    for (name in options)
                    {
                        src = target[name];
                        copy = options[name];

                        // Prevent never-ending loop
                        if (target === copy)
                        {
                            continue;
                        }

                        // Recurse if we're merging plain objects or arrays
                        if (deep && copy && (Phaser.Utils.isPlainObject(copy) || (copyIsArray = Array.isArray(copy))))
                        {
                            if (copyIsArray)
                            {
                                copyIsArray = false;
                                clone = src && Array.isArray(src) ? src : [];
                            }
                            else
                            {
                                clone = src && Phaser.Utils.isPlainObject(src) ? src : {};
                            }

                            // Never move original objects, clone them
                            target[name] = Phaser.Utils.extend(deep, clone, copy);

                        // Don't bring in undefined values
                        }
                        else if (copy !== undefined)
                        {
                            target[name] = copy;
                        }
                    }
                }
            }

            // Return the modified object
            return target;
        }

    };

    /**
    * A polyfill for Function.prototype.bind
    */
    if (typeof Function.prototype.bind != 'function') {

        /* jshint freeze: false */
        Function.prototype.bind = (function () {

            var slice = Array.prototype.slice;

            return function (thisArg) {

                var target = this, boundArgs = slice.call(arguments, 1);

                if (typeof target != 'function')
                {
                    throw new TypeError();
                }

                function bound() {
                    var args = boundArgs.concat(slice.call(arguments));
                    target.apply(this instanceof bound ? this : thisArg, args);
                }

                bound.prototype = (function F(proto) {
                    if (proto)
                    {
                        F.prototype = proto;
                    }

                    if (!(this instanceof F))
                    {
                        return new F;
                    }
                })(target.prototype);

                return bound;
            };
        })();
    }

    /**
    * A polyfill for Array.isArray
    */
    if (!Array.isArray)
    {
        Array.isArray = function (arg)
        {
            return Object.prototype.toString.call(arg) == '[object Array]';
        };
    }

    /**
    * A polyfill for Array.forEach
    * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
    */
    if (!Array.prototype.forEach)
    {
        Array.prototype.forEach = function(fun /*, thisArg */)
        {
            "use strict";

            if (this === void 0 || this === null)
            {
                throw new TypeError();
            }

            var t = Object(this);
            var len = t.length >>> 0;

            if (typeof fun !== "function")
            {
                throw new TypeError();
            }

            var thisArg = arguments.length >= 2 ? arguments[1] : void 0;

            for (var i = 0; i < len; i++)
            {
                if (i in t)
                {
                    fun.call(thisArg, t[i], i, t);
                }
            }
        };
    }

    /**
    * Low-budget Float32Array knock-off, suitable for use with P2.js in IE9
    * Source: http://www.html5gamedevs.com/topic/5988-phaser-12-ie9/
    * Cameron Foale (http://www.kibibu.com)
    */
    if (typeof window.Uint32Array !== "function")
    {
        var CheapArray = function(type)
        {
            var proto = new Array(); // jshint ignore:line

            window[type] = function(arg) {

                if (typeof(arg) === "number")
                {
                    Array.call(this, arg);
                    this.length = arg;

                    for (var i = 0; i < this.length; i++)
                    {
                        this[i] = 0;
                    }
                }
                else
                {
                    Array.call(this, arg.length);

                    this.length = arg.length;

                    for (var i = 0; i < this.length; i++)
                    {
                        this[i] = arg[i];
                    }
                }
            };

            window[type].prototype = proto;
            window[type].constructor = window[type];
        };

        CheapArray('Uint32Array'); // jshint ignore:line
        CheapArray('Int16Array');  // jshint ignore:line
    }

    /**
     * Also fix for the absent console in IE9
     */
    if (!window.console)
    {
        window.console = {};
        window.console.log = window.console.assert = function(){};
        window.console.warn = window.console.assert = function(){};
    }