if (!document.trace) {
	this.trace = function(output) {
		//if (console.log && output) console.log(output);
	}
}

/**
 * ScrollBar (fixed horizontal)
 * @uses mootools-release-1.11.js
 */
var ScrollBar = new Class({
	
	initialize : function() {
		trace('ScrollBar.initialize()');
		
		this.scrollPane = {};
		this.bar = {};
		this.handle = {};
		this.handleL = {};
		this.handleC = {};
		this.handleR = {};
		
		this.minHandleWidth = 100;
		this.maxHandleWidth = 10000;
		this.handlePaddingH = 2;
		
		// styles...
		this.styles = {
			scrollTrack: 			sn_img_base_url + '/browser_scroll_track_alt.png',
			scrollHandleLeft: 		sn_img_base_url + '/browser_scroll_handle_l_alt.png',
			scrollHandleCenter: 	sn_img_base_url + '/browser_scroll_handle_c_alt.png',
			scrollHandleRight: 		sn_img_base_url + '/browser_scroll_handle_r_alt.png'
		};
		
		this.rendered = false;
		this.showing = true;
		this.dragging = false;
		this.handleHasFocus = false;
		
	},
	
	
	attachTo : function(scrollPane) {
		if (!scrollPane) return;
		
		this.scrollPane = scrollPane;
		
		this.render();
	},
	
	
	render : function() {
		trace('ScrollBar.render()');
		
		this.rendered = true;
		
		var bar = new Element('div');
		bar.setStyle('position', 'absolute');
		bar.setStyle('z-index', '10');
		bar.setStyle('width', this.scrollPane.parentWidth + 'px');
		bar.setStyle('height', '19px');
		bar.setStyle('top', this.scrollPane.scrollParent.getCoordinates().height - 5 + 'px');
		
		bar.setStyle('left', '12px');	
		
		// the bar cannot use a PNG (filter: AlphaImageLoader) or it will mess up the event flow in IE6...
		// this should be a GIF image or PNG that does not require alpha...
		bar.setStyle('background', 'url(' + this.styles.scrollTrack + ') no-repeat');
		bar.injectAfter(this.scrollPane.scrollParent);
		this.bar = bar;
		
		var handle = new Element('div');
		handle.setStyle('overflow', 'hidden');
		handle.setStyle('position', 'relative');
		handle.setStyle('width', '30px');
		handle.setStyle('height', '19px');
		handle.setStyle('left', '0px');
		handle.injectInside(this.bar);
		this.handle = handle;
		
		var handleL = new Element('div');
		handleL.setStyle('overflow', 'hidden');
		handleL.setStyle('position', 'absolute');
		handleL.setStyle('width', '10px');
		handleL.setStyle('height', '19px');
		handleL.setStyle('left', '0px');
		if (window.ie && !window.ie7) {
			handleL.setStyle('filter', 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.styles.scrollHandleLeft + '", sizingMethod="scale")');
		} else {
		handleL.setStyle('background', 'url(' + this.styles.scrollHandleLeft + ') no-repeat');
		}
		handleL.injectInside(this.handle);
		this.handleL = handleL;
		
		var handleC = new Element('div');
		handleC.setStyle('overflow', 'hidden');
		handleC.setStyle('position', 'absolute');
		handleC.setStyle('width', '10px');
		handleC.setStyle('height', '19px');
		handleC.setStyle('left', '10px');
		if (window.ie && !window.ie7) {
			handleC.setStyle('filter', 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.styles.scrollHandleCenter + '", sizingMethod="scale")');
		} else {
			handleC.setStyle('background', 'url(' + this.styles.scrollHandleCenter + ') repeat-x');
		}
		handleC.injectInside(this.handle);
		this.handleC = handleC;
		
		var handleR = new Element('div');
		handleR.setStyle('overflow', 'hidden');
		handleR.setStyle('position', 'absolute');
		handleR.setStyle('width', '10px');
		handleR.setStyle('height', '19px');
		handleR.setStyle('left', '20px');
		if (window.ie && !window.ie7) {
			handleR.setStyle('filter', 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.styles.scrollHandleRight + '", sizingMethod="scale")');
		} else {
		handleR.setStyle('background', 'url(' + this.styles.scrollHandleRight + ') no-repeat');
		}
		
		handleR.injectInside(this.handle);
		this.handleR = handleR;
		
		this.maxHandleWidth = this.bar.getCoordinates().width;
		
		this.updateSize();
		this.updatePosition();
		
		this.bar.addEvent('mousedown', this.onPressBar.bindWithEvent(this));
		this.handle.addEvent('mousedown', this.onDragStart.bindWithEvent(this));
		this.handle.addEvent('mouseover', this.onHandleOver.bindWithEvent(this));
		this.handle.addEvent('mouseout', this.onHandleOut.bindWithEvent(this));
	},
	
	
	onHandleOver : function(e) {
		this.handleHasFocus = true;
	},
	
	
	onHandleOut : function(e) {
		this.handleHasFocus = false;
	},
	
	
	onPressBar : function (e) {
		if (this.handleHasFocus) return;
		
		var clickPosX = e.client.x - this.trackBasePosX;
		var amount = clickPosX / this.handleMaxX;
		this.scrollPane.setScrollAmountX(amount, true);
	},
	
	
	onDragStart : function(e) {
		
		e.stopPropagation();
		e.preventDefault();
		
		// IE fix to prevent selection while dragging...
		
		if (window.ie) {
			document.onselectstart = function() { return false; };
  		}
		
		this.dragging = true;
		
		// store drag coordinate rules values for use during drag operation...
		
		this.handleOffsetX = e.client.x - e.target.getPosition().x;
		

		
		// event bindings...
		
		this.handle.removeEvents('mousedown');
		document.addEvent('mousemove', this.onDragProgress.bindWithEvent(this));
		document.addEvent('mouseup', this.onDragComplete.bindWithEvent(this));
	},
	
	
	onDragProgress : function(e) {
		
		// set target position for drag...
		
		var dragX = e.client.x - this.trackBasePosX - this.handleOffsetX;
		if (dragX < this.handleMinX) dragX = this.handleMinX;
		if (dragX > this.handleMaxX) dragX = this.handleMaxX;
		
		// apply target position for drag...
		
		this.handle.setStyle('left', dragX + 'px');
		
		// apply scroll amount directly to attached scroll pane...
		
		var amount = dragX / this.handleMaxX;
		this.scrollPane.setScrollAmountX(amount);
	},
	
	
	onDragComplete : function(e) {
		
		// IE fix to prevent selection while dragging (release)...
		
		if (window.ie) {
			document.onselectstart = null;
  		}
  		
		this.dragging = false;
		
		// apply final amount directly to attached scroll pane...
		
		this.scrollPane.quantize();
		
		// event bindings...
		
		e.preventDefault();
		
		document.removeEvents('mouseup');
		document.removeEvents('mousemove');
		this.handle.addEvent('mousedown', this.onDragStart.bindWithEvent(this));
	},
	
	
	updateSize : function() {
		
		if (!this.rendered) return;
	
		// update whether scrolling is needed...
		
		if (this.scrollPane.parentWidth >= this.scrollPane.contentWidth) {
			if (this.showing) this.hide();
			return;
		} else {
			if (!this.showing) this.show();
		}
		
		//
		
		this.updateExtents();
		
		// update handle size...
		
		var handleWidth = this.scrollPane.parentWidth * this.scrollPane.parentWidth / this.scrollPane.contentWidth + this.handlePaddingH * 2;
		if (handleWidth < this.minHandleWidth) handleWidth = this.minHandleWidth;
		if (handleWidth > this.maxHandleWidth) handleWidth = this.maxHandleWidth;
		
		this.handle.setStyle('width', handleWidth);
		this.handleC.setStyle('width', handleWidth - 20 + 'px');
		this.handleR.setStyle('left', handleWidth - 10 + 'px');
	},
	
	
	updatePosition : function() {
		
		if (!this.rendered) return;
		
		this.updateExtents();

		// only update the scrollbar position when not dragging (internally updating)...
		
		if (!this.dragging) {
			var nudge = -this.handlePaddingH;
			var x = this.scrollPane.parentWidth * this.scrollPane.getScrollAmountX();
			var maxX = this.bar.getCoordinates().width - this.handle.getCoordinates().width;
			if (x < 0) x = 0;
			if (x > maxX) x = maxX;
			
			this.handle.setStyle('left', x + nudge + 'px');
		}
	},
	
	
	updateExtents : function() {
		this.trackBasePosX = this.bar.getPosition().x;
		this.handleMinX = -this.handlePaddingH;
		this.handleMaxX = this.bar.getCoordinates().width - this.handlePaddingH - this.handle.getCoordinates().width;
	},
	
	
	hide : function() {
		trace('ScrollBar.hide()');
		
		if (!this.rendered) return;
		this.showing = false;
		this.bar.setStyle('display', 'none');
	},
	
	
	show : function() {
		trace('ScrollBar.show()');
		
		if (!this.rendered) return;
		this.showing = true;
		this.bar.setStyle('display', 'block');
	},
	
	
	toString : function() {
		return "[ScrollBar]";
	}
});