dojo.declare("WW.DockCart", null, {

	constructor : function(args){
	  if (dojo.isIE == 6) return;
		dojo.mixin(this, args);
		this.initAddToCarts();
		var dock = dojo.byId('dockcart');
		if (!this.modulePos) {
			dojo.place(dock, dojo.body(), 'last');
			dock.style.position = 'fixed';
		} else {
		  dock.style.position = 'absolute';
		  dock.parentNode.style.height = dojo.style(dock, 'height')+'px';
		}
		this.msg = dojo.byId('dockcart-msg');
	  this.fish = new dojox.widget.FisheyeList({
			itemWidth : this.minW,
			itemHeight : this.minH,
			itemMaxWidth: this.maxW,
			itemMaxHeight: this.maxH,
			effectUnits: this.effIcons,
			itemPadding: this.margin,
			attachEdge: 'bottom'
		}, 'dockcart-icons');
		dojo.mixin(this.fish, this.overrideFisheyeList);
		this.fish.dock = dock;
		this.fish.parent = this;
		this.initContent();
		this.fish.startup();
		if (this.hideEmpty && !this.modulePos && this.fish.children.length < 3)
		  dock.style.bottom = (-2*this.fish.itemHeight)+'px';
		if (this.fish.itemHeight < this.minH) {
		  var mt = this.minH - this.fish.itemHeight;
		  for (var i=0; i<this.fish.itemCount; ++i)
		    this.fish.children[i].domNode.style.marginTop = mt+'px';
		}
		dock.style.visibility = 'visible';
	},

	initAddToCarts: function() {
		if (dojo.isIE) {
		  var forms = document.getElementsByTagName('form');
		  for (var i=0; i<forms.length; ++i)
		    if (forms[i].name == 'addtocart')
		      if (dojo.isIE == 9)
				  	dojo.attr(forms[i], 'onsubmit', 'dc.onSubmitAddToCart({currentTarget:this}); return false;');
				  else {
				    dojo.attr(forms[i], 'onsubmit', '');
						dojo.connect(forms[i], 'onsubmit', this, 'onSubmitAddToCart');
					}
		} else {
			var forms = document.getElementsByName('addtocart');
			for (var i=0; i<forms.length; ++i) {
			  dojo.attr(forms[i], 'onsubmit', 'return false;');
			  dojo.connect(forms[i], 'onsubmit', this, 'onSubmitAddToCart');
			}
		}
	},

	initContent: function() {
	  var content = dojo.fromJson(this.content);
	  var products = content.products;
		this.cart = this.addItem({
		  productId: 0,
			iconSrc: this.cartIcon,
			label: this.cartTxt,
			price: this.totalTxt,
			url: this.cartUrl
		});
		this.load = this.cart.rmvNode;
		this.load.innerHTML = '<img src="'+this.loadIcon+'"/>';
		this.load.style.backgroundPosition = 'right';
		this.load.style.padding = '0px';
		this.load.style.visibility = 'hidden';
		for (var i=0; i<products.length; ++i)
			this.addItem({
			  productId: products[i].product_id,
				iconSrc: products[i].product_thumb_image,
				label: products[i].product_name,
				price: products[i].price,
				url: products[i].product_page,
				count: products[i].quantity,
				desc: products[i].description
			});
		var checkout = this.addItem({
		  productId: 0,
			iconSrc: this.checkIcon,
			label: this.checkTxt,
			price: content.sum,
			url: this.checkUrl
		});
		checkout.rmvNode.style.display = 'none';
		this.sum = checkout.prcNode;
		this.sum.style.fontWeight = 'bold';
		var bodyW = dojo.marginBox(this.fish.dock.parentNode).w;
		this.plusW = (this.maxW - this.minW)*this.effIcons;
		if (bodyW < this.minW*(products.length+2)+this.plusW)
		  this.fish.itemWidth = this.fish.itemHeight =
				Math.floor((bodyW-this.plusW)/(products.length+2))-1;
	},

	onSubmitAddToCart: function(e) {
	  var form = e.currentTarget;
	  if ((form.elements['quantity[]'] && form.elements['quantity[]'].value < 1)
		|| this.load.style.visibility == 'visible') return;
		form.action = this.path + "index.php";
	  this.load.style.visibility = 'visible';
	  var args = '';
	  var i, s = dojo.query('select', form);
	  for (i=0; i<s.length; ++i) args += s[i].name + s[i].value;
	  var post = {
      form: form,
      handleAs: 'text',
			load: dojo.hitch(this, 'getAjaxResult', 'addProduct', {
				id: form.elements['product_id'].value,
				args: args
			}),
			//error: dojo.hitch(this, 'addToCartError'),
			timeout: 5000,
			preventCache: true
	  };
	  if (this.hideEmpty && !this.modulePos && this.fish.children.length < 3)
			dojo.animateProperty({
			  node: this.fish.dock,
			  duration: 2*this.duration,
			  properties: {bottom: 0},
			  onEnd: dojo.hitch(dojo, 'xhrPost', post)
			}).play();
		else dojo.xhrPost(post);
		if (e.preventDefault) e.preventDefault();
	},

	getAjaxResult: function(func, param, data) {
	  var script = data.match(/<script.*>([^<]+)<\/script>/i);
	  if (script) eval(script[1]);
	  else if (data.search(/Success/) > 0)
			dojo.xhrPost({
	    	url: this.path+'/index.php',
	    	postData: 'option=com_ajax_dockcart&format=raw&w='+this.maxW+'&h='+this.maxH+'&img='+this.icon,
	    	handleAs: 'json',
	    	sync: true,
				load: dojo.hitch(this, func, param),
				//error: dojo.hitch(this, "refresh"),
				timeout: 5000,
				preventCache: true
			});
		else {
		  this.msg.innerHTML = data.match(/<b>.+<\/b>:[^<]+/i);
		  this.msg.style.display = 'block';
			this.load.style.visibility = 'hidden';
			dojo.animateProperty({
			  node: this.msg,
			  duration: this.duration,
			  properties: {top: -this.fish.itemHeight},
			  onEnd: dojo.hitch(this, 'onEndShowMsg')
			}).play();
		}
	},
	
	onEndShowMsg: function() {
		dojo.animateProperty({
		  node: this.msg,
		  duration: this.duration,
		  delay: this.duration*5,
		  properties: {top: 55},
			onEnd: function() {this.node.style.display = 'none';}
		}).play();
	},

	addProduct: function(prod, data) {
	  if (data.products.length > this.maxCount) {
			location.reload(true);
			return;
		}
	  var i;
	  if (i=this.isProductInCart(prod)) {
	    var item = this.fish.children[i];
	    item.cntNode.innerHTML = data.products[i-1].quantity;
    	item.prcNode.innerHTML = data.products[i-1].price;
			dojo.animateProperty({
			  node: item.imgNode,
			  duration: this.duration*0.66,
			  properties: {marginTop: -this.fish.itemHeight},
			  easing: dojo.fx.easing.quadOut,
				onEnd: dojo.hitch(this, 'onEndJumpUp', item)
			}).play();
		} else {
		  var product = data.products[data.products.length-1];
			var w = (this.fish.itemMaxWidth-this.fish.itemWidth)*this.effIcons;
		  if (this.fish.bodyW < (this.fish.children.length+1)*this.fish.itemWidth + w) {
		    this.fish.itemWidth = this.fish.itemHeight =
					Math.floor((this.fish.bodyW - w)/(this.fish.children.length + 1));
		    for (i=0; i<this.fish.itemCount; ++i)
		      dojo.animateProperty({
		        node: this.fish.children[i].domNode,
		        duration: this.duration,
		        properties: {
		          width: this.fish.itemWidth,
		          height: this.fish.itemHeight,
		          marginTop: this.minH - this.fish.itemHeight
						}
					}).play();
			}
			var item = this.addItem({
			  productId: product.product_id,
				iconSrc: product.product_thumb_image,
				label: product.product_name,
				price: product.price,
				url: product.product_page,
				count: product.quantity,
				desc: product.description
			}, this.fish.children.length-1);
		  dojo.disconnect(this.fish._onMouseMoveHandle);
			dojo.animateProperty({
			  node: item.domNode,
			  duration: this.duration,
			  properties: {
		      width: this.fish.itemWidth,
		      height: this.fish.itemHeight,
		      marginTop: this.minH - this.fish.itemHeight,
		      top: 0
			  },
			  onAnimate: dojo.hitch(this, 'onAnimate'),
			  onEnd: dojo.hitch(this, 'onEndAdd', item)
			}).play();
			this.fish._calcHitGrid();
		}
		this.sum.innerHTML = data.sum;
		this.load.style.visibility = 'hidden';
	},
	
	onEndJumpUp: function(item) {
		dojo.animateProperty({
		  node: item.imgNode,
		  duration: 2*this.duration,
		  properties: {marginTop: 0},
		  easing: dojo.fx.easing.bounceOut
		}).play();
	},

	isProductInCart: function(prod) {
	  for (var i=1; i<this.fish.children.length; ++i)
	    if (this.fish.children[i].productId == prod.id
			&&	this.fish.children[i].args == prod.args) return i;
		return 0;
	},

	addItem: function(args, index) {
	  if (!args.iconSrc) args.iconSrc = this.noimgIcon;
	  dojo.mixin(args, this.overrideFisheyeListItem);
	  var item = new dojox.widget.FisheyeListItem(args);
	  item.args = '';
	  if (item.desc) {
	    var desc = item.desc.replace(/_/g, ' ').split(/;\s*|:/);
	    item.label += '<br/><table border="0">';
	    for (var i=0; i<desc.length; ++i)
				item.label += '<tr><td>'+desc[i]+':</td><td>'+desc[++i]+'</td></tr>';
	    item.label += '</table>';
	    item.lblNode.innerHTML = item.label;
	    desc = item.desc.split(/;\s*|:/);
	    for (var i=0; i<desc.length; ++i)
	      item.args += desc[i] + item.productId + desc[++i];
		}
	  item.prcNode.innerHTML = item.price;
		item.parent = this.fish;
		item.cntNode.innerHTML = item.count;
		if (index) {
      item.lblNode.style.display = item.prcNode.style.display = item.rmvNode.style.display = 'none';
      item.domNode.style.width = item.domNode.style.height = '0px';
      item.domNode.style.top = this.fish.itemHeight+'px';
			item.imgNode.style.left = this.fish.itemPadding+'%';
			item.imgNode.style.top = this.fish.itemPadding+'%';
			item.imgNode.style.width = (100 - 2 * this.fish.itemPadding) + '%';
			item.imgNode.style.height = (100 - 2 * this.fish.itemPadding) + '%';
			this.fish.addChild(item, index);
		} else this.fish.addChild(item);
		return item;
	},

  removeProduct: function(item) {
    this.load.style.visibility = 'visible';
    dojo.xhrPost({
      url: this.path+'/index.php',
      postData: 'option=com_virtuemart&page=shop.cart&func=cartDelete&product_id='+item.productId+'&description='+item.desc,
      handleAs:	'text',
			load: dojo.hitch(this, 'getAjaxResult', 'removeItem', item),
			//error:  dojo.hitch(this, "addToCartError"),
			timeout: 5000,
			preventCache: true
	  });
	},

	removeItem: function(item, data) {
	  this.load.style.visibility = 'hidden';
	  item.lblNode.style.display = item.prcNode.style.display = item.rmvNode.style.display = 'none';
		this.sum.innerHTML = data.sum;
	  dojo.disconnect(this.fish._onMouseMoveHandle);
		dojo.animateProperty({
		  node: item.domNode,
		  duration: this.duration,
		  properties: {
		      width: 0,
		      height: 0,
		      top: this.fish.itemHeight
		  },
		  onAnimate: dojo.hitch(this, 'onAnimate'),
		  onEnd: dojo.hitch(this, 'onEndRemove', item)
		}).play();
	},

	onAnimate: function() {
	  this.fish.dock.style.left = ((this.fish.bodyW-dojo.marginBox(this.fish.dock).w)/2) + 'px';
	},

	onEndRemove: function(item) {
   	this.fish.removeChild(item);
   	if (this.fish.itemWidth < this.minW) {
   	  var w = Math.floor((this.fish.bodyW-this.maxW*this.effIcons)/(this.fish.itemCount-this.effIcons));
   	  this.fish.itemWidth = this.fish.itemHeight = w < this.minW? w : this.minW;
   	  for (var i=0; i<this.fish.itemCount; ++i)
	      dojo.animateProperty({
	        node: this.fish.children[i].domNode,
	        duration: this.duration,
	        properties: {
	          width: this.fish.itemWidth,
	          height: this.fish.itemHeight,
	          marginTop: this.minH - this.fish.itemHeight,
	          top: 0
					}
				}).play();
      this.fish._initializePositioning();
		} else this.fish._calcHitGrid();
		this.fish._onMouseMoveHandle = dojo.connect(document.documentElement, "onmousemove", this.fish, "_onMouseMove");
		if (this.hideEmpty && !this.modulePos && this.fish.children.length < 3)
			dojo.animateProperty({
			  node: this.fish.dock,
			  duration: 2*this.duration,
			  properties: {bottom: -2*this.fish.itemHeight}
			}).play();
	},

	onEndAdd: function(item) {
		this.fish._onMouseMoveHandle = dojo.connect(document.documentElement, "onmousemove", this.fish, "_onMouseMove");
		this.fish.children = this.fish.getChildren();
		this.fish._initializePositioning();
		item.lblNode.style.display = item.prcNode.style.display = item.rmvNode.style.display = '';
	},

	overrideFisheyeList: {
		startup: function(){
			this.children = this.getChildren();
			this._initializePositioning();
			this._onMouseMoveHandle = dojo.connect(document.documentElement, "onmousemove", this, "_onMouseMove");
			this._onScrollHandle = dojo.connect(window, "onscroll", this, "_calcHitGrid");
			this._onResizeHandle = dojo.connect(window, "onresize", this, "_initializePositioning");
		},

		removeChild: function(widget){
			if (!widget) return;
			var node = widget.domNode;
			if (node && node.parentNode) node.parentNode.removeChild(node); // detach but don't destroy
			var i = 0;
			while (i < this.children.length && this.children[i] != widget) ++i;
			while (i < this.children.length) this.children[i] = this.children[++i];
			this.itemCount = --this.children.length;
		},

		_initializePositioning: function(){
			this.itemCount = this.children.length;
			this.barWidth  = (this.isHorizontal ? this.itemCount : 1) * this.itemWidth;
			this.barHeight = (this.isHorizontal ? 1 : this.itemCount) * this.itemHeight;
			// calculate effect ranges for each item
			for(var i=0; i<this.children.length; i++){
				this.children[i].posX = 0
				this.children[i].posY = 0;
				this.children[i].cenX = this.itemWidth  / 2;
				this.children[i].cenY = this.itemHeight / 2;
				var isz = this.isHorizontal ? this.itemWidth : this.itemHeight;
				var r = this.effectUnits * isz;
				var c = this.isHorizontal ? this.children[i].cenX : this.children[i].cenY;
				var lhs = this.isHorizontal ? this.proximityLeft : this.proximityTop;
				var rhs = this.isHorizontal ? this.proximityRight : this.proximityBottom;
				var siz = this.isHorizontal ? this.barWidth : this.barHeight;
				var range_lhs = r;
				var range_rhs = r;
				if(range_lhs > c+lhs){ range_lhs = c+lhs; }
				if(range_rhs > (siz-c+rhs)){ range_rhs = siz-c+rhs; }
				this.children[i].effectRangeLeft = range_lhs / isz;
				this.children[i].effectRangeRght = range_rhs / isz;
			}
			// position the items
			for(var i=0; i<this.children.length; i++){
				var itm = this.children[i];
				var elm = itm.domNode;
				elm.style.width  = this.itemWidth + 'px';
				elm.style.height = this.itemHeight + 'px';

				itm.imgNode.style.left = this.itemPadding+'%';
				itm.imgNode.style.top = this.itemPadding+'%';
				itm.imgNode.style.width = (100 - 2 * this.itemPadding) + '%';
				itm.imgNode.style.height = (100 - 2 * this.itemPadding) + '%';
			}
			// calc the grid
			this.bodyW = dojo.marginBox(this.dock.parentNode).w;
		  this.dock.style.left = ((this.bodyW-dojo.marginBox(this.dock).w)/2) + 'px';
			this._calcHitGrid();
		},

		_calcHitGrid: function(){
			var pos = dojo.coords(this.domNode, true);
			this.hitX1 = pos.x - this.proximityLeft;
			this.hitY1 = pos.y - this.proximityTop;
			this.hitX2 = pos.x + pos.w + this.proximityRight;
			this.hitY2 = pos.y + 2*this.itemHeight;
		},
		
		_paint: function(){
			if(this.itemCount < 1) return;
			var x=this.pos.x;
			var y=this.pos.y;
			// figure out our main index
			var pos = this.isHorizontal ? x : y;
			var prx = this.isHorizontal ? this.proximityLeft : this.proximityTop;
			var siz = this.isHorizontal ? this.itemWidth : this.itemHeight;
			var sim = this.isHorizontal ?
				(1.0-this.timerScale)*this.itemWidth + this.timerScale*this.itemMaxWidth :
				(1.0-this.timerScale)*this.itemHeight + this.timerScale*this.itemMaxHeight ;
			var cen = ((pos - prx) / siz) - 0.5;
			var max_off_cen = (sim / siz) - 0.5;
			if(max_off_cen > this.effectUnits){ max_off_cen = this.effectUnits; }
			// figure out our off-axis weighting
			var cen2 = (y - this.proximityTop) / this.itemHeight;
			var off_weight = cen2 > 0.4? cen2 > 1? -(cen2-2) : 1 : y / (this.proximityTop + (this.itemHeight / 2));
			// set the sizes
			for(var i=0; i<this.itemCount; i++){
				var weight = this._weighAt(cen, i);
				if(weight < 0){weight = 0;}
				this._setItemSize(i, weight * off_weight);
			}
			// set the positions
			var main_p = Math.round(cen);
			var offset = 0;
			if(cen < 0) main_p = 0;
			else if(cen > this.itemCount - 1) main_p = this.itemCount -1;
			else offset = (cen - main_p) * ((this.isHorizontal ? this.itemWidth : this.itemHeight) - this.children[main_p].sizeMain);
			this._positionElementsFrom(main_p, offset);
		},

		_setItemSize: function(p, scale){
			scale *= this.timerScale;
			var y;
			var w = Math.round(this.itemWidth  + ((this.itemMaxWidth  - this.itemWidth ) * scale));
			var h = Math.round(this.itemHeight + ((this.itemMaxHeight - this.itemHeight) * scale));
			this.children[p].sizeW = w;
			this.children[p].sizeH = h;
			if(this.anchorEdge == this.EDGE.TOP){
				y = (this.children[p].cenY - (this.itemHeight / 2));
			}else if(this.anchorEdge == this.EDGE.BOTTOM){
				y = (this.children[p].cenY - (h - (this.itemHeight / 2)));
			}else{
				y = (this.children[p].cenY - (h / 2));
			}
			this.children[p].domNode.style.top  = y + 'px';
			this.children[p].domNode.style.width  = w + 'px';
			this.children[p].domNode.style.height = h + 'px';
		},

		_positionElementsFrom: function(p, offset){
			this.dock.style.left = ((this.bodyW-dojo.marginBox(this.dock).w)/2) + 'px';
			this._positionLabel(this.children[p]);
		},

		_positionLabel: function(itm){
		  if (!itm.labelW) {
		    var mb = dojo.marginBox(itm.lblNode);
		    itm.labelW = mb.w;
		    itm.labelH = mb.h;
			}
			itm.lblNode.style.left = ((itm.sizeW-itm.labelW) / 2) + 'px';
			itm.lblNode.style.top  = (-itm.labelH-5) + 'px';
		}
	},
	
	overrideFisheyeListItem: {
	  templateString:
			'<div class="dojoxFisheyeListItem" dojoAttachEvent="onmouseover:onMouseOver,onmouseout:onMouseOut,onclick:onClick">' +
			'  <img class="dojoxFisheyeListItemImage" dojoAttachPoint="imgNode">' +
			'  <div class="dojoxFisheyeListItemRemove" dojoAttachPoint="rmvNode"><span class="count" dojoAttachPoint="cntNode"></span></div>' +
			'  <div class="dojoxFisheyeListItemLabel" dojoAttachPoint="lblNode"></div>' +
			'  <div class="dojoxFisheyeListItemPrice" dojoAttachPoint="prcNode"></div>' +
			'</div>',

		onMouseOver: function(e){
		  if (e.target.tagName != 'IMG')
			  if (e.target == this.rmvNode) {
			    //this.lblNode.innerHTML = 'Remove: ' + this.label;
			    //this.labelW = dojo.marginBox(this.lblNode).w;
					dojo.addClass(this.rmvNode, "hover");
				} else {
					dojo.removeClass(this.rmvNode, "hover");
					return;
				}
			dojo.addClass(this.domNode, "dojoxFishSelected");
	  	this.parent._positionLabel(this);
		},

		onMouseOut: function(e){
			dojo.removeClass(this.domNode, "dojoxFishSelected");
			if (e.target == this.rmvNode) {
				dojo.removeClass(this.rmvNode, "hover");
				//this.lblNode.innerHTML = this.label;
				this.labelW = dojo.marginBox(this.lblNode).w;
			}
		},

		onClick: function(e){
		  if (e.target == this.rmvNode) this.parent.parent.removeProduct(this);
			else location.href = this.url;
		}
	}

});
