/*
 *      -----------------------------------------------------
 *     |                                                     |
 *     |                                     <bluntchisel>   |
 *     |                                                     |
 *     |                                                     |
 *     |                                                     |
 *     |                                                     |
 *     |  content management system v3.0                     |
 *     |  copyright (c) 2007-2008                            |
 *     |                                                     |
 *     |                                                     |
 *      -----------------------------------------------------
 *      
 *      file        : GalleryModule.js
 *      description : photo gallery module for the bluntchisel CMS (v3), based
 *                    on the (e)2 photo gallery - see GalleryModule.php for
 *                    (e)2 photo gallery copyright notice
 */


/*
 * after a bit of deciphering, we discovered that the GalleryModule.imageGallery array items
 * each contain the following entries:
 *   [0] - full image source
 *   [1] - image width
 *   [2] - image height
 *   [7] - image caption
 *   [8] - first id (???)
 *   [9] - image file's name (custom added)
 */

var GalleryModule = new Class({
	'ajaxURL'        : '',
	'rootURL'        : '',
	'transitionSpeed': '300',
	'fadeSpeed'      : '300',
	'currentPos'     : 0,
	'currentThumbPos': 0,
	'moveAmount'     : 80,
	'thumbnailNum'   : '',
	'maxThumbnails'  : '4',
	'currentImageID' : '0',
	'moving'         : false,
	'finishedSizing' : false,
	'preloadImages'  : 'no',
	'firstImageStart': 1,
	'nextOrPrev'     : 0,
	'fadeOut'        : true,
	'thumbOpen'      : false,
	'imagePrefix'    : '',
	'imagesFolder'   : '',
	'thumbPrefix'    : '',
	'albumPath'      : '',
	'maxThumbWidth'  : '0',
	'thumbEditMode'  : false,
	
	/*
	 * Constructor.
	 * 
	 * @param _slot The slot in which the module exists.
	 * @param _page The page ID in which the module is being rendered.
	 * @param _varName The name of the variable of type GalleryModule.
	 * @param _albumPath The path to the current album.
	 * @param _imagePrefix The folder prefix to pre-pend to all image URLs.
	 * @param _thumbPrefix The folder prefix to pre-pend to all thumbnail URLs.
	 */
	initialize: function (_slot, _page, _varName, _albumPath, _imagePrefix, _thumbPrefix, _options)
	{
		// if additional parameters have been supplied
		if (_options) $extend(this, _options);
		
		// element initialisation
		this.slot = _slot;
		this.page = _page;
		this.varName = _varName;
		this.imagePrefix = _imagePrefix;
		this.thumbPrefix = _thumbPrefix;
		this.albumPath = _albumPath;
		
		// gallery initialisation
		this.loadedImage = new Array();
		this.loadedImage[0] = 1;
		this.imageGallery = new Array();
		this.tempGallery = new Array();
		
		// Checks the gallery path to see if it's in root mode. Not display the gallery.
		window.addEvent('domready', function ()
		{
			if (this.albumPath != "/" && this.albumPath != "") {
				if (this.tempGallery.length)
				{
					this.initGallery(this.tempGallery, this.tempGallery.length,
						this.tempGallery[0][8], this.tempGallery[0][1],
						this.tempGallery[0][2], 0);
				}
				// make sure we add the "upload image" button
				if (admin)
				{
					admin.addAddButton('addImageButton', '', 'Upload to Gallery',
						serverURL+'cms/css/GalleryModule/uploadGalleryLo.jpg',
						serverURL+'cms/css/GalleryModule/uploadGalleryHi.jpg',
						"admin.showFileUploader(false, 'galleryMode', '"+this.imagePrefix+this.albumPath+"/','"+this.albumPath+"');");
						
					admin.addEditButton();
					admin.addDeleteButton();
				}
			} else
			{
				if (admin) {
					admin.addAddButton('addAlbumButton', '', 'Add a new album to the gallery',
					serverURL+'cms/css/GalleryModule/addAlbumLo.jpg',
					serverURL+'cms/css/GalleryModule/addAlbumHi.jpg',
					this.varName + ".showAddAlbumDialog();");
					
					admin.addEditButton();
					admin.addDeleteButton();
				}
			}}.bind(this)
		);
	},
	
	showAddAlbumDialog: function (_mode, _albumPath)
	{
		// assume add mode
		if (!_mode || _mode == null)
			_mode = 'addMode';
		
		//ajax will pop up from here openAjaxWindow() in this window will be the add new album details.
		//
		function createAlbum (e) {
			e = new Event(e);
			e.stop();
			
			if(!loading)
			{
				// Send the AJAX request
				var ajaxRequest = new Request({url:serverURL+'ajax',
					method:'post',
					onComplete: function(data) {
						if(data == 'success')
						{
							window.location.reload();
						} else
						if (data == 'error')
							window.alert('Unable to perform operation. Please contact the system administrator.');
						else
						if (data == 'alreadyexists')
							window.alert('An album with a similar name already exists. Please try another name.');
						
						loading=false;}});
				
				if (_mode == 'addMode')
				{
					//send the data via an ajax request
					ajaxRequest.send({ data: {
						'cmd'         : 'createAlbum',
						'title'       : $('albumDialogTitleEdit').get('value'),
						'description' : $('albumDialogDescriptionEdit').get('value'),
						'page'        : this.page,
						'slot'        : this.slot,
						'module'      : "GalleryModule"
						}
					});
				} else if (_mode == 'editMode')
				{
					//send the data via an ajax request
					ajaxRequest.send({ data: {
						'cmd'         : 'editAlbum',
						'albumPath'   : _albumPath,
						'title'       : $('albumDialogTitleEdit').get('value'),
						'description' : $('albumDialogDescriptionEdit').get('value'),
						'page'        : this.page,
						'slot'        : this.slot,
						'module'      : "GalleryModule"
						}
					});
				}
			}
		}
		
		// create a ajax window to insert data for a new album to be created.
		var wndTitle = (_mode == 'addMode') ? 'Create new Album' : 'Edit Album Details';
		var htmlCode = "<div id=\"albumCreateHeader\" class=\"AlbumCreateHeader\">"+wndTitle+"</div><form id=\"albumCreateForm\" method=\"post\">"+
		"<table id=\"albumCreateTable\" cellspacing=\"5\" cellpadding=\"5\" border=\"0\">"+
		"<tr><td>Title</td><td><input id=\"albumDialogTitleEdit\" name=\"title\" size=\"15\" style=\"width:170px\" /></td></tr>"+
		"<tr><td valign=\"top\">Description</td><td><textarea id=\"albumDialogDescriptionEdit\" name=\"description\" rows=\"9\" cols=\"40\" style=\"width:170px\"></textarea></td></tr>"+
		"<tr><td>&nbsp</td><td><div align=\"right\"><input id=\"okayBtn\" name=\"okayBtn\" value=\"OK\" type=\"submit\" class=\"inputButton\" />&nbsp&nbsp"+
		"<input id=\"cancelButton\" name=\"cancelbutton\" type=\"button\" value=\"Cancel\" onclick=\"closeAjaxWindow(\'albumCreateWindow\');\" class=\"inputButton\" /></div></td></tr>"+
		"</table></form>";
		
		$('albumCreateWindow').set('html',htmlCode);

		openAjaxWindow('albumCreateWindow',280,280);
		$('albumCreateForm').removeEvent('submit');
		$('albumCreateForm').addEvent('submit', createAlbum.bind(this));
	},
	
	isReady: function (_loadArea, _imgIndex, _imgID)
	{
		if (this.finishedSizing)
		{
			this.modifyImage(_loadArea, _imgIndex, _imgID);
			this.finishedSizing = false;
		}
	},
	
	modifyImage: function (_loadArea, _imgIndex, _imgID, _this)
	{
		// a little internal function
		function loadImageNow ()
		{
			if (!_this)
				_this = this;
			if (_this.currentImageID != _imgID)
			{
				$(_loadArea).set('html', _this.returnImgCode(_this.imageGallery[_imgIndex]));
				$('galleryPhotoCount').set('html', (Number(_imgIndex)+1)+" of "+_this.imageGallery.length+
					" Photos");
				// if we're in edit mode, make sure the text area is still there
				if (_this.thumbEditMode)
					$('galleryImgTitle').set('html', '<textarea id="galleryTitleEdit">'+_this.imageGallery[_imgID][7]+'</textarea>'); 
				else
					$('galleryImgTitle').set('html', _this.imageGallery[_imgID][7]);
				_this.initImage(_loadArea);
				_this.currentImageID = _imgID;
				_this.loadedImage[_imgIndex] = 1;
			}
			
			// resize the main window accordingly, if necessary
			if (resizeMainWindow != null)
				resizeMainWindow();
		}
		
		// if the image has not been loaded yet
		if (this.loadedImage[_imgIndex] == null)
		{
			new Asset.image(this.imageGallery[_imgIndex][0], {onload: loadImageNow.bind(this)});
		} else
		{
			loadImageNow();
		}
	},
	
	returnImgCode: function (_img)
	{
		return "<img src=\""+_img[0]+"\" border=\"0\" id=\""+_img[8]+"\" />";
	},
	
	initImage: function (_imageID)
	{
		var fader = new Fx.Tween(_imageID, {duration: this.fadeSpeed});
		fader.set('opacity', 0);
		fader.start('opacity', 0, 1);
		
		var titleFade = new Fx.Tween('galleryImgTitle', {duration: this.transitionSpeed});
		titleFade.set('opacity', 0);
		titleFade.start('opacity', 0, 1);
	},
	
	checkButton: function ()
	{
		if (this.currentThumbPos < 0)
		{
			$('galleryBackBtn').set('opacity', '1');
			$('galleryBackBtn').set('visibility', 'visible');

		} else {
			$('galleryBackBtn').set('opacity', '0');
			$('galleryBackBtn').set('visibility', 'hidden');
		}
		
		
		var galWidth = this.thumbnailNum * this.maxThumbWidth;
		
		var boxWidth = $('thumbBox').getStyle('width');
		boxWidth = Number(boxWidth.substr(0, (boxWidth.length - 2)));
		
		if (this.currentThumbPos + galWidth <  (boxWidth - this.moveAmount)) {
			$('galleryMoreBtn').set('opacity', '0');
			$('galleryMoreBtn').set('visibility', 'hidden');

		} else {
			$('galleryMoreBtn').set('opacity', '1');
			$('galleryMoreBtn').set('visibility', 'visible');
		}
	},
	
	checkNext: function (_num)
	{
		this.maxThumbnails = (Number(this.thumbnailNum)-1);
		if (this.thumbnailNum <= 1)
		{
			$('galleryPrevBtn').set('visibility', 'hidden');
			$('galleryNextBtn').set('visibility', 'hidden');
			$('galleryPrevBtn').set('opacity', '0');
			$('galleryNextBtn').set('opacity', '0');
		} else
		if (_num < 1)
		{
			//window.alert("begin");
			$('galleryPrevBtn').set('visibility', 'hidden');
			$('galleryNextBtn').set('visibility', 'visible');
			$('galleryPrevBtn').set('opacity', '0');
			$('galleryNextBtn').set('opacity', '1');
			
		} else
		if (_num < this.maxThumbnails)
		{
		//window.alert("mid");
			$('galleryPrevBtn').set('visibility', 'visible');
			$('galleryNextBtn').set('visibility', 'visible');
			$('galleryPrevBtn').set('opacity', '1');
			$('galleryNextBtn').set('opacity', '1');

		} else
		{
		//window.alert("The End");
			$('galleryPrevBtn').set('visibility', 'visible');
			$('galleryNextBtn').set('visibility', 'hidden');
			$('galleryPrevBtn').set('opacity', '1');
			$('galleryNextBtn').set('opacity', '0');

		}
	},
	
	addPosition: function (_addWidth)
	{
		if (!this.moving)
		{
			if (_addWidth == "minus")
				this.currentPos -= 1;
			else if (_addWidth == "plus")
				this.currentPos += 1;
		}
		return this.currentPos;
	},
	
	moveThumbs: function (_way)
	{
		var move = this.currentThumbPos;
		
		if (_way == "plus")
			move += this.moveAmount;
		else
			move -= this.moveAmount;
		
		var moveThumbs = new Fx.Tween('thumbGall', {duration: this.transitionSpeed});
		moveThumbs.start('left', this.currentThumbPos, move);
		this.currentThumbPos = move;
		this.checkButton();
	},
	
	thumbs: function ()
	{
		var resizeThumb = new Fx.Tween('thumbHide', {duration: this.transitionSpeed, transition: Fx.Transitions.quadOut});
		var moveThumbs = new Fx.Tween('thumbBox', {duration: this.transitionSpeed, transition: Fx.Transitions.quadOut});
		
		if (this.thumbOpen)
		{
			resizeThumb.start('height', 119);
			moveThumbs.start('top', -120, 0);
			this.thumbOpen = false;
		} else
		{
			resizeThumb.start('height', 0);
			moveThumbs.start('top', 0, -120);
			this.thumbOpen = true;
		}
	},
	
	initGallery: function (_tempGallery, _count, _firstID, _startWidth, _startHeight)
	{
		this.imageGallery = _tempGallery;
		if (this.preloadImages == "yes")
		{
			var x;
			
			for (x=0;x<this.imageGallery.length; x++)
			{
				var img = new Asset.image(this.imageGallery[x][0]);
			}
		}
		
		this.thumbnailNum = this.imageGallery.length;
		this.currentImageID = _firstID;
		this.currentWidth = _startWidth;
		this.currentHeight = _startHeight;
		if (this.thumbnailNum > this.maxThumbnails)
		{
			$('galleryBackBtn').set('html',
				"<div id=\"galleryLeftMore\"><ul><li>"+
				"<a href=\"javascript:"+this.varName+".checkButton("+this.varName+
				".addPosition('minus'));"+this.varName+".moveThumbs('plus');\"><img src=\""+
				this.rootURL+"cms/css/GalleryModule/buttonblank.gif\" width=\"15\" "+
				"height=\"115\" border=\"0\" /></a></li></ul></div>");
				
			$('galleryMoreBtn').set('html',
				"<div id=\"galleryRightMore\"><ul><li>"+
				"<a href=\"javascript:"+this.varName+".checkButton("+this.varName+
				".addPosition('plus'));"+this.varName+".moveThumbs('minus');\"><img src=\""+
				this.rootURL+"cms/css/GalleryModule/buttonblank.gif\" width=\"15\" "+
				"height=\"115\" border=\"0\" /></a></li></ul></div>");
		}
		var setLoaderWidth = new Fx.Tween('galleryImageWrapper', {duration: this.transitionSpeed,
			onComplete: function() {
				var setLoaderHeight = new Fx.Tween('galleryImageWrapper', {duration: this.transitionSpeed,
				onComplete: function() {this.loadFirstImage(); }.bind(this)});
				setLoaderHeight.start('height', this.imageGallery[0][2]);
			}.bind(this)});
		setLoaderWidth.start('width', this.imageGallery[0][1]);
		this.checkNext(0);
	},
	
	getStarted: function (_width, _height, _loadArea, _imgIndex, _imgID, _currentImgID)
	{
		// if there is an image currently being edited, save its caption
		// before we move on to the next image
		if (admin.editMode && this.thumbEditMode)
			this.save(false);
			
		this.checkNext(_imgID);
		if (_currentImgID != _imgID)
		{
			if (this.firstImageStart)
			{
				this.currentWidth = this.firstImageWidth;
				this.currentHeight = this.firstImageHeight;
				this.firstImageStart = false;
			}
			
			if (this.nextOrPrev)
			{
				this.currentWidth = this.cwidth;
				this.currentHeight = this.cheight;
				this.nextOrPrev = false;
			}
			
			var resizeDivHeight = new Fx.Tween('galleryImageWrapper', {duration: this.transitionSpeed,
				onComplete: function() {
					
					this.modifyImage(_loadArea, _imgIndex, _imgID, this);
					this.currentHeight = _height;
					this.currentWidth = _width;
				}.bind(this)
			});
			
			var fader = new Fx.Tween('galleryImgLoader', {duration: this.transitionSpeed,
				onComplete: function () {

					var resizeDivWidth = new Fx.Tween('galleryImageWrapper', {duration: this.transitionSpeed,
					onComplete: function() {
						resizeDivHeight.start('height', this.currentHeight, _height);
					}.bind(this)});
					resizeDivWidth.start('width', this.currentWidth, _width);
				}.bind(this)
			});
			
			fader.start('opacity', 1, 0);
			
			var titleFade = new Fx.Tween('galleryImgTitle', {duration: this.transitionSpeed});
			titleFade.set('opacity', 0);
			this.fadeOut = false;
		}
	},
	
	loadFirstImage: function ()
	{
		var fadeFirst = new Fx.Tween('galleryImgLoader', {duration: this.transitionSpeed});
		fadeFirst.set('opacity', 0);
		var firstTitleFade = new Fx.Tween('galleryImgTitle', {duration: this.transitionSpeed});
		firstTitleFade.set('opacity', 1);

		_this = this;
		function setFirstImage ()
		{
			$('galleryImgLoader').set('html', "<img src=\""+_this.tempGallery[0][0]+"\" />");
			$('galleryImgTitle').set('html', _this.tempGallery[0][7]);
			
			fadeFirst.start('opacity', 0, 1);
			//_this.currentHeight = _this.imageGallery[0][2];
			//_this.currentWidth = _this.imageGallery[0][1];
		}
		new Asset.image(this.imageGallery[0][0], {onload: setFirstImage.bind(this)});
		this.checkButton();
	},
	
	nextImage: function ()
	{
		var imgID = Number(this.currentImageID)+1;
		var imgIndex = this.imageGallery[imgID][8];
		
		this.checkNext(imgID);
		this.nextOrPrev = 1;
		this.getStarted(Number(this.imageGallery[imgID][1]), Number(this.imageGallery[imgID][2]),
			'galleryImgLoader', Number(imgIndex), Number(imgID),
			Number(this.currentImageID), Number(this.imageGallery[this.currentImageID][1]),
			Number(this.imageGallery[this.currentImageID][2]));
	},
	
	prevImage: function ()
	{
		var imgID = Number(this.currentImageID)-1;
		var imgIndex = this.imageGallery[imgID][8];
		
		this.checkNext(imgID);
		this.nextOrPrev = 1;
		this.getStarted(Number(this.imageGallery[imgID][1]), Number(this.imageGallery[imgID][2]),
			'galleryImgLoader', Number(imgIndex), Number(imgID),
			Number(this.currentImageID), Number(this.imageGallery[this.currentImageID][1]),
			Number(this.imageGallery[this.currentImageID][2]));
	},
	
	mouseOverGallery: function (_id)
	{
		if (admin.editMode || admin.deleteMode)
		{
			$('galleryTitleRow'+_id).setStyle('background-color', '#aaa');
			//$('galleryThumbsRow'+_id).setStyle('background-color', '#aaa');
		}
	},
	
	mouseOutGallery: function (_id)
	{
		$('galleryTitleRow'+_id).setStyle('background-color', 'transparent');
		//$('galleryThumbsRow'+_id).setStyle('background-color', 'transparent');
	},
	
	mouseClickGallery: function (_id)
	{
		if (admin.editMode)
		{
			this.showAddAlbumDialog('editMode', $('galleryTitleRow'+_id).get('path'));
			$('albumDialogTitleEdit').set('value', $('albumTitle'+_id).get('html'));
			$('albumDialogDescriptionEdit').set('value', $('albumDescription'+_id).get('html'));
		} else
		if (admin.deleteMode)
		{
			// just make sure
			if (window.confirm('Are you sure you want to delete this album?'))
			{
				new Request({url: serverURL+'ajax', method: 'post',
					data: {
						'module': 'GalleryModule',
						'page'  : this.page,
						'slot'  : this.slot,
						'cmd'   : 'deleteAlbum',
						'path'  : $('galleryTitleRow'+_id).get('path')
					},
					onComplete: function (data) {
						if (data == 'error')
							window.alert('Unable to delete album. Please contact the system administrator.');
						else
						if (data == 'success')
						{
							// delete the row from the table
							$('galleryTitleRow'+_id).dispose();
							$('galleryThumbsRow'+_id).dispose();
						} else
							window.alert('Unable to perform request. Please contact the system administrator.');
					}}).send();
			}
		}
	},
	
	mouseOverImage: function (_id)
	{
		if (admin.editMode && !this.thumbEditMode)
			$('galleryImgTitle').setStyle('background-color', '#aaa');
		
		// if we're in delete mode
		if (admin.deleteMode)
		{
			// something about delete mode
		}
	},
	
	mouseOutImage: function (_id)
	{
		$('galleryImgTitle').setStyle('background-color', 'transparent');
	},
	
	/*
	 * Returns true if the event must continue executing, or false if it must stop.
	 */
	mouseClickImage: function (_id)
	{
		// if we're currently not in thumbnail edit mode, and we are in administrative edit mode
		if (!this.thumbEditMode && admin.editMode)
		{
			// display the editor
			$('galleryImgTitle').set('html', '<textarea id="galleryTitleEdit">'+$('galleryImgTitle').get('html')+'</textarea>');
			this.mouseOutImage();
			this.thumbEditMode = true;
			admin.activeModule = this;
		}
		
		// if we're in delete mode
		if (admin.deleteMode)
		{
			if (window.confirm('Are you sure you want to delete this image?'))
			{
				// attempt to delete the image via AJAX
				new Request({url: serverURL+'ajax', method: 'post',
					data: {
						'module'    : 'GalleryModule',
						'page'      : this.page,
						'slot'      : this.slot,
						'cmd'       : 'deleteImage',
						'albumPath' : this.albumPath,
						'image'     : this.imageGallery[_id][9]
					},
					onComplete: function (data) {
						if (data == 'success')
							window.location.reload();
						else if (data == 'error')
							window.alert('Unable to delete image from server. Please contact the system administrator.');
						else
							window.alert(data);
					}
				}).send();
			}
			return false;
		}
		
		return true;
	},
	
	/*
	 * Saves the thumbnail currently being edited and removes the caption editor.
	 */
	save: function (_closeEditor)
	{
		// assume that the editor is to be closed
		if (_closeEditor == null)
			_closeEditor = true;
		
		if (this.thumbEditMode)
		{
			var caption = $('galleryTitleEdit').get('value');
			
			// perform the change request via AJAX
			new Request({url: serverURL+'ajax', method: 'post',
				data: {
					'module'    : 'GalleryModule',
					'page'      : this.page,
					'slot'      : this.slot,
					'cmd'       : 'saveImageCaption',
					'albumPath' : this.albumPath,
					'image'     : this.imageGallery[this.currentImageID][9],
					'caption'   : caption
				},
				onComplete: function (data) {
					if (data == 'error')
						window.alert('An error occurred while trying to save the image caption. Please contact the system administrator.');
					else if (data == 'success')
					{
						// store it in memory
						this.imageGallery[this.currentImageID][7] = caption;
						if (_closeEditor)
						{
							// change it back to a plain old DIV element
							$('galleryImgTitle').set('html', caption);
							this.thumbEditMode = false;
						}
					} else
						window.alert(data);
				}.bind(this)
			}).send();
		}
	}
});

