/**
 * PhotoArea - Container for photo display (list/calendar/slideshow)
 * @extends Component
 *
 * {Photobox[]} photoBoxes
 * {HTMLObject} prevPhoto, nextPhoto
 * {int} photoIndex
 * {boolean} playing, forwards
 * {Timeout} ssTimeout
 */
var PhotoArea = Class.create(Component);

PhotoArea.prototype.init = function()
{
	if(this.ssMove)
		Event.observe(document, 'keyup', this.ssMove.bindAsEventListener(this), false);
	this.quickCatList = [];
	this.photoboxClass = Photobox;
	this.rowCount = 0;
}

/**
 * PhotoArea.update - update PhotoArea depending on view mode
 * @method
 * @param {XMLNode} xml - XML data
 */
PhotoArea.prototype.update = function(xml)
{
	switch(this.layout.viewMode)
	{
		case 'list':
			this.writePhotoList(xml);
			break;
		case 'calendar':
			this.writeCalendar(xml);
			break;
		case 'slideshow':
			this.writeSlideshow(xml);
			break;
	}
}

/**
 * PhotoArea.writePhotoList - write a photo list
 * @method
 * @param {XMLNode} xml - XML data
 * @param {HTMLObject} prefix - extra HTML Object to render at top of container
 */
PhotoArea.prototype.writePhotoList = function(xml, prefix)
{
	this.contents.removeChildren();
	this.contents.appendChild(new Pagespacer());
	if(prefix)
		this.contents.appendChild(prefix);

	var calendar = xml.getElementsByTagName('calendar')[0] ? true : false;

	var photoNode = xml.getElementsByTagName('photos')[0];
	if(photoNode)
	{
		var moreMonths = false;
		var lastMonthName = '';
		var lastDate = '';

		this.photoBoxes = {};

		var row = 0;
		var photos = photoNode.getElementsByTagName('photo');
		if(photos.length)
		{
			var photoLine = this.contents.appendChild(new Element('div'));
			photoLine.className = 'bar photo';
			photoLine.appendChild(new Lineclear());

			for(var i = 0, il = photos.length; i < il; i++)
			{
				var monthName = photos[i].getAttribute('month');
				var date = photos[i].getAttribute('date');

				if(!calendar && lastMonthName != monthName && (this.layout.sortBy == 'taken' || this.layout.sortBy == 'added'))
				{
					if(row > 0)
					{
						photoLine.appendChild(new Lineclear());
						photoLine = this.contents.appendChild(new Element('div'));
						photoLine.className = 'bar photo';
						photoLine.appendChild(new Lineclear());
					}

					var monthBar = this.contents.insertBefore(new Element('div'), photoLine);
					monthBar.className = 'bar month' + (moreMonths ? ' second' : '');
					monthBar.innerHTML = monthName;

					row = 0;
					moreMonths = true;
				}
				else if(row == 0)
				{
					photoLine.appendChild(new Lineclear());
					photoLine = this.contents.appendChild(new Element('div'));
					photoLine.className = 'bar photo';
					photoLine.appendChild(new Lineclear());
				}
				var showDate = (!calendar && lastDate != date && (this.layout.sortBy == 'taken' || this.layout.sortBy == 'added'));
				var p = new this.photoboxClass(photoLine.appendChild(new Element('div')));
				p.photoarea = this;
				p.init(this.layout, photos[i], showDate);
				this.photoBoxes[p.hash] = p;
				lastMonthName = monthName;
				lastDate = date;

				row++;
				if(this.rowCount) row %= this.rowCount;

				if(row == 0)
					photoLine.appendChild(new Lineclear());
			}
			if(row > 0)
				photoLine.appendChild(new Lineclear());
		}
	}
	this.contents.appendChild(new Pagespacer());

	var usedCategories = xml.getElementsByTagName('usedcategories')[0];
	var relatedCategories = xml.getElementsByTagName('relatedcategories')[0];
	if(usedCategories || relatedCategories)
	{
		this.quickCatList = [];

		var usedCats = usedCategories.getElementsByTagName('category');
		for(var i = 0, il = usedCats.length; i < il; i++)
			this.quickCatList.push(usedCats[i]);

		var relatedCats = relatedCategories.getElementsByTagName('category');
		for(var i = 0, il = relatedCats.length; i < il; i++)
			this.quickCatList.push(relatedCats[i]);
	}
}

/**
 * PageList - a page list component
 * @extends Component
 *
 * {boolean} options.inverted - flag to move summary below list
 */
var PageList = Class.create(Component);

PageList.prototype.update = function(xml)
{
	switch(this.layout.viewMode)
	{
		case 'list':
			this.writePageList(xml);
			break;
		case 'calendar':
			this.writeDateList(xml);
	}
}

/**
 * PageList.writePageList - write list of page numbers
 * @method
 * @param {XMLNode} xml - XML data
 */
PageList.prototype.writePageList = function(xml)
{
	this.contents.removeChildren();

	var photoNode = xml.getElementsByTagName('photos')[0];
	if(!photoNode)
		photoNode = xml.getElementsByTagName('accounts')[0];
	var results = parseInt(photoNode.getAttribute('results'));
	var photosPerPage = parseInt(photoNode.getAttribute('perpage'));
	var page = parseInt(photoNode.getAttribute('page'));

	if(results == 0)
	{
		if(!this.inverted)
		{
			var pageList = this.contents.appendChild(new Element('div'));
			pageList.className = 'pages';
			pageList.appendChild($T('\u00a0'));
			this.contents.appendChild($T(language('nophotos')));
			this.contents.appendChild(pageList);
		}
		return;
	}

	var section;
	if(page != -1)
	{
		section = ((photosPerPage*(page-1))+1) + '-' + ((photosPerPage * page) < results ? (photosPerPage * page) : results);
	}
	else
	{
		section = '1-' + Math.min(settings.photos_per_page_limit, results);
	}

	var pageResults = language('photos') + ' ' + section + ' ' + language('outof') + ' ' + results;

	if(page > Math.ceil(results / photosPerPage))
		page = 1; //If page is beyond current number of pages (i.e. view has been shrunk) reset page to 1

	if(!this.inverted)
		this.contents.appendChild($T(pageResults));

	var pageList = this.contents.appendChild(new Element('div'));
	pageList.className = 'pages';
	pageList.appendChild($T(language('page') + ': '));
	var firstPage = Math.max(page - ((settings.pages - 1) / 2), 1);
	var endPage = Math.ceil(results / photosPerPage);
	var lastPage = Math.min(firstPage + settings.pages - 1, endPage);

	if(page > 1)
		pageList.appendChild(new PageButton(this, page - 1 , language('previous')));

	if(firstPage > 1)
	{
		pageList.appendChild(new PageButton(this, 1));
		if(firstPage != 2)
			pageList.appendChild($T(' … '));
	}

	for(var i = firstPage; i <= lastPage; i++)
	{
		if(page != i)
		{
			pageList.appendChild(new PageButton(this, i));
		}
		else
		{
			var button = new Span(i);
			button.className = 'page_current';
			pageList.appendChild(button);

		}
	}
	if(lastPage < endPage)
	{
		if(lastPage != endPage - 1)
			pageList.appendChild($T(' … '));
		pageList.appendChild(new PageButton(this, endPage));
	}

	if(results > photosPerPage)
	{
		if(page == -1)
		{
			var button = new Span(language('all'));
			button.className = 'page_current';
			pageList.appendChild(button);
		}
		else
		{
			pageList.appendChild(new PageButton(this, -1, language('all')));
		}
	}
	if(page < endPage && page != -1)
		pageList.appendChild(new PageButton(this, page + 1 , language('next')));

	if(this.inverted)
		this.contents.appendChild($T(pageResults));
	this.layout.page = page;
}

/**
 * PageButton - page list button
 * @constructor
 * @param {PageList} pageList - containing PageList object
 * @param {int} page - page number
 * @param {String} text - page label
 */
function PageButton(pageList, page, text)
{
	var button = new TextButton(function() { pageList.layout.loadData({mode: 'list', page: page}); return false; }, text ? text : page);
	button.page = page;
	return button
}
