/**
 * beautifulScrollbar
 * 
 * @description		get Divs with overflow and replace Scrollbar with pagination
 * @author				Daniel Sturm
 * @created				09/03/05
 */

var beautifulScrollbar = new Class({

	/**
	 * class implements...
	 */
	Implements: Options,

  /**
	 * default options
	 */
	options: {
		container:     'div.beautifulScrollbar',
		debug:         false,
		localPath:     false,
		shortenScript: 'zs.beautifulScrollbar.ajaxShortenHTML.php'
	},

	/**
	 * initialize the class
	 * @access public
	 * @param	{optional:object} individual options
	 * @return {void}
	 */
	initialize: function(options) {
		this.setOptions(options);

		if ( this.options.debug )
			window.addEvent('domready', this._initDebug.bind(this));

		if ( ! this.options.localPath )
			window.addEvent('domready', this._guessLocalPath.bind(this));

		window.addEvent('domready', this._initContainer.bind(this));
	},

	/**
	 * initializes all container
	 * @access private
	 * @return {void}
	 */
	_initContainer: function() {
		if ( container = $$(this.options.container) ) {
			container.each(this.beautifyContainer.bind(this));
		}; // endif
	},

	/**
	 * beautifies a container
	 * @access public
	 * @param	{element} the container
	 * @return {void}
	 */
	beautifyContainer: function(container) {
		var container = $(container);

		if ( this._checkContainer(container) ) {
			container.addClass('beautifulScrollbar');
			
			this._shortenContainerContent(container);
		}; // endif
	},

	/**
	 * checks if an element should be beautifies
	 * @access private
	 * @param	{element} the container
	 * @return {boolean}
	 */
	_checkContainer: function(container) {
		var containerDim = this._getContainerDim($(container));
		return ( containerDim.height < containerDim.scrollHeight );
	},

	/**
	 * returns container dimensions
	 * @access private
	 * @param	{element} the container
	 * @return {boolean}
	 */
	_getContainerDim: function(container) {
		var container          = $(container);
		var containerDim       = container.getSize();
		var containerScrollDim = container.getScrollSize();

		return {'height': containerDim.y, 'scrollHeight': containerScrollDim.y};
	},

	/**
	 * shortens a container content
	 * @access private
	 * @param	{element} the container
	 * @return {boolean}
	 */
	_shortenContainerContent: function(container) {
		var containerDim    = this._getContainerDim($(container));
		var containerOffset = 25;

		if ( !$defined(container.retrieve('orig_content')) ) {
			container.store('orig_content', container.get('html').trim());
		}; // endif

		this._AJAXgetContentParts(container, (containerDim.scrollHeight/(containerDim.height-containerOffset)));
	},

	/**
	 * shortens a container content by AJAX
	 * @access private
	 * @param	{element} the container
	 * @param	{float} shorting_ratio
	 * @return {boolean}
	 */
	_AJAXgetContentParts: function(container, rate) {
		new Request.JSON({
			url: this.options.localPath + "/" + this.options.shortenScript,
			method: 'post',
			onSuccess: function(responseJSON, responseText) {
				if ( responseJSON ) {
					container.store('parted_content', responseJSON.content);
					this._AJAXshowContentPart(container, 0);
				}; // endif
			}.bind(this)
		}).post({
			'content': container.retrieve('orig_content'),
			'rate': rate.toFloat()
		});
	},

	/**
	 * shows specific part of content
	 * @access private
	 * @param	{element} the container
	 * @param	{int} part index
	 * @return {boolean}
	 */
	_AJAXshowContentPart: function(container, part) {
		var containerContent = container.retrieve('parted_content');

		if ( $type(part) ) {
			if ( "+1" === part )
				part = container.retrieve('current_part')+1
			else if ( "-1" === part )
				part = container.retrieve('current_part')-1;
		}; // endif

		// container.set('html', JSON.decode('"'+containerContent[part]+'"'));
		container.set('html', containerContent[part].replace(/"\"/, ''));
		container.store('current_part', part);

		this._buildLinks(container);
	},

	/**
	 * builds links for navigation
	 * @access private
	 * @param	{element} the container
	 * @return {boolean}
	 */
	_buildLinks: function(container) {
		var currentPart = container.retrieve('current_part');
		var totalParts  = container.retrieve('parted_content').length;

		container.getElements('a.more_link').dispose();

		if ( currentPart < ( totalParts -1 ) ) {
			var more_link = new Element('a', { 'class': "more_link", 'html': " &raquo;", 'title': "weiter",
				'events': { 'click': this._AJAXshowContentPart.bind(this, [container, "+1"]) }
			}).inject(container);
		}; // endif

		if ( 0 < currentPart ) {
			var less_link = new Element('a', { 'class': "more_link", 'html': "&laquo; ", 'title': "zurück",
				'events': { 'click': this._AJAXshowContentPart.bind(this, [container, "-1"]) }
			}).inject(container, 'top');
		}; // endif
	},


	/**
	 * guess local path to script
	 * @access private
	 * @return {string|boolean}
	 */
	_guessLocalPath: function() {
		var scriptAssets = $$('head script');

		scriptAssets.each(function(scriptAsset, i) {
			if ( ( src = scriptAsset.get('src') ) && ! scriptAsset.get('src').match(new RegExp("^http")) && ! this.options.localPath ) {
				this.options.localPath = src.substr(0, src.lastIndexOf('/'));
			}; // endif
		}.bind(this)); // while

		return this.options.localPath;
	},


	/**
	 * initialize DebugLog
	 * @access private
	 * @return {void}
	 */
	_initDebug: function() {
		var debugLog = new Element('div', {
			'id': "BS_debugLog",
			'styles': {
				'background-color': "#fff",
				'border': "1px solid red",
				'color': "red",
				'font-size': ".8em",
				'margin': 5,
				'padding': 5,
				'position': "absolute",
				'top': 0,
				'width': 940,
				'z-index': 1000
			}
		}).inject($(document.body));
	},

	/**
	 * adds text to log
	 * @access public
	 * @return {void}
	 */
	debugEntry: function(logentry) {
		if ( this.options.debug && ( log = $('BS_debugLog') ) ) {
			log.innerHTML += (logentry + ';\n');
		}; // endif
	}
	
});