/**
 * Copyright (C) 2010-2011 Graham Breach
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
/**
 * jQuery.tagcanvas 1.6.1
 * For more information, please contact <graham@goat1000.com>
 */
(function(b){Point3D=function(c,e,d){this.x=c;this.y=e;this.z=d};RotX=function(f,d){var e=Math.sin(d),g=Math.cos(d);return new Point3D(f.x,(f.y*g)+(f.z*e),(f.y*-e)+(f.z*g))};RotY=function(f,d){var e=Math.sin(d),g=Math.cos(d);return new Point3D((f.x*g)+(f.z*-e),f.y,(f.x*e)+(f.z*g))};RotZ=function(f,d){var e=Math.sin(d),g=Math.cos(d);return new Point3D((f.x*g)+(f.y*e),(f.x*-e)+(f.y*g),f.z)};Project=function(e,l,k,i,f,d){var c,g,j;c=(l.y*e.z1)/(e.z1+e.z2+l.z);g=(l.x*e.z1)/(e.z1+e.z2+l.z);j=e.z2+l.z;return new Point3D(g,c,j)};function a(){this.Draw=function(){var f=this.canvas,k=0,g,j,l,e,h;l=f.getContext("2d");l.setTransform(1,0,0,1,0,0);l.clearRect(0,0,f.width,f.height);g=f.width/2;j=f.height/2;this.active=null;for(h=0;h<this.taglist.length;++h){this.taglist[h].Calc(this.yaw,this.pitch)}this.taglist=this.taglist.sort(function(m,i){return m.sc-i.sc});for(h=0;h<this.taglist.length;++h){e=this.taglist[h].Draw(l,g,j);if(e&&e.sc>k){this.active=e;this.active.index=h;k=e.sc}}if(this.freezeActive&&this.active){this.yaw=this.pitch=0}else{this.Animate(f.width,f.height)}if(this.active){this.active.Draw(l)}};this.Animate=function(e,g){if(this.mx>=0&&this.my>=0&&this.mx<e&&this.my<g){this.yaw=(this.maxSpeed*2*this.mx/e)-this.maxSpeed;this.pitch=-((this.maxSpeed*2*this.my/g)-this.maxSpeed);if(this.reverse){this.yaw=-this.yaw;this.pitch=-this.pitch}this.initial=null}else{if(!this.initial){var i=Math.abs(this.yaw),f=Math.abs(this.pitch);if(i>this.minSpeed){this.yaw=i>this.z0?this.yaw*this.decel:0}if(f>this.minSpeed){this.pitch=f>this.z0?this.pitch*this.decel:0}}}};this.Clicked=function(g){try{if(this.active&&this.taglist[this.active.index]){this.taglist[this.active.index].Clicked(g)}}catch(f){}};this.Outline=function(e){this.tc=e;this.ts=new Date();this.Update=function(f,k,g,i,j){this.x=j*(f-this.tc.outlineOffset);this.y=j*(k-this.tc.outlineOffset);this.w=j*(g+this.tc.outlineOffset*2);this.h=j*(i+this.tc.outlineOffset*2);this.sc=j};this.Draw=function(g){var f=new Date()-this.ts;g.setTransform(1,0,0,1,0,0);g.strokeStyle=this.tc.outlineColour;g.lineWidth=this.tc.outlineThickness;g.shadowBlur=g.shadowOffsetX=g.shadowOffsetY=0;if(this.tc.pulsateTo<1){g.globalAlpha=this.tc.pulsateTo+((1-this.tc.pulsateTo)*(0.5+(Math.cos(2*Math.PI*f/(1000*this.tc.pulsateTime))/2)))}else{g.globalAlpha=1}g.strokeRect(this.x,this.y,this.w,this.h)};this.Active=function(h,f,g){return(f>=this.x&&g>=this.y&&f<=this.x+this.w&&g<=this.y+this.h)};this.Update(0,0,0,0,1)};this.Tag=function(f,k,i,j,g,l){this.tc=f;this.image=k.src?k:null;this.name=k.src?"":k;this.a=i;this.p3d=new Point3D;this.p3d.x=j[0]*f.radius*1.1;this.p3d.y=j[1]*f.radius*1.1;this.p3d.z=j[2]*f.radius*1.1;this.x=0;this.y=0;this.w=g;this.h=l;this.colour=f.textColour;this.weight=1;this.weighted=!f.weight;if(!this.image){if(f.weight){var e=1,m;if(document.defaultView&&document.defaultView.getComputedStyle){m=document.defaultView.getComputedStyle(i,null).getPropertyValue("font-size");e=m.replace("px","")*1}else{f.weight=false}if(e>f.max_weight){f.max_weight=e}if(e<f.min_weight){f.min_weight=e}this.weight=e}this.textHeight=f.textHeight;this.extents=a.FindTextBoundingBox(this.name,this.tc.textFont,this.textHeight);if(this.extents){this.h=this.extents.max.y}}this.sc=1;this.alpha=1;this.outline=new f.Outline(f);this.Weight=function(r,p){var n,h,q,o;if(p.weightMode=="colour"||p.weightMode=="both"){n=p.canvas.height*(1+p.max_weight-p.min_weight);h=p.canvas.height*(1+this.weight-p.min_weight);q=r.createLinearGradient(0,h-n,0,h);for(o in p.weightGradient){q.addColorStop(o,p.weightGradient[o])}this.colour=q}if(p.weightMode=="size"||p.weightMode=="both"){this.textHeight=this.weight*p.weightSize}this.extents=a.FindTextBoundingBox(this.name,p.textFont,this.textHeight);if(this.extents){this.h=this.extents.max.y}this.weighted=true};this.Draw=function(r,h,q){var o=this.tc,n,p;if(!this.image&&o.weight&&!this.weighted){this.Weight(r,o)}r.globalAlpha=this.alpha;r.setTransform(this.sc,0,0,this.sc,0,0);h=h/this.sc;q=q/this.sc;r.textBaseline="top";r.fillStyle=this.colour;if(o.shadowBlur||o.shadowOffset[0]||o.shadowOffset[1]){r.shadowColor=o.shadow;r.shadowColor=a.SetAlpha(r.shadowColor,this.alpha);r.shadowBlur=o.shadowBlur;r.shadowOffsetX=o.shadowOffset[0];r.shadowOffsetY=o.shadowOffset[1]}r.font=this.textHeight+"px "+o.textFont;if(this.image){this.w1=this.w*this.sc;this.h1=this.h*this.sc}else{if(!this.w1){this.w1=r.measureText(this.name).width+2}if(this.extents){this.h1=this.extents.max.y+this.extents.min.y}else{this.h1=this.h}}n=h,p=q;h=h-(this.w1/2);q=q-(this.h1/2);if(this.image){r.drawImage(this.image,h+this.x,q+this.y,this.image.width*this.sc,this.image.height*this.sc)}else{r.fillText(this.name,h+this.x+1,q+this.y+1,this.w1-2)}this.outline.Update(n+this.x-this.w1/2,p+this.y-this.h1/2,this.w1,this.h1,this.sc);if(this.outline.Active(r,o.mx,o.my)){return this.outline}return null};this.Calc=function(o,n){var h=RotY(this.p3d,o);this.p3d=RotX(h,n);h=Project(this.tc,this.p3d,this.w,this.h,Math.PI/4,20);this.x=h.x;this.y=h.y;this.sc=(this.tc.z1+this.tc.z2-h.z)/this.tc.z2;this.alpha=Math.min(1,this.tc.minBrightness+1-((h.z-this.tc.z2+this.tc.radius)/(2*this.tc.radius)));if(this.alpha>1){console.log(this.alpha)}};this.Clicked=function(n){if(this.a.target!=""&&this.a.target!="_self"){if(self.frames[this.a.target]){self.frames[this.a.target]=this.a.href}else{if(top.frames[this.a.target]){top.frames[this.a.target]=this.a.href}else{window.open(this.a.href,this.a.target)}}return}if(this.a.fireEvent){if(!this.a.fireEvent("onclick")){return}}else{var h=document.createEvent("MouseEvents");h.initMouseEvent("click",true,true,window,0,0,0,0,0,false,false,false,false,0,null);if(!this.a.dispatchEvent(h)){return}}document.location=this.a.href}};this.PointsOnSphere=function(m){var e,l,g,f,k=[],h=Math.PI*(3-Math.sqrt(5)),j=2/m;for(e=0;e<m;++e){l=e*j-1+(j/2);g=Math.sqrt(1-l*l);f=e*h;k.push([Math.cos(f)*g,l,Math.sin(f)*g])}return k};this.AddImage=function(g,f,e){if(g.complete){f.w=g.width;f.h=g.height;e.push(f)}else{jQuery(g).bind("load",function(){f.w=this.width;f.h=this.height;e.push(f)})}};var c,d={mx:-1,my:-1,cx:0,cy:0,z1:20000,z2:20000,z0:0.0002,freezeActive:false,pulsateTo:1,pulsateTime:3,reverse:false,depth:0.5,maxSpeed:0.05,minSpeed:0,decel:0.95,initial:null,hideTags:true,minBrightness:0.1,outlineColour:"#ffff99",outlineThickness:2,outlineOffset:5,textColour:"#ff99ff",textHeight:15,textFont:"Helvetica, Arial, sans-serif",shadow:"#000",shadowBlur:0,shadowOffset:[0,0],zoom:1,weight:false,weightMode:"size",weightSize:1,weightGradient:{0:"#f00",0.33:"#ff0",0.66:"#0f0",1:"#00f"}};for(c in d){this[c]=d[c]}this.max_weight=0;this.min_weight=200}a.MouseMove=function(g){var f,d,c=document.documentElement;for(f in a.tc){d=a.tc[f];if(g.pageX){d.mx=g.pageX-d.cx;d.my=g.pageY-d.cy}else{d.mx=g.clientX+(c.scrollLeft?c.scrollLeft:document.body.scrollLeft)-d.cx;d.my=g.clientY+(c.scrollTop?c.scrollTop:document.body.scrollTop)-d.cy}}};a.MouseClick=function(g){var d=a,c=document.addEventListener?0:1,f=g.target?g.target.id:g.srcElement.parentNode.id;if(g.button==c&&d.tc[f]){d.MouseMove(g);d.tc[f].Clicked(g)}};a.DrawCanvas=function(){var d=a,c;for(c in d.tc){d.tc[c].Draw()}};a.tc={};a.SetAlpha=function(i,e){var h=i,g,f;e=new Number(e).toPrecision(3);if(i[0]=="#"){if(i.length==4){i="#"+i[1]+i[1]+i[2]+i[2]+i[3]+i[3]}h="rgba("+parseInt(i.substr(1,2),16)+","+parseInt(i.substr(3,2),16)+","+parseInt(i.substr(5,2),16)+","+e+")"}else{if(i.substr(0,4)=="rgb("||i.substr(0,4)=="hsl("){h=(i.replace("(","a(").replace(")",","+e+")"))}else{if(i.substr(0,5)=="rgba("||i.substr(0,5)=="hsla("){g=i.lastIndexOf(",")+1,f=i.indexOf(")");e*=parseFloat(i.substring(g,f));h=i.substr(0,g)+e.toPrecision(3)+")"}else{h=i}}}return h};a.FindTextBoundingBox=function(u,l,r){if(window.G_vmlCanvasManager){return null}var g=document.createElement("canvas"),o,t,k,d,j,n,q,p,e,m;g.width=t=parseInt(u.length*r);g.height=k=parseInt(r*2);o=g.getContext("2d");o.fillStyle="#000";o.fillRect(0,0,t,k);o.font=l;o.textHeight=r;o.textBaseline="top";o.fillStyle="#fff";o.font=r+"px "+l;o.fillText(u,0,0);d=o.getImageData(0,0,t,k);j=d.width;n=d.height;m={min:{x:j,y:n},max:{x:-1,y:-1}};for(p=0;p<n;++p){for(q=0;q<j;++q){e=(p*j+q)*4;if(d.data[e+1]>0){if(q<m.min.x){m.min.x=q}if(q>m.max.x){m.max.x=q}if(p<m.min.y){m.min.y=p}if(p>m.max.y){m.max.y=p}}}}if(j!=t){m.min.x*=(t/j);m.max.x*=(t/j)}if(n!=k){m.min.y*=(t/n);m.max.y*=(t/n)}g=null;return m};jQuery.fn.tagcanvas=function(e,d){var c,f=d?jQuery("#"+d):this;if(document.all&&!d){return false}c=f.find("a");if(typeof(window.G_vmlCanvasManager)!="undefined"){this.each(function(){b(this)[0]=window.G_vmlCanvasManager.initElement(b(this)[0])})}if(!c.length||!this[0].getContext||!this[0].getContext("2d").fillText){return false}this.each(function(){var k,m,h,l,g,j,n=b(this).offset();if(!d){c=b(this).find("a")}j=new a;for(k in e){j[k]=e[k]}j.z1=(19800/(Math.exp(j.depth)*(1-1/Math.E)))+20000-19800/(1-(1/Math.E));j.z2=j.z1*(1/j.zoom);j.radius=(this.height>this.width?this.width:this.height)*0.33*(j.z2+j.z1)/(j.z1);j.taglist=[];m=j.PointsOnSphere(c.length);for(k=0;k<c.length;++k){h=c[k].getElementsByTagName("img");if(h.length){l=new Image;l.src=h[0].src;g=new j.Tag(j,l,c[k],m[k],1,1);j.AddImage(l,g,j.taglist)}else{j.taglist.push(new j.Tag(j,c[k].innerText?c[k].innerText:c[k].textContent,c[k],m[k],2,j.textHeight+2))}}j.yaw=j.initial?j.initial[0]*j.maxSpeed:0;j.pitch=j.initial?j.initial[1]*j.maxSpeed:0;j.cx=n.left;j.cy=n.top;j.canvas=b(this)[0];a.tc[b(this)[0].id]=j;if(!a.started){jQuery(document).bind("mousemove",a.MouseMove);jQuery(document).bind("mouseout",a.MouseMove);jQuery(document).bind("mouseup",a.MouseClick);a.started=setInterval(function(){a.DrawCanvas()},10)}if(d&&j.hideTags){f.hide()}});return true}})(jQuery);

