//
// Copyright 2007-2008 Will Barton <will@water-powered.com>
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 
//   1. Redistributions of source code must retain the above copyright
//      notice, this list of conditions and the following disclaimer.
//   2. Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//   3. The name of the author may not be used to endorse or promote products
//      derived from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
// THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// 

var PhotoPane = {
	init: function(options) {

		this.options = $extend({ 
			thumbsPerPage:  6
		}, options || {});

		// Get the anchor links of thumbnail images
		this.anchors = [];
		$each($$('a'), function (el) {
			if (el.rel && el.rel.test(/^photopane/i)) {
				el.addEvent('click', function(e) {
						e = new Event(e).stop();
						this.sendRequest(el, e); 
					}.bind(this));
				this.anchors.push(el);
			}
		}, this);
		this.currentAnchor = null;

		// Paginate thumbnails
		this.paginateThumbs();

        // Check to see if a hash was given, if so, we want to go ahead and
        // open that photo 
        if (location.hash != '') {
            this.anchors.each(function(el) {
                if (el.href.contains(location.hash.split('#')[1])) {
					this.changePage(parseInt(el.parentNode.id));
                    this.sendRequest(el);
                }
            }, this);
        } else {
			// Load the default, the first anchor
			this.sendRequest(this.anchors[0]);
		}

	},

	paginateThumbs: function() {

		var i = 0;
		// Get the totally number of pages for the given anchors
		var numThumbPages = this.anchors.length / this.options.thumbsPerPage;

		// We don't need to do any pagination if there won't be multiple pages
		if (numThumbPages <= 1.0) {
			return;
		}

		// Construct a new block of paginated thumbs
		thumbPages = new Element('div', {'id': 'pages'})
		thumbPages.injectInside($('thumbs'));

		// Create a list of thumb pages, and create them, moving the anchors 
		// into the appropriate pages.
		this.pages = [];
		this.currentPage = 0;
		for (i = 0; i < numThumbPages; i++) {
			page = new Element('div', {'id': i})
			page.injectInside(thumbPages);
			page.style.display = 'none';
			page.addClass('page');
			
			// Split the anchors up into pages
			$each(this.anchors.slice(i * this.options.thumbsPerPage,
									 this.options.thumbsPerPage + 
									 this.options.thumbsPerPage * i),
				function(el) { el.injectInside(page); });

			// Add the page to our list
			this.pages.push(page);

		}

		// Add the previous and next page links
		this.firstPage = new Element('a', {'href':'#', 'id':'firstPage'}
			).injectInside(thumbPages);
		new Element('span').injectInside(this.firstPage).setHTML('First');

		this.prevPage = new Element('a',
				{'href':'#', 'id':'prevPage'}
			).injectInside(thumbPages);
		new Element('span').injectInside(this.prevPage).setHTML('Previous');

		this.lastPage = new Element('a', {'href':'#', 'id':'lastPage'}
			).injectInside(thumbPages);
		new Element('span').injectInside(this.lastPage).setHTML('Last');

		this.nextPage = new Element('a',
				{'href':'#', 'id':'nextPage'}
			).injectInside(thumbPages);
		new Element('span').injectInside(this.nextPage).setHTML('Next');

		// Set up prev/next events
		this.firstPage.addEvent('click', function(e) {
			e = new Event(e).stop();
			if (this.currentPage > 0) 
				this.changePage(0);
		}.bind(this));

		this.prevPage.addEvent('click', function(e) {
			e = new Event(e).stop();
			if (this.currentPage > 0) 
				this.changePage(this.currentPage - 1);
		}.bind(this));

		this.nextPage.addEvent('click', function(e) {
			e = new Event(e).stop();
			if (this.currentPage < this.pages.length)
				this.changePage(this.currentPage + 1);
		}.bind(this));

		this.lastPage.addEvent('click', function(e) {
			e = new Event(e).stop();
			if (this.currentPage < this.pages.length)
				this.changePage(this.pages.length - 1);
		}.bind(this));

		// Display the current page, or page 1
		// this.pages[0].style.display = 'block';
		this.changePage(0);

	},

	changePage: function(pageNum) {

		if (this.pages == null) { return; }
		
		// Change the page displayed
		this.pages[this.currentPage].style.display = 'none';
		this.pages[pageNum].style.display = 'block';
		this.currentPage = pageNum;

		// Adjust the prev/next buttons as needed
		if ((this.currentPage - 1) < 0) {
			this.prevPage.style.display = 'none';
			this.firstPage.style.display = 'none';
		} else {
			this.prevPage.style.display = 'block';
			this.firstPage.style.display = 'block';
		}

		if ((this.currentPage + 1) >= this.pages.length) { 
			this.nextPage.style.display = 'none';
			this.lastPage.style.display = 'none';
		} else {
			this.nextPage.style.display = 'block';
			this.lastPage.style.display = 'block';
		}

	},

	sendRequest: function(el) {
		// Send AJAX Request
		new Request.HTML({
				url: el.href, 
				method: 'get', 
				onSuccess: this.onRequestSuccess.bind(this)
		}).send();
		
		// Add loading image

		// Make the given element (anchor) 'active'
		if (this.currentAnchor) {
			this.currentAnchor.removeClass('active');
		}
		this.currentAnchor = el;
		this.currentAnchor.addClass('active');

		// Change pages if necessary
		if (parseInt(this.anchors.indexOf(el) / this.options.thumbsPerPage) 
				!= this.currentPage) {
			this.changePage(parseInt(this.anchors.indexOf(el) / 
					this.options.thumbsPerPage));
		}

	},

	onRequestSuccess: function(tree, elements, html) {
		// XXX: Use a single fade
		var fadeOut = new Fx.Tween('pane', 'opacity', {
						duration: 250,
						transition: Fx.Transitions.linear
					});
		var fadeIn = new Fx.Tween('pane', 'opacity', {
						duration: 250,
						transition: Fx.Transitions.linear
					});

		var hash = "";

		// When the fade finishes, fill in the HTML, then fade back in
		fadeOut.addEvent('onComplete', function() {
				// Set the HTML
				$('pane').innerHTML = tree[4].innerHTML;

				// Adjust the link to element
				var hash = '#' + $('linkTo').href.split('/').pop();
				$('linkTo').href = hash;
				location.hash = hash;
				
				// Arrange Prev/Next links for the image
				var index = this.anchors.indexOf(this.currentAnchor);
				var width = $('pane').getFirst().getFirst().width;
				var height = $('pane').getFirst().getFirst().height;
				$('pane').getFirst().style.width = width + 40 + 'px';
				$('pane').getFirst().style.height = height + 40 + 'px';
				if ((index - 1) >= 0) {
					var prevImage = new Element('a', {'href':'#',
						'style':'position: relative; left: +20px; top: -' 
								+ (height+20) + 'px; width: '+ width/2 
								+ 'px; height: ' + height + 'px;',
						'id':'prevImage'}).injectInside($('pane').getFirst());
					prevImage.cloneEvents(this.anchors[index - 1]);
					new Element('span').injectInside(prevImage).setHTML('Previous Photo');
				}
				if ((index + 1) < this.anchors.length) {
					var nextImage = new Element('a', {'href':'#',
						'style':'position: relative; right: +18px; top: -' 
								+ (height+20) + 'px; width: '+ width/2 
								+ 'px; height: ' + height + 'px;',
						'id':'nextImage'}).injectInside($('pane').getFirst());
					nextImage.cloneEvents(this.anchors[index + 1]);
					new Element('span').injectInside(nextImage).setHTML('Next Photo');
				}
				// Fade in
				fadeIn.start(0,1);
			}.bind(this));

		// Fade out the current pane
		fadeOut.start(1,0);
	}


}

window.addEvent('domready', PhotoPane.init.bind(PhotoPane));

