var class_panelScroller = Class.create ({

	selfObjectName: null,

	panelBlockElement: null,
	slidingPanelsGroupElement: null,
	panelElements: null,

	currentCount: null,
	paused: true,
	mouseOver: false,
	scrollTimeout: null,

	autoScrollPauseMS: 5000,
	scrollDurationMS: 500,
	regularTraverseDistance: 1,


	// constructor
	initialize: function (selfObjectName, panelBlockId) {

		this.selfObjectName = selfObjectName;
		this.uniqueId = Math.round ((Math.random () * 10000000000) + 1);

		this.panelBlockElement = $(panelBlockId);
		this.panelBlockElement.setStyle ({overflow: "hidden", position: "relative"});

		eval ("var temp = function () { " + this.selfObjectName + ".mouse_over ();};");
		this.panelBlockElement.observe ("mouseover", temp);
		eval ("var temp = function () { " + this.selfObjectName + ".mouse_out ();};");
		this.panelBlockElement.observe ("mouseout", temp);

		this.slidingPanelsGroupElement = this.panelBlockElement.find_child_elements (".slidingPanelsGroup").pop ();
//		this.slidingPanelsGroupElement.setStyle ({position: "relative"});

		this.panelElements = this.panelBlockElement.find_child_elements (".slidingPanel");

		this.currentCount = 0;

		return this;
	},

	// set some scrolling attributes
	set_auto_scroll_pause_ms: function (autoScrollPauseMS) {
		this.autoScrollPauseMS = autoScrollPauseMS;
		return this;
	},
	set_scroll_duration_ms: function (scrollDurationMS) {
		this.scrollDurationMS = scrollDurationMS;
		return this;
	},
	set_traverse_distance: function (regularTraverseDistance) {
		this.regularTraverseDistance = regularTraverseDistance;
		return this;
	},






	// register elements to control the flow of the panel scroller
	register_nav_jump: function (navElement, count) {
		if ($(navElement)) {
			eval ("var temp = function (event) { event.stop (); " + this.selfObjectName + ".scroll_to (" + count + ", true); };");
			$(navElement).observe ("click", temp);
		}
		return this;
	},
	register_nav_next: function (navElement) {
		if ($(navElement)) {
			eval ("var temp = function (event) { event.stop (); " + this.selfObjectName + ".scroll_next (true); };");
			$(navElement).observe ("click", temp);
		}
		return this;
	},
	register_nav_prev: function (navElement) {
		if ($(navElement)) {
			eval ("var temp = function (event) { event.stop (); " + this.selfObjectName + ".scroll_prev (true); };");
			$(navElement).observe ("click", temp);
		}
		return this;
	},
	register_pause: function (navElement) {
		if ($(navElement)) {
			eval ("var temp = function (event) { event.stop (); " + this.selfObjectName + ".pause (); };");
			$(navElement).observe ("click", temp);
		}
		return this;
	},




	// register that the mouse is currently over the scroller (so it can pause)
	mouse_over: function () {
		clearTimeout (this.scrollTimeout);
		this.mouseOver = true;
		return true;
	},

	// register that the mouse is currently over the scroller (so it can pause)
	mouse_out: function () {
		this.mouseOver = false;
		if (!this.paused)
			this.start ();
		return true;
	},





	// start the scroller off
	start: function () {
		this.scrollTimeout = setTimeout (this.selfObjectName + ".scroll ();", this.autoScrollPauseMS);
		this.paused = false;
		return this;
	},



	// scroll the panels one iteration (or to a relative panel)
	scroll: function (count, pauseOverride) {

		clearTimeout (this.scrollTimeout);

		if (count === undefined)
			count = this.regularTraverseDistance;

		if (!this.mouseOver) {
//alert ('abc');
			if ((!this.paused) || (pauseOverride === true)) {
//alert ('def');
				this._scroll_relative (count);
//alert ('ghi');
				if (!this.paused)
					this.scrollTimeout = setTimeout (this.selfObjectName + ".scroll ();", this.autoScrollPauseMS);
			}
		}
		return this;
	},

	// scroll to a specific panel
	scroll_to: function (count, pauseOverride) {

		clearTimeout (this.scrollTimeout);

		if (!this.mouseOver) {
			if ((!this.paused) || (pauseOverride === true)) {

				this._scroll_absolute (count);

				if (!this.paused)
					this.scrollTimeout = setTimeout (this.selfObjectName + ".scroll ();", this.autoScrollPauseMS);
			}
		}
		return this;
	},

	// scroll forward one iteration
	scroll_next: function (pauseOverride) {
		return this.scroll (this.regularTraverseDistance, pauseOverride);
	},

	// scroll back one iteration
	scroll_prev: function (pauseOverride) {
		return this.scroll (-this.regularTraverseDistance, pauseOverride);
	},


	// pause/unpause the scroller
	pause: function () {
		if (this.paused == true) {
			this.paused = false;
			this.start ();
		}
		else {
			this.paused = true;
			clearTimeout (this.scrollTimeout);
		}
		return this;
	},




	// scroll the panels based on a relative number of positions
	_scroll_relative: function (distance) {

		// work out which panel to scroll to
		this.currentCount += distance;

		// make sure the panel count is within the correct limit
		if(this.currentCount >= this.panelElements.length)
			this.currentCount = 0;
		else if (this.currentCount < 0) {
			if (this.currentCount > - Math.abs (distance))
				this.currentCount = 0;
			else
				this.currentCount = this.panelElements.length - Math.abs (distance);
		}

		this._scroll_absolute (this.currentCount);
		return true;
	},

	// scroll the panels based on an absolute number of positions
	_scroll_absolute: function (count) {

		if (this.panelElements.length > 1) {

			this.currentCount = count;

			// make sure the panel count is within the correct limit
			if (this.currentCount < 0)
				this.currentCount = this.panelElements.length - 1;
			if (this.currentCount >= this.panelElements.length)
				this.currentCount = 0;

			var startPos = this.panelBlockElement.cumulativeOffset ();
			var endPos = this.panelElements[this.currentCount].cumulativeOffset ();

//			Effect.Queues.get (this.slidingPanelsGroupElement).each (function (e) { e.cancel (); });	// cancel any existing sliding effects
			new Effect.Move (this.slidingPanelsGroupElement, { x: startPos.left - endPos.left, y: startPos.top - endPos.top, mode: "relative", duration: this.scrollDurationMS / 1000 });

//			jQuery (this.slidingPanelsGroupElement).animate ({left: (- endPos.left), top: (startPos.top - endPos.top)}, 500);
		}
		else
			this.currentCount = 0;
		return true;
	}

});
