/** * %%INFO 2008-07-18 15:30:04+0200 rgarcia%%
 * @author Ruben Garcia
 * @usage PrelistenWidget(Object options)
 * @example
 * <script type="text/javascript">
 * // <![CDATA[
var pW = new PrelistenWidget([options]);
 * // ]]>
 * </script>
 */

//Needed methods for string manipulation
if(typeof 'x'.startsWith != 'function'){
	String.prototype.startsWith=function(pattern){return this.indexOf(pattern)===0;};
}

PrelistenWidget = Class.create();
PrelistenWidget.prototype = {
	initialize: function(options) {
		this.options = Object.extend({
			oidPrefix:               'oid_',
			parent:                  'body',
			buttonClassname:         'prelisten',
			clickableEntity:         'img',
			actionEvent:             'click',
			playerURL:               'ajax/_ajaxFtPlayer',
			swapImage:               true,
			swapImageUrl:            'img/icons/icon_prelisten_stop.gif',
			swapBackImageUrl:        'img/icons/icon_prelisten_play.jpg',
			changeImageOnClick:      true,
			prelistenDivName:        'flashPlayer',
			prelistenDivContentName: 'flashPlayerContent',
			onClick:                 null,
			draggable:               true,
			dragId:                  'flashPlayerLayerDrag',
			hasTitleBar:             false,
			titleLabel:              'Prelisten',
			titleId:                 'flashPlayerLayerTitle',
			hasCloseButton:          true,
			closeLabel:              'close',
			closeId:                 'flashPlayerLayerClose',
			hasCloseButtonImage:     true,
			closeImageUrl:           'img/icons/icon_prelisten_close.gif',
			dragOpacity:             false,
			dragMarginX:             0,
			dragMarginY:             0,
			dragConstrainParent:     false,
			playerHeight:            201,
			playerWidth:             350,
			scrollbaroffset:         20,
			observedClassName:       'plw',
			offsetX:                 0,
			offsetY:                 0
		}, options || {});

		this.eventHandler = this.onEvent.bindAsEventListener(this);
		this.showPlayer = this.openPlayer.bindAsEventListener(this);
		this.hidePlayer = this.closePlayer.bindAsEventListener(this);
		this.dragConstrain = this.dragSnap.bind(this);

		this.divWidth = 0;
		this.divHeight = 0;
		this.closeHandler = false;

		this.buttons = $$(this.options.parent + ' ' + '.' + this.options.buttonClassname + ' ' + this.options.clickableEntity);
		this.prelistenDiv = $(this.options.prelistenDivName);
		this.prepareElements();
	},
	prepareElements: function() {
		for(var i=0; i<this.buttons.length; i++) {
			var button = $(this.buttons[i]);
			if(button.hasClassName(this.options.observedClassName)) {
				continue;
			}
			button.addClassName(this.options.observedClassName);
			var classes = button.up().up().classNames().toArray();
			for(var j=0; j<classes.length; j++) {
				if(classes[j].startsWith(this.options.oidPrefix)) {
					var orderId = classes[j].substr(this.options.oidPrefix.length);
//					button.oid = orderId
					button.observe(this.options.actionEvent, this.eventHandler);
					if(this.options.swapImage) {
						var iW = new ImageWidget(button, {imageFullPath: this.options.swapBackImageUrl, hoverImageFullPath: this.options.swapImageUrl, changeImageOnClick: this.options.changeImageOnClick});
					}
				}
			}
		}
		if(!this.prelistenDiv) {
			var dragBar;
			this.prelistenDiv = document.createElement('div');
			Element.extend(this.prelistenDiv);
			this.prelistenDiv.setAttribute('id',this.options.prelistenDivName);
			if(this.options.draggable) {
				dragBar = document.createElement('div');
				Element.extend(dragBar);
				dragBar.setAttribute('id', this.options.dragId);
				if(this.options.hasTitleBar) {
					var titleBar = document.createElement('span');
					titleBar.setAttribute('id', this.options.titleId);
					titleBar.update(this.options.titleLabel);
					dragBar.appendChild(titleBar);
				}
				if(this.options.hasCloseButton) {
					var closeButton = document.createElement('span');
					Element.extend(closeButton);
					closeButton.setAttribute('id', this.options.closeId);
					if(!this.options.hasCloseButtonImage){
						closeButton.update(this.options.closeLabel);
					} else {
						var closeImage = document.createElement('img');
						closeImage.setAttribute('src', this.options.closeImageUrl);
						closeImage.setAttribute('alt', this.options.closeLabel);
						closeButton.appendChild(closeImage);
					}
					closeButton.observe('click', this.hidePlayer);
					closeButton.setStyle({
						cursor: 'default'
					});
					dragBar.appendChild(closeButton);
				}
				dragBar.setStyle({
					cursor: 'move'
				});
				this.prelistenDiv.appendChild(dragBar);
			}
			this.prelistenDivContent = document.createElement('div');
			Element.extend(this.prelistenDivContent);
			this.prelistenDivContent.setAttribute('id',this.options.prelistenDivContentName);
			this.prelistenDiv.appendChild(this.prelistenDivContent);
			document.body.appendChild(this.prelistenDiv);
			this.prelistenDiv.setStyle({
				position: 'absolute',
				zIndex: 1000
			});
			if(this.options.draggable) {
				var dragOptions = {
					handle: dragBar,
					snap: this.dragConstrain
					//, scroll: window
				};
				if(!this.options.dragOpacity) {
					dragOptions.starteffect = Prototype.emptyFunction();
					dragOptions.endeffect = Prototype.emptyFunction();
				}
				this.draggable = new Draggable(this.prelistenDiv, dragOptions);
			}
			this.prelistenDiv.hide();
		}
	},
	getButtonOid: function(element) {
		var classes = element.up().up().classNames().toArray();
		for(var j=0; j<classes.length; j++) {
			if(classes[j].startsWith(this.options.oidPrefix)) {
				return classes[j].substr(this.options.oidPrefix.length);
			}
		}
	},
	onEvent: function(event) {
		var element = Event.element(event);
		if(this.options.onClick) {
			this.options.onClick(event);
		} else {
			var oid = this.getButtonOid(element);
			var tmp = new Ajax.Updater(this.options.prelistenDivContentName,
				this.options.playerURL,
				{
					parameters: 'item=' + oid,
					asynchronous: true,
					evalScripts: true,
					onSuccess: this.showPlayer(event)
				}
			);
		}
		Event.stop(event);
	},
	openPlayer: function(event) {
		this.movePlayer(event);
		this.prelistenDiv.show();
	},
	closePlayer: function() {
		this.prelistenDiv.hide();
		$(this.options.prelistenDivContentName).update();
	},
	movePlayer: function(event) {
		// Effect.move checken!
		var x = Event.pointerX(event) + this.options.offsetX;
		var y = Event.pointerY(event) + this.options.offsetY;
		var screen = this.getInnerDimensions();
		var nX = screen.width - this.options.playerWidth;
		if(x > nX) { x = nX; }
		var nY = screen.height - this.options.playerHeight;
		if(y > nY) { y = nY; }
		var tmp = new Effect.Move(this.prelistenDiv, {duration: 0, x: x, y: y, mode: 'absolute'});
	},
	dragSnap: function(x,y,draggable) {
		var parent_dimensions;
		function constrain(n, lower, upper) {
			if (n > upper) { return upper; }
			else if (n < lower) { return lower; }
			else { return n;}
		}

		var element_dimensions = Element.getDimensions(draggable.element);
		if(this.options.dragConstrainParent) {
			parent_dimensions = Element.getDimensions(draggable.element.parentNode);
		} else {
			parent_dimensions = this.getInnerDimensions();
		}
		//console.log('x: ', x, 'maxX: ', parent_dimensions.width - element_dimensions.width - this.options.dragMarginX)
		//console.log('y: ', y, 'maxY: ', parent_dimensions.height - element_dimensions.height - this.options.dragMarginY)
		return[
			constrain(x, 0, parent_dimensions.width - element_dimensions.width - this.options.dragMarginX),
			constrain(y, 0, parent_dimensions.height - element_dimensions.height - this.options.dragMarginY)
		];
	},
	getScrollXY: function() {
		var scrOfX = 0, scrOfY = 0;
		if( typeof( window.pageYOffset ) == 'number' ) {
			//Netscape compliant
			scrOfY = window.pageYOffset;
			scrOfX = window.pageXOffset;
		} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
			//DOM compliant
			scrOfY = document.body.scrollTop;
			scrOfX = document.body.scrollLeft;
		} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
			//IE6 standards compliant mode
			scrOfY = document.documentElement.scrollTop;
			scrOfX = document.documentElement.scrollLeft;
		}
		return {x: scrOfX, y: scrOfY, left: scrOfX, top: scrOfY};
	},
	getInnerDimensions: function() {
		// Get window dimensions
		var wX,wY;
		var scroll = this.getScrollXY();
		if (self.innerHeight) { // all except Explorer
			wX = self.innerWidth + scroll.x;
			wY = self.innerHeight + scroll.y;
		} else if (document.documentElement && document.documentElement.clientHeight) { 	// Explorer 6 Strict Mode
			wX = document.documentElement.clientWidth + scroll.x;
			wY = document.documentElement.clientHeight + scroll.y;
		} else if (document.body) {// other Explorers
			wX = document.body.clientWidth + scroll.x;
			wY = document.body.clientHeight + scroll.y;
		}
		return {width: wX - this.options.scrollbaroffset, height: wY - this.options.scrollbaroffset};
	}
};