/**
 * CircleTag - A plugin for jQuery with circle tag cloud effect.
 * @requires jQuery v1.3 or above
 *
 * http://www.paopao.name/internet/circle-tag-cloud-plugin-for-jquery.html
 *
 * Copyright (c) 2009 paopao (paopao.name)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 * Version: 0.1.0
 * Requires jQuery Easing plugin v1.3 if needed
 */

/**
 * Use the following snippet to initialize the tag cloud.
 *   $(function() { $(".tags").circleTag({ speed: 300, fxin: "easeInQuad", fxout: "easeOutQuad"}) });
 *
 * Thats it. Now you should have a working circle tag cloud. 
 *
 * @param an options object - You can specify all the options shown below as an options object param.
 *
 * @option speed - default is 300 ms
 * @desc Creates a menu with an animation speed of 300 ms per pixel.
 *
 * @option fxin - default is "easeInQuad"
 * @You need to include the easing plugin for this to work.
 *
 * @option fxout - default is "easeOutQuad"
 * @You need to include the easing plugin for this to work.
 */
jQuery.fn.extend({
    circleTag : function(o) {
        o = $.extend({speed: 300, fxin: "easeInQuad", fxout: "easeOutQuad" }, o || {});

        return this.each(function(){
            var w = parseFloat($(this).css("width")),
                h = parseFloat($(this).css("height")),
                $a = $("a", this);
            $a.each(function(){
                $(this).css({top:(Math.random()*h)+"px", left:(Math.random()*w)+"px" });
                
                if(parseFloat($(this).css("left")) <= w/2) {
                    $(this).data("ol",parseFloat($(this).css("left"))).data("ot",parseFloat($(this).css("top"))).data("dl",w - parseFloat($(this).css("left"))).data("dt",h - parseFloat($(this).css("top")));
                } else {
                    $(this).data("dl",parseFloat($(this).css("left"))).data("dt",parseFloat($(this).css("top"))).data("ol",w - parseFloat($(this).css("left"))).data("ot",h - parseFloat($(this).css("top")));
                }
                var myspeed = o.speed * Math.sqrt((($(this).data("dl")+$(this).data("ol"))/2 - $(this).data("ol")));
                $(this).data("speed", myspeed);
                var fs = $(this).css("font-size");
                var parts = fs.match(/^([\d+-.]+)(.*)$/);
                $(this).data("fs",parts[1]).data("fu", parts[2] || "");
                $(this).css("z-index",8).css("opacity",0.6);
            });

            $(this).hover(function() {
                $a.each(function() {
                    $(this).stop();
                    move.apply(this);
                });
            }, function() {
                $a.each(function() {
                    $(this).stop()
                });
            });

            function move() {
                var dl = '', dt = '', time = $(this).data("speed"), di = 0, fs = $(this).data("fs") + $(this).data("fu"), op = 1, ci = $(this).css("z-index"), cl = parseFloat($(this).css("left")), method = "linear" ;
                var halfw = ($(this).data("dl")+$(this).data("ol"))/2;
                var halfh = ($(this).data("dt")+$(this).data("ot"))/2;
                if(ci >= 8 && cl < halfw) {
                    dl = halfw + "px";
                    dt = halfh + "px";
                    time = (halfw - cl)/(halfw - $(this).data("ol"))*time;
                    fs = $(this).data("fs") * 1.8 + $(this).data("fu");
                    op = 1;
                    method = o.fxin;
                    $(this).css("z-index",16);
                } else if(ci > 8 && cl >= halfw) {
                    dl = $(this).data("dl") + "px";
                    dt = $(this).data("dt") + "px";
                    time = time - (cl - halfw)/($(this).data("dl") - halfw)*time;
                    fs = $(this).data("fs") + $(this).data("fu");
                    op = 0.6;
                    method = o.fxout;
                    $(this).css("z-index",0);
                } else if(ci <=8 && cl > halfw) {
                    dl = halfw + "px";
                    dt = halfh + "px";
                    time = (cl - halfw)/($(this).data("dl") - halfw)*time;
                    fs = $(this).data("fs") * 0.2 + $(this).data("fu");
                    op = 0.2;
                    method = o.fxin;
                    $(this).css("z-index",0);
                } else if(ci < 8 && cl <= halfw) {
                    dl = $(this).data("ol") + "px";
                    dt = $(this).data("ot") + "px";
                    time = time - (halfw - cl)/(halfw - $(this).data("ol"))*time;
                    fs = $(this).data("fs") + $(this).data("fu");
                    op = 0.6;
                    method = o.fxout;
                    $(this).css("z-index",16);
                }
                $(this).animate({
                    left:dl,
                    top:dt,
                    fontSize:fs,
                    opacity:op
                }, time, method, move)
            }
        });
    }
});