/*
 * Image Grid
 * ==========
 *
 * Aranges images in a grid.  Images can be sorted either by column or row.
 * The number of columns and rows in the grid and the dimensions of the cells
 * can be set before drawing.
 */
using('ak.Image');
using('evance.net.Request');
using('evance.net.RequestData');
using('evance.utils.XMLFactory');

if(!$defined(ak)){var ak = {}};

ak.ImageGrid = evance.core.UIObject.extend({
	_className: 'ImageGrid',
	_classOwner: 'ak.ImageGrid',
    _request: null,
    _requestData: null,
	_focused: false,
    galleryId: null,
    rows: 2,
    cols: 4,
    loadOrder: 'rows',  // rows | cols
    cellWidth: 100,
    cellHeight: 100,
    proxy: null,
    _totalPages: null,
    currentPage: 1,
	currentImage: 0,
    _fileNames: null,    // XXX TODO: These should probably be changed
    _fileIds: null,      // to _thumbNames and _bannerNames instead to
    images: new Array(), // fit in with Slideshow.
    scroll: null,
    _targets: new Array(),
	_imageDir: '/images/',

	initialize: function(){
		this.parent(arguments[0]);
        this._request = new evance.net.Request();
        this._request.method = 'POST';
        this._request.setMimeType = 'text/xml';
        this._request.setResponseFormat('xml');
        this._request.format = 'xml';
        this._request.addListener(this);
        this._requestData = new evance.net.RequestData();
        this._requestData.setAutoClear(true);
    },

    sync: function(){
        this._requestData.addItem('action', 'thumbs');
        if(this.galleryId > 0) this._requestData.addItem('galleryId', this.galleryId);
        else evance.warn(this._className + '.galleryId is not defined');
        if(this.proxy)
            this._request.post(this.proxy, this._requestData.serialise());
        else
            evance.warn(this.id + ' cannot make ajax request. ImageGrid.proxy not defined');
    },

    onHttpRequestResponse: function(e){
        if(this._getFileNames(e.response)){
            this.draw();
            this.dispatchEvent('onHttpRequestResponse', e);
        } else {
            e.invalidResponse = true;
            this.dispatchEvent('onHttpRequestError', e);
        }
    },

    addTarget: function(t){
        this._targets.push(t);
    },

    _getFileNames: function(xml){
        for(var a=0; a<xml.childNodes.length; a++){
            if(xml.childNodes[a].nodeType == 1){
                if(xml.childNodes[a].nodeName == 'document'){
                    x = xml.childNodes[a];
                    var names = new Array();
                    var ids = new Array();
                    for(var i=0; i<x.childNodes.length; i++){
                        element = x.childNodes[i];
                        if(element.nodeType == 1 && element.nodeName == 'thumb'){
                            names.push(element.firstChild.nodeValue);
                            if(element.attributes[0].name == 'id')
                                ids.push(element.attributes[0].value);
                        }
                    }
                    this._fileNames = names;
                    this._fileIds = ids;
                    this._totalPages = Math.ceil(this._fileNames.length / (this.rows * this.cols));
                    return true;
                }
            }
        }
        return false;
    },
	
	cursorInCol: function(imageId){
		var cells = this.rows * this.cols;
		var page = Math.ceil((imageId + 1)/ cells);
		var relCol = Math.ceil(imageId % this.cols);
		var offset = (page - 1) * this.cols;
		var absCol = offset + relCol;
		return absCol;
	},

	scrollToPage: function(imageId){
		/* The page should only scroll on the following conditions:
		 *   1. the visible page is the same as the page the selected image is on and
		 *   2. the ImageGrid is not focused (i.e. the mouse isn't over the ImgGrid)
		 */
		if(!this._focused){
			var cells = this.rows * this.cols;
			var pageAfterChange = Math.ceil((imageId + 1)/ cells);
			var currentPage = Math.ceil((this.currentImage) / cells);
			if(pageAfterChange == this.currentPage) return;
			if(currentPage != this.currentPage) return;
			this.scroll.stop();
			var scrollPoint = (pageAfterChange - 1) * this.cols * this.cellWidth;
			this.scroll.scrollTo(scrollPoint, 0);
			this.currentPage = pageAfterChange;
			this.setPagers();
		}
	},

    nextPage: function(){
        if(this.currentPage < this._totalPages){
            this.scroll.stop();
            this.scroll.scrollTo(this.currentPage * this.cols * this.cellWidth, 0);
            this.currentPage++;
			this.setPagers();
        }
    },

    prevPage: function(){
        if(this.currentPage > 1){
            this.scroll.stop();
            this.currentPage--;
            this.scroll.scrollTo((this.currentPage-1) * this.cols * this.cellWidth, 0);
			this.setPagers();
        }
    },

	setPagers: function(){
		if(this.currentPage < this._totalPages){
			$(this.id + '_Next').style.backgroundPosition = "0 42px";
			$(this.id + '_Next').style.cursor = "pointer";
		} else {
			$(this.id + '_Next').style.backgroundPosition = "0 0";
			$(this.id + '_Next').style.cursor = "default";
		}
        if(this.currentPage > 1){
			$(this.id + '_Prev').style.backgroundPosition = "0 -42px";
			$(this.id + '_Prev').style.cursor = "pointer";
		} else {
			$(this.id + '_Prev').style.backgroundPosition = "0 0";
			$(this.id + '_Prev').style.cursor = "default";
		}
    },

    onImageClick: function(e){
		this.currentImage = e.imageId;
        this.animateCursor(e, 500);
    },

    onImageChange: function(e){
		//this.currentImage = e.imageId;
        this.animateCursor(e, 2000);
		var cells = this.rows * this.cols;
		if(e.imageId % cells == 0){
			this.scrollToPage(e.imageId);
		}
    },

    animateCursor: function(e, dur){
        var imageId = 'ImageGrid_1_Row_Img_' + e.imageId;
        var img = $(this.id + '_Current');
        var self = this;
        var fx = img.effect("opacity", {
            duration: dur,
            onComplete: function(){
                var imgCol = e.imageId % 4;
				img.style.left = (self.cellWidth * self.cursorInCol(e.imageId)) + "px";
				img.style.top = $(imageId).offsetTop + "px";
                fx = img.effect("opacity", {duration: dur});
		        fx.start(0,0.7);
            }
        });
		fx.start(0.7,0);
    },

    draw: function(){
		if(this.isPageLoaded) {
			if(this.parentId) {
                this.parentElement = $(this.parentId);
                this.parentElement.innerHTML = '';
				this.parent();
                this.element.innerHTML = '';
                this.parentElement.appendChild(this.element);
                this.element.style.backgroundColor = 'white';
                this.element.style.position = "relative";
				var ref = this;
				var timeout;
				this.element.addEvent('mouseenter', function(){
						ref._focused = true;
						$clear(timeout);
				});
				this.element.addEvent('mouseleave', function(){
					timeout = setTimeout(function(){
						ref._focused = false
					},
					1000);
				});

                var prevPage = document.createElement('div');
                this.element.appendChild(prevPage);
                prevPage.id = this.id + '_Prev';
                prevPage.style.position = 'absolute';
                prevPage.style.marginLeft = '0px';
                prevPage.style.marginTop = '80px';
                prevPage.style.width = '33px';
                prevPage.style.height = '42px';
                prevPage.style.cursor = 'pointer';
                prevPage.style.backgroundImage = "url("+this._imageDir+"imagegrid_prev.png)";
                prevPage.style.backgroundRepeat = "no-repeat";
                var ref = this;
                prevPage.onclick = function(){ ref.prevPage() };
                this.images = new Array();

                var nextPage = document.createElement('div');
                this.element.appendChild(nextPage);
                nextPage.id = this.id + '_Next';
                nextPage.style.position = 'absolute';
                nextPage.style.marginLeft = '368px';
                nextPage.style.marginTop = '80px';
                nextPage.style.width = '32px';
                nextPage.style.height = '42px';
                nextPage.style.cursor = 'pointer';
                nextPage.style.backgroundImage = "url("+this._imageDir+"imagegrid_next.png)";
                var ref = this;
                nextPage.onclick = function(){ ref.nextPage() };

                var currentImg = document.createElement('div');
                currentImg.id = this.id + '_Current';
                currentImg.style.position = 'absolute';
                currentImg.style.left = '0px';
                currentImg.style.top = '0px';
                currentImg.style.width = this.cellWidth + 'px';
                currentImg.style.height = this.cellHeight + 'px';
                currentImg.style.cursor = 'pointer';
                currentImg.style.backgroundImage = "url("+this._imageDir+"imagegrid_border.gif)";
                currentImg.style.opacity = 0.7;
                currentImg.style.backgroundColor = 'transparent';
                currentImg.style.backgroundRepeat = "no-repeat";
                currentImg.style.backgroundPosition = "center";

                // Load images.

                this.element.className = 'imageGridContainer';
                this.element.style.height = this.cellHeight * this.rows + "px";
                this.element.style.width = this.cellWidth * this.cols + "px";
                this.element.style.height = this.cellHeight * this.rows + "px";
                this.element.style.overflow = 'hidden';
                var grid = document.createElement('div');
                grid.id = this.id + '_Grid';
                grid.className = 'imageGrid';
                grid.style.height = this.cellHeight * this.rows + "px";
                grid.style.width = this.cellWidth * this.cols * this._totalPages + "px";
                var gridHolder = document.createElement('div');
                gridHolder.id = this.id + '_GridContaner';
                gridHolder.className = 'imageGridContainer';
                gridHolder.style.overflow = 'hidden';    // Required for fx to work.
                gridHolder.style.width = this.cellWidth * this.cols + "px";
                //gridHolder.style.height = this.cellHeight * this.rows + "px";

                gridHolder.appendChild(grid);
                gridHolder.appendChild(currentImg);
                this.element.appendChild(gridHolder);
                if(this.loadOrder == 'cols'){
                    // [0][2] [4][6]     <-- ex. of 2x2 grid ordered by col.
                    // [1][3] [5][7]
                    var pagelen = this.rows * this.cols;
                    var page, col;
                    for(var i=p=c=inext=0; i<this._fileNames.length; i++){
                        // i == global counter;
                        // p == page number
                        // c = column number;
                        // inext == value of i at start of next page.
                        if(i == inext){
                            inext = inext + pagelen;
                            p++;
                            var page = document.createElement('div');
                            grid.appendChild(page);
                        }
                        if(i == c){
                            c = c + this.rows;
                            col = document.createElement('div');
                            col.setAttribute('style', 'float:left');
                            page.appendChild(col);
                        }
                        page.id = this.id + "_Page_" + p;
						page.appendChild(currentImg);
                        // TODO: Change to Image object.
                        var cell = document.createElement('div');
                        cell.innerHTML = this._fileNames[i];
                        cell.style.width = this.cellWidth;
                        cell.style.height = this.cellHeight;
                        col.appendChild(cell);
                    }
                } else {
                    // [0][1] [4][5]     <-- ex. of 2x2 grid ordered by row.
                    // [2][3] [6][7]
                    // First page must be initialised outide of loop.
                    var page = document.createElement('div');
                    page.id = this.id + "_Page_" + 1;
                    grid.appendChild(page);
					grid.appendChild(currentImg);
                    // Now begin for loop.
                    for(var i=0, p=1, inext = this.rows * this.cols;
                            i<this._fileNames.length; i++){
                        var cell = new ak.Image();
                        cell.id = this.id + "_Row" + "_Img_" + i;
                        cell.imageId = i;
                        cell.parentId = page.id;
                        cell.src = this._fileNames[i];
                        cell.cssFloat = 'left';
                        cell.width = this.cellWidth;
                        cell.height = this.cellHeight;
                        cell.load();
                        cell.draw();
                        cell.element.className = 'imageGridCell';
                        cell.addListener(this);
                        page.appendChild(cell.element);
                        this.images[i] = cell;
                        this._targets.each(function(x){
                            cell.addListener(x);
                        });
                        if(i == (inext * p) - 1){
                            // We have filled the last cell of the last row.
                            // Time to move to next page.
                            //page.style.position = 'absolute';
                            //page.style.marginLeft = this.cellWidth * this.cols * p;
                            page.setAttribute('style', 'float:left');
                            page.style.cssFloat = 'left';
                            page.style.styleFloat = 'left';
                            page.style.width = this.cellWidth * this.cols + "px";
                            page.style.height = this.cellHeight * this.rows + "px";
                            p++;
                            if(p <= this._totalPages){
                                page = document.createElement('div');
                                page.id = this.id + "_Page_" + p;
                                grid.appendChild(page);
                            }
                        }
                    }
					this.setPagers();
                    if(i < this.cols * this.rows * this._totalPages) grid.appendChild(page);
                }
				this.load();

                this.scroll = new Fx.Scroll(gridHolder.id, {
                    wait: false,
                    duration: 650,
                    transition: Fx.Transitions.Quad.easeInOut
                });

                // set prev and next page zindex
                prevPage.style.zIndex = ++evance.core.Interface.depth;
                nextPage.style.zIndex = ++evance.core.Interface.depth;
				return true;
            }
        }
        return false;
    }
});


window.addEvent("load", function() {
	// Set up handlers for "Select style" popup.
	var selectPopup = $("SelectStyle");
	var close = selectPopup && $E("a", selectPopup);		
	if (close) {
		close.addEvent("click", function(e) {
			var e = new Event(e);
			e.preventDefault();
			selectPopup.style.display = "none";
			
			// Set a cookie so it stays closed across page load.
			document.cookie='selectStyleOpen=false';
			
			return false;
		});
	}
});
