/**
* handles the observeing of the whole document (keydown, click)
*
* example for click:
* 	var index = i4_Document_listener.click({
*		exclude: ['.edit_bar', '.edit_button_container', '.edit_button_container *'],
*		callback: (function() {
*			this.hide_all();		
*		}).bind(this)
*	});
*
* example for stop click:
*	i4_Document_listener.stop_click(index);
*
* example for keydown:
* 	var index = i4_Document_listener.keydown({
*		keys: [27, nn, nn],
*		callback: function() {
*			i4_Popup.remove_all();
*		}
*	});
*
* example for stop keydown:
*	i4_Document_listener.stop_keydown(index);
*/
var i4_Document_listener = {
	clicks: [],
	keydowns: [],
	mouseouts: [],
	
	index_click: 0,
	index_keydown: 0,
	index_mouseout: 0,
	
	handler_mousemove: 0,
	handler_click: 0,
	handler_keydown: 0,

	run: function(){
		
		// click	
		if (this.clicks.size() > 0) {
			if (this.handler_click == 0) {
				this.handler_click = document.on('click', (function(event){
					// log('click');
					// log(this.clicks);
					this.clicks.each(function(item) {
						if (item[1].callback) {
							var ok = true;
							if (item[1].exclude) {
								item[1].exclude.each(function(item2) {
									$$(item2).each(function(item3){
										if (item3 === event.target) {
											ok = false;
										}
								
									});
								});
							}
							
							if (ok) {
								item[1].callback();
							}
							
						}
					});
				
				}).bind(this));
			} else {
				this.handler_click.start();
			}// if handler_click == 0
		} else {
			if (this.handler_click != 0) { 
				this.handler_click.stop();
			} // if handler_click != 0
		}// if clicks.size > 0
		
		// keydown
		if (this.keydowns.size() > 0) {
			if (this.handler_keydown == 0) {
				this.handler_keydown = document.on('keydown', (function(event){
					// log('keydown');
					this.keydowns.each(function(item) {
						if (item[1].callback) {
							var ok = false;
							
							if (item[1].keys) {
								
								item[1].keys.each(function(item2) {
									if (item2 == event.keyCode) {
										ok = true;
									}
								});
								
							} else {
								ok = true;
							}
							
							if (ok) {
								item[1].callback();
							}
							
						}
					});
					
				}).bind(this));
			} else {
				this.handler_keydown.start();
			}// if handler_keydown == 0
		} else {
			if (this.handler_keydown != 0) { 
				this.handler_keydown.stop();
			} // if handler_keydown != 0
		}// if keydowns.size > 0
		
		
		// mouse position
		if (this.mouseouts.size() > 0) {
			if (this.handler_mousemove == 0) {
			
				this.handler_mousemove = document.on('mousemove', (function(event){
					// log('mousemove');
					this.mouseouts.each(function(item) {
						
						if (item[1].callback) {
							var ok = false;
							
							var distance = 0;
							if (item[1].distance) {
								distance = item[1].distance;
							}
							
							if (item[1].element) {
								var pointer = event.pointer();
								
								var measure_left = item[1].element.measure('left');
								var measure_top = item[1].element.measure('top');
								
								var x_min = measure_left-distance;
								var x_max = measure_left+item[1].element.measure('width')+distance;
								var y_min = measure_top-distance;
								var y_max = measure_top+item[1].element.measure('height')+distance;
								
								if (!(pointer.x > x_min && pointer.x < x_max) || !(pointer.y > y_min && pointer.y < y_max)) {
									ok = true;
								}
								
							} 
							
							if (ok) {
								item[1].callback();
							}
							
						}
					});
					
				}).bind(this));
				
			} else {
				this.handler_mousemove.start();
			}// if handler_mousemove == 0
		} else {
			if (this.handler_mousemove != 0) { 
				this.handler_mousemove.stop();
			} // if handler_mousemove != 0
		}// if mouseout.size > 0
		
	}, // i4_Document_listener.run()
	
	click: function(params) {
		var index = this.index_click++;
		this.clicks.push([index, params]);	
		
		this.run();
		
		return index;
	}, // i4_Document_listener.click()
	
	stop_click: function(index) {
		this.clicks.each((function(item) {
			if (item[0] == index) {
				this.clicks = this.clicks.without(item);
			}
		}).bind(this));
		
		this.run();
	}, // i4_Document_listener.stop_click()
	
	keydown: function(params) {
		var index = this.index_keydown++;
		this.keydowns.push([index, params]);
		
		this.run();
		
		return index;
	}, // // i4_Document_listener.keydown()
	
	stop_keydown: function(index) {
		this.keydowns.each((function(item) {
			if (item[0] == index) {
				this.keydowns = this.keydowns.without(item);
			}
		}).bind(this));
		
		this.run();
	}, // i4_Document_listener.stop_keydown()
	
	mouseout: function(params) {
		var index = ++this.index_mouseout;
		this.mouseouts.push([index, params]);
		
		this.run();
		
		return index;
	}, // // i4_Document_listener.mouseout()
	
	stop_mouseout: function(index) {
		this.mouseouts.each((function(item) {
			if (item[0] == index) {
				this.mouseouts = this.mouseouts.without(item);
			}
		}).bind(this));
		
		this.run();
	} // i4_Document_listener.stop_mouseout()
} // i4_Document_listener

