/// <reference path="../debug.ts" />
var econda;
(function (econda) {
    var net;
    (function (net) {
        /**
         * Class represents a uri.
         * <h2>Examples</h2>
         *
         *     var uri = new econda.net.Uri("http://www.econda.de");
         *     console.log(uri.toString());
         *     // >> http://www.econda.de
         *
         *     console.log("Domain is: " + uri.getHost());
         *     // >> www.econda.de
         *
         * @class econda.net.Uri
         * @author Christoph Lütjen
         */
        var Uri = (function () {
            function Uri(uri) {
                /**
                 * Uri as string
                 * @property
                 * @private
                 */
                this.uri = null;
                /**
                 * @property {String}
                 * @private
                 */
                this.scheme = null;
                /**
                 * @property {String}
                 * @private
                 */
                this.host = null;
                /**
                 * @property {String}
                 * @private
                 */
                this.path = null;
                /**
                 * @property {String}
                 * @private
                 */
                this.query = null;
                /**
                 * @property {String}
                 * @private
                 */
                this.hash = null;
                if (uri instanceof Uri) {
                    return uri;
                }
                else {
                    this.uri = uri;
                    if (this.uri) {
                        this.parseUri();
                    }
                }
            }
            /**
             * Returns the scheme component of this URI.
             * @returns {String}
             */
            Uri.prototype.getScheme = function () {
                if (this.scheme) {
                    return this.scheme.toLowerCase();
                }
                else {
                    return null;
                }
            };
            Uri.prototype.setScheme = function (scheme) {
                var scheme = new String(scheme).toLocaleLowerCase();
                if (this.uri !== null) {
                    this.uri = this.uri.replace(/^\w*\:/, scheme + ':');
                }
                this.resetComponents();
                this.parseUri();
            };
            /**
             * Get host component of uri
             * @returns {String}
             */
            Uri.prototype.getHost = function () {
                return this.host;
            };
            /**
             * Get path component of uri
             * @returns {String}
             */
            Uri.prototype.getPath = function () {
                return this.path;
            };
            /**
             * Get filename component of uri
             * @returns {String}
             */
            Uri.prototype.getFilename = function () {
                var path = this.path;
                if (typeof path == 'string' && path.lastIndexOf('/') > -1) {
                    return path.substr(path.lastIndexOf('/') + 1);
                }
                else {
                    return null;
                }
            };
            /**
             * Get query component of uri
             * @returns {String}
             */
            Uri.prototype.getQuery = function () {
                return this.query;
            };
            /**
             * Get hash component of uri
             * @returns {String}
             */
            Uri.prototype.getHash = function () {
                return this.hash;
            };
            /**
             * Parse uri and write components to object properties.
             * @private
             * @chainable
             */
            Uri.prototype.parseUri = function () {
                var uri = this.uri;
                var regex = /^(?:([^:/?#]+):)?(?:\/\/([^/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/;
                var matches = uri.match(regex);
                this.scheme = matches[1] || null;
                this.host = matches[2] || null;
                this.path = matches[3] || null;
                this.query = matches[4] || null;
                this.hash = matches[5] || null;
                return this;
            };
            /**
             * Reset all properties containing components of this uri
             * @private
             * @chainable
             */
            Uri.prototype.resetComponents = function () {
                this.scheme = null;
                this.host = null;
                this.path = null;
                this.query = null;
                this.hash = null;
                return this;
            };
            /**
             * Get parameter value
             * @returns {String} value or null if parameter doesn't exist
             */
            Uri.prototype.getParam = function (name) {
                var parts = [];
                if (typeof this.query === 'string') {
                    parts = this.query.split('&');
                }
                var params = {};
                for (var n = 0; n < parts.length; n++) {
                    var itemParts = String(parts[n]).split('=');
                    params[itemParts[0]] = itemParts.length >= 2 ? itemParts[1] : '';
                }
                return params[name] || null;
            };
            /**
             * Appends uri parameters to existing uri
             *
             *     var uri = new econda.net.Uri("http://www.econda.de");
             *     uri.appendParams({myparam: "my value"});
             *     console.log(uri).toString();
             *     // >> http://www.econda.de?myparam=my%20value
             *
             * @param {Object} params Object with params
             * @returns {econda.net.Uri}
             */
            Uri.prototype.appendParams = function (params) {
                var uri = this.uri;
                var hashpos = uri.lastIndexOf('#'), baseUri = hashpos > -1 ? uri.substring(0, hashpos) : uri, hash = hashpos > -1 ? uri.substr(hashpos) : '', hasParams = (uri.indexOf('?') > -1), ret;
                ret = baseUri + (hasParams ? '&' : '?') + Uri.concatParams(params) + hash;
                this.uri = ret;
                this.resetComponents();
                this.parseUri();
                return this;
            };
            /**
             * Check if uri matches a given regular expression.
             * @param {RegExp} pattern
             * @returns {String[]}
             */
            Uri.prototype.match = function (pattern) {
                return this.uri.match(pattern);
            };
            /**
             * Clone object
             * @returns {econda.net.Uri}
             */
            Uri.prototype.clone = function () {
                var clone = new Uri(this.uri);
                return clone;
            };
            /**
             * Returns a string containing all given parameters.
             * @static
             * @param {Object} params Parameters as object
             * @returns {String} Parameters as string
             */
            Uri.concatParams = function (params) {
                var parts = [];
                for (var name in params) {
                    parts.push(name + '=' + encodeURIComponent(params[name]));
                }
                return parts.join('&');
            };
            /**
             * @return {string} protocol to use
             */
            Uri.detectProtocol = function () {
                return (typeof location.protocol === 'string' && location.protocol === 'https:') ? 'https' : 'http';
            };
            /**
             * Returns uri as string
             * @returns {String}
             */
            Uri.prototype.toString = function () {
                return this.uri;
            };
            /**
             * Constant for http protocol
             * @property
             * @static
             */
            Uri.SCHEME_HTTP = 'http';
            /**
             * Constant for https protocol
             * @property
             * @static
             */
            Uri.SCHEME_HTTPS = 'https';
            /**
             * Constant for ftp protocol
             * @property
             * @static
             */
            Uri.SCHEME_FTP = 'ftp';
            return Uri;
        }());
        net.Uri = Uri;
    })(net = econda.net || (econda.net = {}));
})(econda || (econda = {}));