function Vector(x,y)
{
    this.x = x;
    this.y = y;
}


function Circles(num,id,yd,duration,future)
{
    var that = this;

    this.object = $('#'+id);
    this.count = num;
    //this.width = this.object.width();
    this.deltaY = yd;
    //this.deltaX = Math.round(this.width/this.count);
    //this.centerVector = new Vector(this.deltaX/2,this.object.height()/2);
    this.object.css('position','relative');
    this.animationFlag = true; // можно ли все это дело мутить
    this.duration = duration;
    this.childrens = [];

    this.reloadChildren();

    this.nowIds = [];
    this.futureIds = future; // два массива, в которых определено, какие сейчас стоят шарики и какие будут потом


    this.initPositions();
    this.addDivs(); // also fills this.nowIds

    // window resizeing
    $(window).resize(function(){that.reinitPositions(that);});


    // cursor handling
    this.cursorEvent = new Object;
    this.cursorEvent.cursorInside = false;

    this.object.bind('mouseover',function(e){
        that.handleMouseIn(e,that);
    });
    this.object.bind('mouseout',function(e){
        that.handleMouseOut(e,that);
    });
    this.object.bind('mousemove',function(e){
        that.handleMouseMove(e,that);
    });
    

}

Circles.prototype.reinitPositions = function(obj)
{
    obj.initPositions();
}

Circles.prototype.handleMouseIn = function(e,that)
{
    that.cursorEvent.cursorInside = true;
}

Circles.prototype.handleMouseOut = function(e,that)
{
    that.cursorEvent.cursorInside = false;
    //var ex = new Object;
    //ex.srcElement = that.object.get(0);
    //ex.offsetX = -999;
    //ex.offsetX = -999;
    //that.handleMouseMove(ex,that);
    /*
    for(var i=0;i<that.count;i++)
    {
        if(!that.childrens[i].availableForAnimation)
        {
            that.initTiming(3000,15000,i);
        }
        that.childrens[i].availableForAnimation = true;
        that.removeKolbaska(i);
    }*/
}

Circles.prototype.handleMouseMove = function(e,that)
{
    //console.log(e.offsetX,e.offsetY,e.srcElement);


    if(e.offsetX==undefined) e.offsetX = e.layerX;
    if(e.offsetY==undefined) e.offsetY = e.layerY;
    if(e.srcElement==undefined) e.srcElement = e.target;

    if(e.srcElement==that.object.get(0))
    {
        that.cursorEvent.x = e.offsetX;
        that.cursorEvent.y = e.offsetY;
    }
    else
    {
        that.cursorEvent.x = e.offsetX+parseInt($(e.srcElement).parents('li').css('left'));
        that.cursorEvent.y = e.offsetY+parseInt($(e.srcElement).parents('li').css('top'));
    }

    that.cursorEvent.lengthsArray = [];

    var x;
    var y;
    var len;
    for(var i=0;i<that.count;i++)
    {
        y = (parseInt($(that.childrens[i]).css('top'))+$(that.childrens[i]).height()/2) - that.cursorEvent.y;
        x = (parseInt($(that.childrens[i]).css('left'))+$(that.childrens[i]).width()/2) - that.cursorEvent.x;
        len = Math.sqrt(x*x+y*y);
        that.cursorEvent.lengthsArray.push(len);
        if(len<that.stopRadius)
        {
            that.cursorEvent.lowerElement = i;
            if(that.childrens[i].availableForAnimation)
            {
                that.pulseElement(i);
                that.addKolbaska(i);
                that.childrens[i].availableForAnimation = false;
                that.cancelTiming(i);
            }
        }
        else
        {
            if(!that.childrens[i].availableForAnimation)
            {
                that.initTiming(3000,15000,i);
            }
            that.childrens[i].availableForAnimation = true;
            that.removeKolbaska(i);
        }
    }


}

Circles.prototype.pulseElement = function(index)
{
    var obj = $(this.childrens[index]);
    var delta = Math.round(obj.height()/16);
    obj.find('img').css('position','absolute');
    obj.find('img').animate({
        'height':(obj.height()+delta)+'px',
        'width':(obj.height()+delta)+'px',
        'top':(-1*delta/2)+'px',
        'left':(-1*delta/2)+'px'
    },300,function(){
        obj.find('img').animate({
            'height':(obj.height())+'px',
            'width':(obj.height())+'px',
            'top':'0px',
            'left':'0px'
        },300);
    });
}

Circles.prototype.reloadChildren = function()
{
    var that = this;
    that.children = [];
    this.object.children().each(function(index){


        this.switchFlag = false;
        this.inAnimation = false;
        this.availableForAnimation = true;
        this.timeout = null;

        that.childrens.push(this);
        that.childrens[index].moveVector = new Object;
        that.childrens[index].moveVector.x = 0;
        that.childrens[index].moveVector.y = 0;
    });
    that.moveRange = $(that.childrens[0]).height()/12;
    var a = $(that.childrens[0]).height();
    that.stopRadius = Math.sqrt(2*(a/2)*(a/2))*1.1;

}

Circles.prototype.rand = function(from,to)
{
    return Math.round(from+(Math.random()*(to-from)));
}

Circles.prototype.timerAction = function(that,index) {
    if(!that.childrens[index].availableForAnimation) return;

    that.prepareElement(index);
    that.animateElement(that.nowIds[index],index,function(index){
        that.initTiming(3000,15000,index)
    });
}

Circles.prototype.cancelTiming = function(index)
{
    clearTimeout(this.childrens[index].timeout);
}

Circles.prototype.initTiming = function(from,to,index) {
    var that = this;
    clearTimeout(this.childrens[index].timeout);
    this.childrens[index].timeout = setTimeout(function(){
        that.timerAction(that,index);
    },that.rand(from,to));
}

Circles.prototype.prepareElement = function(index)
{
    /*
     * Adds changes to rotation arrays
     */
    this.futureIds.push(this.nowIds[index]);
    this.nowIds[index] = this.futureIds.shift();

    // some little move element

    this.childrens[index].moveVector.x = this.rand(this.moveRange*-1,this.moveRange);
    this.childrens[index].moveVector.y = this.rand(this.moveRange*-1,this.moveRange);

//console.log(this.childrens[index].moveVector);


}

Circles.prototype.addKolbaska = function(index)
{
    this.removeKolbaska(index);
    var newDiv = $('<div>');
    var link = $('<a>');
    link.html(this.nowIds[index].alt);
    link.attr('href',this.nowIds[index].href);
    newDiv.append(link);
    newDiv.addClass('kolbaska');
    var cssRules = {
        'position':'absolute',
        'top':($(this.childrens[index]).height()+$(this.childrens[index]).height()/16)+'px',
        'left':'0',
        'width':'100%',
        //'background':'red',
        'display':'none'
    };
    newDiv.css(cssRules);
    $(this.childrens[index]).append(newDiv);
    newDiv.fadeIn(300);

}

Circles.prototype.removeKolbaska = function(index)
{
    $(this.childrens[index]).find('.kolbaska').fadeOut(300,function(){
        $(this).remove()
    });
}

Circles.prototype.animateElement = function(infoObject,index,callback)
{
    /*
     * switchFlag = false - now in primary
     *              true  - now in secondary
     */
    var imgInfo = new Object;
    imgInfo.src = infoObject.src;
    imgInfo.alt = infoObject.alt;
    var that = this;
    var chld = $(this.childrens[index]);
    var img = chld.find('img');
    var newimg = $('<img>');
    newimg.attr(imgInfo);
    newimg.css('display','none');
    newimg.bind('load',function(){
        if(that.childrens[index].switchFlag)
        {
            chld.find('.primary').append(newimg);
        }
        else
        {
            chld.find('.secondary').append(newimg);
        }
        that.childrens[index].switchFlag = !that.childrens[index].switchFlag;
        that.childrens[index].inAnimation = true;

        img.fadeOut(that.duration,function(){
            img.parent().css('display','none');

            // some little move here
            var x = that.childrens[index].originalPosition.x + that.childrens[index].moveVector.x;
            var y = that.childrens[index].originalPosition.y + that.childrens[index].moveVector.y;
            $(that.childrens[index]).css('top',y);
            $(that.childrens[index]).css('left',x);

            newimg.parent().css('display','block');
            newimg.parent().attr('href',infoObject.href);
            newimg.fadeIn(that.duration,function(){
                that.childrens[index].inAnimation = false;
                img.remove();
                if(callback!=undefined) callback(index);
            });
        });

    });
}

Circles.prototype.addDivs = function()
{
    var that = this;
    this.object.children().each(function(index){

        var curInfoObject = new Object;
        var oldAObj = $(this).find('a');
        var css = {
            'position':'absolute',
            'top':'0',
            'left':'0',
            'height':'100%',
            'width':'100%'
        };

        curInfoObject.href = oldAObj.attr('href');
        curInfoObject.src = $(this).find('img').attr('src');
        curInfoObject.alt = $(this).find('img').attr('alt');

        var primary = $('<a>').addClass('primary').css('z-index','1002').css(css);
        var secondary = $('<a>').addClass('secondary').css('z-index','1001').css(css);
        secondary.css('display','none');
        primary.attr('href',oldAObj.attr('href'));
        $(this).append(primary);
        $(this).append(secondary);
        primary.append($(this).find('img'));
        oldAObj.remove();
        that.nowIds.push(curInfoObject);
        that.initTiming(3000,15000,index);

    });
}

Circles.prototype.initPositions = function()
{
    this.width = this.object.width();
    this.deltaX = Math.round(this.width/this.count);
    this.centerVector = new Vector(this.deltaX/2,this.object.height()/2);
    
    var that = this;
    var flag = -1;
    this.object.children().each(function(index){

        that.childrens[index].originalPosition = new Object;
        that.childrens[index].originalPosition.y = Math.round((that.centerVector.y)-$(this).height()/2+(that.deltaY*flag));
        that.childrens[index].originalPosition.x = Math.round((index*that.deltaX+that.centerVector.x)-$(this).width()/2);

        //console.log(that.childrens[index].originalPosition);

        $(this).css('position','absolute')
        .css('top',(that.centerVector.y)-$(this).height()/2+(that.deltaY*flag)+(that.childrens[index].moveVector.y))
        .css('left',(index*that.deltaX+that.centerVector.x)-$(this).width()/2+(that.childrens[index].moveVector.x));
        flag*=-1;
    });
}

function circlesInit(id)
{
    var i=0;
    $('#'+id).children().each(function(){
        $(this).attr('id','cr'+i++);
    });

    engine = new Circles($('#'+id).children().size(),id,75,1000,circFutIds); // GLOBAL!!!!!!!!!
}


function test()
{
    /*
    engine.animateElement({
        'src':'images/circles/c2.png',
        'alt':'some shit',
        'href':'#2'
    },0);*/
    //engine.pulseElement(0);
    //engine.addKolbaska(0);
    engine.initPositions();
}

var engine;

$(document).ready(function()
{
    circlesInit('mycircles');

});

