// JQuery URL Toolbox
// Written by Mark Perkins, mark@allmarkedup.com
// License: http://unlicense.org/ (i.e. do what you want with it!)
// https://github.com/allmarkedup/jQuery-URL-Toolbox
/* updated 28/10/2011 by upadrian
/*
Use var myUrl = $(element).url() to grab an element's URL and return a special 'URL' object. (a, form, img, base, link and iframe 
elements are supported, and using 'document' (no quotes) as the selector will return a URL object based on the current page's URL)
Then use myUrl.attr('theAttr') to return any part of the URL, where 'theAttr' can be any one of: source, protocol, host, port, 
query, file, hash or path.
If you include a second argument to the attr() method – i.e. something like myUrl.attr('path', '/myNewPath/'), then it will 
set the value of that part of the URL to the value of the second argument. Whatever the URL of element the initial url() 
function was called on will be updated accordingly. If the document URL was used (via $(document).url()) then the location
will be changed accordingly, normally resulting in a page refresh.
Doing a .toString() on the URL object at any time will return the current string representation of the URL.
The .segment(i) method (where 'i' is the segment number, starting from zero) will return the corresponding segment from the URL. 
Including a second parameter will set that segment.
The .param('key') method (where 'key' is the query string key) will return the corresponding value of the suppied key in the URL 
query (GET) string, if there is one. Including a second parameter will set that parameter.
If you have a hash fragment that consists of segments, like #/part1/part2/ then you can get/set those segments using the 
hashSegment() method, which works exactly like the segment() one.
Similarly if you have a hash fragment that looks like a query string, the parts can be get/set using the hashParam() method.
*/


(function(a){function t(a){var b=document.createElement("a");b.href=a;if(b.protocol==":")b.protocol="http:";return{source:a,protocol:b.protocol.replace(":",""),host:s(b.hostname,b.port),base:function(){if(b.port!=0&&b.port!==null&&b.port!=="")return b.protocol+"//"+s(b.hostname,b.port)+":"+b.port;return b.protocol+"//"+b.host}(),port:b.port,query:b.search,params:l(b.search),file:(b.pathname.match(/\/([^\/?#]+)$/i)||[,""])[1],hash:h(b.hash),path:function(){var a=b.pathname.replace(/^([^\/])/,"/$1");if(a=="/")a="";return a}(),segments:b.pathname.replace(/^\//,"").split("/"),hashSegments:o(h(b.hash)),hashParams:p(h(b.hash))}}function p(a){if(a.indexOf("=")!==-1)return l(a);return null}function o(a){if(a.indexOf("=")===-1){if(a.charAt(a.length-1)=="/")a=a.slice(0,-1);return a.replace(/^\//,"").split("/")}return null}function l(a){var b={},c=a.replace(/^\?/,"").split("&"),d=c.length,e=0,f;for(;e<d;e++){if(!c[e]){continue}f=c[e].split("=");b[f[0]]=f[1]}return b}var b=function(a){return typeof a==="string"};var c=function(a){return typeof a==="object"};var d=function(a){return typeof a==="function"};var e=function(a){return a.length==1&&!c(a[0])};var f=function(a){return a.length>=2||a.length==1&&c(a[0])};var g=function(a){return a.replace(/\?.*$/,"")};var h=function(a){return a.replace(/^#/,"")};var j=document.location,k={a:"href",img:"src",form:"action",base:"href",script:"src",iframe:"src",link:"href"};var m=function(a,b){var c=b===true?"?":"";for(i in a)c+=i+"="+a[i]+"&";return c.slice(0,-1)};var n=function(a){return a.join("/")};var q=function(b){var c=a(b).get(0).tagName;if(c!==undefined)return c.toLowerCase();return c};var r=function(a){if(a===undefined)a="url parser error"};var s=function(a,b){var c=new RegExp(":"+b);return a.replace(c,"")};a.extend(a.expr[":"],{external:function(a,b,c){var d=a.tagName;if(d!==undefined){var e=d.toLowerCase();var f=k[e];if(a[f]){if(e!=="a"){var g=document.createElement("a");g.href=a[f]}else var g=a;return g.hostname&&s(g.hostname,g.port)!==s(j.hostname,j.port)}}return false},internal:function(a,b,c){var d=a.tagName;if(d!==undefined){var e=d.toLowerCase();var f=k[e];if(a[f]){if(e!=="a"){var g=document.createElement("a");g.href=a[f]}else var g=a;return g.hostname&&s(g.hostname,g.port)===s(j.hostname,j.port)}}return false}});a.url=function(a){return new u(a)};a.fn.url=function(){if(this.size()>1){var b={};this.each(function(c){b[c]=new u(a(this))});return b}else{return new u(this)}};var u=function(b){var d=null,g=null,i={};var u=function(a){var b="";if(i.hashParams!=null){b=makeQueryString(i.hashParams)}else if(i.hashSegments!=null){b=makePathString(i.hashSegments)}if(b!==""){if(i.hash.charAt(0)=="/")b="/"+b;if(a===true)return"#"+b;return b}return""};var v=function(){if(d=="elm"){g.attr(k[q(g)],i.source)}else if(d=="doc"){j.href=i.source}};var w=function(){i.source=i.base+i.path+i.query;if(i.hash&&i.hash!="")i.source+="#"+i.hash};var x=function(a,b){switch(a){case"source":i=t(b);break;case"base":if(b.charAt(b.length-1)=="/")b=b.slice(0,-1);var c=document.createElement("a");c.href=i.base=b;i.protocol=c.protocol.replace(":","");i.host=s(c.hostname,c.port);i.port=c.port;break;case"protocol":case"host":case"port":i[a]=b;if(c.port!=0&&c.port!==null&&c.port!=="")i.base=c.protocol+"//"+s(c.hostname,c.port)+":"+c.port;else i.base=c.protocol+"//"+c.host;break;case"query":i.query="?"+b.replace(/\?/,"");i.params=l(b);break;case"file":i.path=i.path.replace(new RegExp(i.file+"$"),b);i.file=b;break;case"hash":i.hash=b;i.hashSegments=o(b);i.hashParams=p(b);break;case"path":if(b.charAt(0)!="/")b="/"+b;i.path=b;i.file=(b.match(/\/([^\/?#]+)$/i)||[,""])[1];i.segments=b.replace(/^\//,"").split("/");break;default:r("you can't update this property directly");break}w()};var y=function(a,b){i.params[a]=b;i.query=m(i.params,true);w()};var z=function(a,b){i.segments[a]=b;i.path="/"+n(i.segments);i.file=(i.path.match(/\/([^\/?#]+)$/i)||[,""])[1];w()};var A=function(a,b){i.hashParams[a]=b;i.hash=m(i.hashParams,true);w()};var B=function(a,b){var c=i.hash.charAt(0)=="/"?"/":"";i.hashSegments[a]=b;i.hash=c+n(i.hashSegments);w()};var C=function(a,b,d){if(e(d)){var g=d[0];return a===undefined||a[g]===undefined||a[g]===""?null:a[g]}else if(f(d)){if(c(d[0])){for(var g in d[0])b(g,d[0][g]);if(d[1]!==false)v()}else{b(d[0],d[1]);if(d[2]!==false)v()}return this}};var D=function(){if(c(b)&&b.size()){urlAttr=undefined;var e=q(b);if(e!==undefined)urlAttr=k[e];if(e!==undefined&&urlAttr!==undefined){d="elm";g=b;var f=b.attr(urlAttr)}else if(e!==undefined&&urlAttr===undefined){r("no valid URL on object");return}else{d="doc";var f=j.href;a(window).bind("hashchange",function(a){x("hash",h(j.hash))})}}else if(!c(b)){d="str";var f=b}else{r("no valid item");return}i=t(f)}();return{attr:function(){return C(i,x,arguments)},param:function(){return C(i.params,y,arguments)},segment:function(){return C(i.segments,z,arguments)},hashParam:function(){return C(i.hashParams,A,arguments)},hashSegment:function(){return C(i.hashSegments,B,arguments)},is:function(a){if(a==="internal"||a===":internal"){return i.host&&i.host===s(j.hostname)}else if(a==="external"||a===":external"){return i.host&&i.host!==s(j.hostname)}},toString:function(){return i.source}}}})(jQuery)
