$.extend($.ui.draggable.prototype, (function (orig) {
  return {
    _mouseCapture: function (event) {
      var result = orig.call(this, event);
      if (result && $.browser.msie) event.stopPropagation();
      return result;
    }
  };
})($.ui.draggable.prototype["_mouseCapture"]));

var Snap = function() {

	var o = this; // copying "this" pointer into "o" because of jquery may override it locally

	o.init = function(SnapBoxId, SnapSrcUrl, imagesSrcUrl){
		o.images = [];
		o.zindex = 0;
		o.SnapSrcUrl = SnapSrcUrl;
		o.imagesSrcUrl = imagesSrcUrl;
		o.SnapBox = $(SnapBoxId);
		o.getSnap();
		o.isModified = false;
	};

	o.getSnap = function(){
		$.getJSON(o.SnapSrcUrl, function(data){
			o.id = data.id;
			o.width = data.width;
			o.height = data.height;
			o.x = data.x;
			o.y = data.y;
			o.images = data.elements;
			o.backgroundId = data.image_id;
			o.initBoxes();
		});
	};

	o.initBoxes = function(){

		o.SnapBox
		.addClass("snapBox")

		// locking position, height and width
		.css('position','fixed')
		.css('height',o.SnapBox.height())
		.css('width',o.SnapBox.width());

		o.viewBox = $(document.createElement('div'))
		.addClass("viewBox")
		.appendTo(o.SnapBox)
		.css('height','100%')
		.css('width','100%')
		.css('overflow','hidden');


		o.toolBox = $(document.createElement('div'))
		.addClass("toolBox")
		.css('position','absolute')
		.css('top','0px')
		.css('right','0px')
		.appendTo(o.SnapBox);

		o.snapBtn = $(document.createElement('div'))
		.addClass("snapBtn")
		.click(function(){
			return snap.snipsnap();
		})
		.hover(
			function () {
				o.snapBtn.addClass("hover");
			}, 
			function () {
				o.snapBtn.removeClass("hover");
			}
		)
		.appendTo(o.toolBox);

		o.container = {};
		o.container.width =  2*o.width - o.viewBox.width();
		o.container.height = 2*o.height - o.viewBox.height();
		o.container.x = Math.round(o.viewBox.width()/2 - o.container.width/2);
		o.container.y = Math.round(o.viewBox.height()/2 - o.container.height/2);

		var margin = 0;

		o.container.containerEl = $(document.createElement('div'))
		.width((o.container.width+2*margin)+"px")
		.height((o.container.height+2*margin)+"px")
		.css('position', 'relative') 
		.css('left',(o.container.x)+"px")
		.css('top', (o.container.y)+"px")
		.addClass("snapContainer")
		.appendTo(o.viewBox);

		o.mx = Math.round((o.container.width - o.width) / 2) + o.x; 
		o.my = Math.round((o.container.height - o.height) / 2) + o.y;

		o.snapEl = $(document.createElement('div'))
		.css('top',o.my+"px")
		.css('left',o.mx+"px")
		.css('cursor','move')
		.css('background','url(/image/read/'+o.backgroundId+')')
		.width((o.width)+"px")
		.height((o.height-0)+"px")
		.addClass("snap")
		.appendTo($(o.container.containerEl))
		.draggable({ 
			containment: 'parent',
			cursor:'move'
		})
		.dblclick(function(event) {
			if( $(event.target).is("div") ) {
				o.snipsnap();
			}
		});
		o.snapEl.addTouch(); // for iphone gesture support	

		$(o.images).each(function(){
			var that = this;
			var iy = Math.round(o.height/2) + this.y;
			var ix = Math.round(o.width/2)  + this.x;
			var iz = this.z;
			if (o.zindex < iz) {
				o.zindex = iz;
			}

			var imgContainer = $(document.createElement('div'))
			.attr('id',this.image_id)
			.addClass('imageItem')
			.css('top',iy+"px")
			.css('left',ix+"px")
			.css('z-index',iz)
			.css('cursor','hand')
			.appendTo(o.snapEl)
			.draggable({ 
				containment: 'parent',
				cursor:'hand',
				drag: function(event, ui) {
					event.stopPropagation();
					event.stopImmediatePropagation();
					o.isModified = true; 
				},
				start : function(event, ui) {
					event.stopPropagation();
					o.snapEl.draggable('disable');
				},
				stop : function(event, ui) {
					o.snapEl.draggable('enable');
				}
			});
			
			var shadow1 = $(document.createElement('div'))
			.addClass('shadow')
			.appendTo(imgContainer);
			
			var shadow2 = $(document.createElement('div'))
			.addClass('shadow')
			.appendTo(shadow1);
			
			var shadow3 = $(document.createElement('div'))
			.addClass('shadow')
			.appendTo(shadow2);
			
			$(document.createElement('img'))
			.attr({ src: '/image/read/'+this.image_id+'/300', title: ''})
			.appendTo(imgContainer)
			.css('cursor','hand')
			.click(function(event){
				event.stopImmediatePropagation(); 
				o.zindex = o.zindex+1;
				imgContainer.css('z-index',o.zindex); //TODO add pointer for max zindex of images
			})
			.dblclick(function(event){
				event.stopImmediatePropagation(); 
				var path = '/image/read/'+that.image_id+'/600';
				$.fn.colorbox({href:path,photo:true,open:true,resize:false,opacity:0.40});
			})
			.addTouch(); // for iphone gesture support
		});
	};

	o.snipsnap = function() {
		if (o.isModified) {
			o.isModified = false;
			o.saveSnap();
		} else {
			var path = '/snap/snipsnap/'+o.id;
			$.fn.colorbox({href:path,iframe:true,open:true,width:'500px',height:'400px',opacity:0.40});
		}
		return false;
	};

	o.saveSnap = function() {
		var elements = [];
		$("div.snap div.imageItem").each(function() {
			var that = $(this);
			var el = {};
			el.image_id = that.attr('id');
			el.x  = parseInt(that.css('left'),10) - Math.round(o.width/2);
			el.y  = parseInt(that.css('top'),10) - Math.round(o.height/2);
			el.z  = parseInt(that.css('z-index'),10);
			el.r = 0; // unused yet
			el.s = 0; // unused yet
			elements.push(el);
		});

		// build snap object
		var snap = {};
		snap.elements = elements;
		snap.id = o.id;
		snap.x = parseInt(o.snapEl.css('left'),10) - Math.round((o.container.width - o.width) / 2);
		snap.y = parseInt(o.snapEl.css('top'),10) - Math.round((o.container.height - o.height) / 2);
		snap.image_id = o.backgroundId;
		var jsonData = $.toJSON(snap);
		$.ajax({ 
			url: '/snap/create/',
			type: 'POST',
			cache: false,
			data: {"snap":jsonData},
			success: function(data) {
				o.id = data;
				$.fn.colorbox({href:'/snap/snipsnap/'+data,iframe:true,open:true,width:'500px',height:'400px',opacity:0.65});
			} 
		});
	};

};

