/**
 * Screen Drag Class
 * 
 * @author   Volodymyr Iatsyshyn
 * @date     2009-05-25
 * @see
 */

if (!window.Keepa)
	var Keepa = {};

dojo.provide('Keepa.ScreenDrag');

dojo.declare('Keepa.ScreenDrag', null, {
	screens: new Array(),
	width: 1800,
	height: 1200,
	currentX: 0,
	currentY: 0,
	doDragBind_: null,
	doFinishDragBind_: null,
	lastMouseX: 0,
	lastMouseY: 0,
	lastUpdate: 0,
	isDraging: false,
	
	constructor: function (container) {
		this.makeScreens(container);
		this.refreshScreens(0, 0);
		
		dojo.connect(container.parentNode, 'mousewheel', this, 'doScroll_');
		dojo.connect(container.parentNode, 'DOMMouseScroll', this, 'doScroll_');
		
		dojo.subscribe('container-size-changed', this, 'onContainerSizeChange_e_');
		dojo.subscribe('on-current-project-changed', this, 'onCurrentProjectChanged_');
		dojo.subscribe('try-change-project', this, 'onTryChangeProject_');
		dojo.subscribe('move-to-initals', this, 'onMoveToInitals_');
		dojo.subscribe('cancel-drag', this, 'onCancelDrag_');
		
		dojo.query('.screen-drag-container A, .screen-drag-container IMG').forEach(function (e) {
			dojo.connect(e, 'mousedown', function (e){
				e.stopPropagation();
			});			
		});
	},
	
	onCancelDrag_: function () {
		this.doFinishDrag_();
		
		return this;
	},
	
	onMoveToInitals_: function () {
		this.refreshScreens(0, 0);
		
		return this;
	},
	
	onTryChangeProject_: function (projectId, nodefault) {
		if (!this.isDraging) {
		    dojo.publish('open-menu-for', [projectId]);
			dojo.publish('on-current-project-changed', [projectId, nodefault]);
		}
		
		this.doFinishDrag_({});
		
		return this;
	},
	
	onCurrentProjectChanged_: function (projectId, nodefault) {
		if (!nodefault)
			this.refreshScreens(0, 0);
		
		dojo.query('.project-container A, .project-container IMG').forEach(function (e) {
			dojo.connect(e, 'mousedown', function (e){
				e.stopPropagation();
			});			
		});
		
		return this;
	},
	
	onContainerSizeChange_e_: function () {
	    var box = dojo.contentBox(this.screens[3]);
		var dx = dojo.style(this.screens[3], 'left') < this.screenW ? 0 : (box.w - this.width);
		var dy = dojo.style(this.screens[3], 'top') < this.screenH ? 0 : (box.h - this.height);
		
		return this.refreshScreens(this.currentX + dx, this.currentY + dy);
	},
	
	makeScreens: function (container) {
		this.screens[3] = container;
		for(var i = 0; i < 3; ++i)
			this.screens[i] = this.clone(container);
		
		dojo.connect(this.screens[3].parentNode, 'mouseleave', this, 'doFinishDrag_');
		
		for(i = 0; i < 4; ++i) {
			dojo.connect(this.screens[i], 'mousedown', this, 'startDrag');
			dojo.connect(this.screens[i], 'mouseup', this, 'doFinishDrag_');
		}
		
		return this;
	},
	
	clone: function (container) {
		var c = document.createElement(container.tagName);
		c.className = container.className;
		c.innerHTML = container.innerHTML;
		container.parentNode.appendChild(c);
		return c;
	},
	
	refreshScreens: function (x, y) {
		var box = dojo.contentBox(this.screens[3]);
		this.width = box.w;
		this.height = box.h;
		
		var screen = dojo.contentBox(this.screens[3].parentNode);
		this.screenW = screen.w;
		this.screenH = screen.h;

		this.currentX = (x + this.width) % this.width;
		this.currentY = (y + this.height) % this.height;
		
		this.doRefresh_();
		
		return this;
	},
	
	startDrag: function (e) {
	    if (e.button > 1) return ;
	
		this.lastMouseX = e.clientX;
		this.lastMouseY = e.clientY;
		
		dojo.publish('on-start-drag', []);

		this.doDragBind_ = dojo.connect(document, 'mousemove', this, 'doDrag_');
		
		this.isDraging = false;		
		this.doRefresh_();
		
		dojo.query('.screen-drag-container').forEach(function (e2) {
	        dojo.style(e2, 'cursor', 'url(/keepa/img/closedhand.cur), move');
		});		
		
		return this;
	},
	
	doDrag_: function (e) {
		if (!this.isDraging) {
			this.isDraging = Math.abs(this.lastMouseX - e.clientX) > 20 || Math.abs(this.lastMouseY - e.clientY) > 20;
		}
		
		if (e.clientX < 0 || e.clientY < 0 || e.clientX > this.screenW || e.clientY > this.screenH)
			return this.doFinishDrag_(e);
			
		this.refreshScreens(
			this.currentX + e.clientX - this.lastMouseX,
			this.currentY + e.clientY - this.lastMouseY
		);
		
		this.lastMouseX = e.clientX;
		this.lastMouseY = e.clientY;

		return this;
	},
	
	doRefresh_: function() {
		if (this.isDraging) {
			setTimeout(dojo.hitch(this, 'doRefresh_'), 250);
		}
		
		for(var i = 0; i < 4; ++i) {
			dojo.style(this.screens[i], {
				left: Math.round(this.currentX + ((i >> 1) - 1) * this.width) + "px",
				top: Math.round(this.currentY + (i % 2 - 1) * this.height) + "px"
			});
		}
		
		return this;
	},
	
	doFinishDrag_: function (e) {
		this.isDraging = false;
		
		dojo.disconnect(this.doDragBind_);
		dojo.query('.screen-drag-container').forEach(function (e2) {
	        dojo.style(e2, 'cursor', 'url(/keepa/img/openhand.cur), move');
		});		
		
		return this;
	},
	
	doScroll_: function (event) {
		this.refreshScreens(this.currentX, this.currentY + 100 * (event.detail ? Math.abs(event.detail) / -event.detail : Math.abs(event.wheelDelta) / event.wheelDelta));
		return this;
	}
});

dojo.mixin(Keepa.ScreenDrag, {
	initialize: function () {
		new Keepa.ScreenDrag(dojo.byId('screen-drag'));
		return this;
	}
});

dojo.addOnLoad(Keepa.ScreenDrag, 'initialize');

dojo.addOnLoad(function() {
    dojo.query('*[mouse-over-image]').forEach(function (e) {
        dojo.create('div', {style:{width:'0px', backgroundImage: ('url(' + dojo.attr(e, 'mouse-over-image') + ')')}}, e);
        
        dojo.connect(e, 'mouseover', function (event) {
            if (event.currentTarget.timer_) {
                clearTimeout(event.currentTarget.timer_);
                event.currentTarget.timer_ = null;
            }
        	dojo.style(event.currentTarget, {
                backgroundImage: 'url(' + dojo.attr(e, 'mouse-over-image') + ')',
                backgroundPosition: ''
            });
        });

        dojo.connect(e, 'mouseout', function (event) {
            var t = event.currentTarget; 
            if (t.timer_) {
                clearTimeout(t.timer_);
            }
            
        	t.timer_ = setTimeout(function() {
        	    dojo.style(t, 'backgroundImage', '');
        	    t.timer_ = null;
        	}, 100);
        }); 
    });
});
