/*************************************************************/
/*                          Globals                          */
/*************************************************************/

var cssClassHandle = 'anyTextHandle';

var MIN_ZINDEX_FOR_BOXES = 900;
var MIN_RADIUS = 227;

/*************************************************************/
/*                        Positioner                         */
/*************************************************************/

var CirclePositioner = Class.create();

CirclePositioner.prototype = {

  initialize: function() {

  },

  MIN_RADIUS : 227,

  position: function(layout, wd){

    var textsRadius = (wd.height / 2) + configuration.textRadiusAdjustment;

	if(textsRadius < MIN_RADIUS) {
	  textsRadius = MIN_RADIUS;
	}

	var amountSpacerPositions = 5;

	var amountTexts = layout.items.length;
	//var adjustmentTop = wd.getCenterPoint().getY() * configuration.textCenterOffsetTop;
	//var adjustmentLeft = wd.getCenterPoint().getX() * configuration.textCenterOffsetTop;
	var winCenter = wd.getCenterPoint().newPoint(configuration.textCenterOffsetLeft, configuration.textCenterOffsetTop);

	if(winCenter.getY() < textsRadius + 30) {
	  winCenter.setY(textsRadius + 30);
	}

	//alert("text radius : " + textsRadius + ", offset top: " + configuration.textCenterOffsetTop);
	layout.positions = [];

	var anyTextPositions = this.getCircleCoords(amountTexts + amountSpacerPositions, textsRadius, winCenter);
	var split = (amountTexts / 2) - (amountSpacerPositions / 2) + 4;

	for (var i = 0; i <= split; i++) {
		layout.positions.push(anyTextPositions[i]);
	}

	i += amountSpacerPositions;

	for (; i < anyTextPositions.length; i++) {
		layout.positions.push(anyTextPositions[i]);
	}

  },

  getCircleCoords: function(amountItems, radius, centerP){

	var steps = 90;
	var frame = 55;

	var pos = new Array();
	var itemCount = amountItems;

	var step = (steps / itemCount);
	var pi2Steps = 2 * Math.PI / steps;


	for(var i = 1; i <= itemCount; i++){

		var tmp = (i * step + frame) * pi2Steps;

		var x = radius * Math.cos(tmp);
		var y = radius * Math.sin(tmp);

	  	pos.push(centerP.newPoint(x, y));
	}
    return pos;
  }

}

var QuietPositioner = Class.create();

QuietPositioner.prototype = {

  initialize: function() {

  },

  position: function(layout, wd){
    layout.positions = [];

	for (var i = 0; i < layout.items.length; i++) {
		var item = layout.items[i];
		var css = item.getCss();
		var x = parseInt(css.left) - item.xOffset;
		var y = parseInt(css.top) - item.yOffset;
		layout.positions.push(new Point(x, y));
	}

  }

}

/*************************************************************/
/*                 ItemCreationStrategy                      */
/*************************************************************/

var TextItemCreationStrategy = Class.create();

TextItemCreationStrategy.prototype = {

  initialize: function() { },

  newItem: function(htmlElement){

  	return new ItemBuilder().newItem(htmlElement);
  }

}

var ImageItemCreationStrategy = Class.create();

ImageItemCreationStrategy.prototype = {

  initialize: function() { },

  newItem: function(htmlElement){

  	return new ItemBuilder().newImageItem(
  	  htmlElement.id,
  	  htmlElement.src,
  	  htmlElement.style.width,
  	  htmlElement.style.height);
  }

}

/*************************************************************/
/*                   AnyTextLayout                           */
/*************************************************************/

var AnyTextLayout = Class.create();

AnyTextLayout.prototype = {

  initialize: function(parentElement, creationStrategy, positioner, findBy) {

	this.parent = $(parentElement);
	this.creationStrategy = creationStrategy || new TextItemCreationStrategy(); // hack for a downward compatibility
	this.positioner = positioner || new CirclePositioner(); // hack for a downward compatibility
	this.findBy = findBy || "a.AnyTextClass"; // hack for a downward compatibility
    this.items = [];
    this.animatedItems = [];
    this.maxWidth = 0;
  },

  add: function(html){

  	new Insertion.Bottom(this.parent, new String(html));
  	var newElem = $$(this.findBy).last();

  	var asItem = new ItemBuilder().newItem(newElem);
  	asItem.setZindex(MIN_ZINDEX_FOR_BOXES + 1);

  	this.items[this.items.length] = asItem;
  },

  addElement: function(htmlElement) {

    if(htmlElement == null) {
  	  throw new Error("Element must not be null");
  	}

  	var asItem = this.creationStrategy.newItem(htmlElement);
  	asItem.setZindex(MIN_ZINDEX_FOR_BOXES + 1);

  	this.items[this.items.length] = asItem;
  },

  addElementById: function(id){

    if(id == null) {
  	  throw new Error("Element id must not be null nor empty");
  	}

  	addElement($(id));
  },

  toString: function() {
    return "Elements: " + this.items.join(", ");
  },

  setPositions: function(wd){

    this.positioner.position(this, wd);
    this.setItemPositions();

  },

  setItemPositions: function() {

	for (var index = 0; index < this.items.length; index++) {
		this.items[index].setPosition(this.positions[index]);
	}

  },

  showAll: function() {

  	for (var index = 0; index < this.items.length; index++) {

  		var item = this.items[index];
  		item.show();

  		var width = item.element.getDimensions()['width'];
  		if(width > this.maxWidth){
  			this.maxWidth = width;
  		}
	}
  },

  windowChanged: function(windowDimensions){
	this.setPositions(windowDimensions);
  },

  getItems: function(){
    return this.items;
  },

  startJoinAnim: function(animUtils){

	var ms = 1000;
	var boxJoinAnimProbability = configuration.boxJoinAnimProbability // very improbable 0.02;
	var boxLeaveAnimProbability = configuration.boxJoinAnimProbability;

	this.animUtils = animUtils;

	shuffleInterval = setInterval(function() {

		var velocity = Math.random() * 700 + 20;
		var didJustMoveOut = false;

		if(Math.random() < boxJoinAnimProbability){

			var rndIndex = Math.round((Math.random() * this.items.length) - 1);
			if(rndIndex < 0) rand = 0;

			var itemGetsAnimated = this.items[rndIndex];
			if(itemGetsAnimated){
				this.animatedItems.push(itemGetsAnimated);
				this.animUtils.getMutator().fadeItemToStrategy(itemGetsAnimated, this.animUtils.getCurrentStrategy(), velocity);
				didJustMoveOut = true;
			}
		}

		if(Math.random() < boxLeaveAnimProbability && this.animatedItems.length > 0 && !didJustMoveOut){
			var rndIndex = Math.round((Math.random() * this.animatedItems.length) - 1);
			if(rndIndex < 0) rand = 0;

			var itemThatComesBack = this.animatedItems.splice(rndIndex, 1)[0];
			if(itemThatComesBack){
				var itemsPosition = this.positions[this.items.indexOf(itemThatComesBack)];
				this.animUtils.getMutator().moveItemToPoint(itemThatComesBack, itemsPosition, velocity);
			}
		}

    }.bind(this), ms);
  }
}
