/*
	Copyright (c) 2006-2007, ePages GmbH
	All Rights Reserved.

	epages.cartridges.de_epages.mediagallery.widget.Filestore

*/
dojo.provide('epages.cartridges.de_epages.mediagallery.widget.Filestore');
dojo.require('epages.lang.hash');
dojo.require('epages.io.json');
dojo.require('epages.widget');
dojo.require('dojo.data.api.Identity');
dojo.require('dojo.data.util.simpleFetch');

dojo.declare(
	'epages.cartridges.de_epages.mediagallery.widget.Filestore',
	[dojo.data.api.Identity],
	{
		/**
		 * public properties
		 */
		actionViewResponse : "JSONViewResponse",
		url                : '?',                  // request url like '/epages/DemoShop.admin/?'
		siteId             : '',                   //objectId of the rode node (start page)
		id                 : 'Filestore',
		validFileTypes     : '',              		 // media gallery option: filter file list to show only files with these extensions
		alleryUsage        : {},                   // hash with gallery size usage data
		/**
		 * private properties
		 */
		_directoryTree    : undefined, // epages.lang.Hash includes server data about directories
		_JsonIo           : undefined, // epages.io.Json includes server connection

		constructor: function(keywordParameters){
			dojo.mixin(this,keywordParameters);
			this._directoryTree = $H();
			this._JsonIo = new epages.io.Json();
		},

		postMixInProperties: function() {
		// summary: initalize values - adjust properites
			this.inherited("postMixInProperties", arguments);
		},

		// loads the file and directory list from the server
		_loadList: function(directoryPath) {
			var info =  this._directoryTree.existsKey(directoryPath) ? this._directoryTree.get(directoryPath) : undefined;
			if (info && ! info.dirty) {
				return true;
			}

			// get data from server
			var JsonData = this._JsonIo.loadSync(
				this.url+'ViewAction=JSONGetDirectoryList&ObjectID='+this.siteId+'&directory='+directoryPath+'&IgnoreDirectoryNotFound=1',
				undefined,
				undefined,
				true
			);
			if (JsonData.data.status === 'DirectoryNotFound') {
				return false;
			}

			if (JsonData.error) {
				JsonData = this._JsonIo.loadSync(
					this.url+'ViewAction=JSONGetDirectoryList&ObjectID='+this.siteId
				);
			}
			// build internal structure
			var aDirectory = directoryPath.split('/');

			this._directoryTree.set(directoryPath, {
				directories : $A(JsonData.data.directories),
				files       : JsonData.data.files,
				title       : aDirectory.pop(),
				parent      : aDirectory.join('/'),
				dirty       : false,
				node        : (info ? info.node : undefined)
			});

			// propagate new gallery size data
			this.galleryUsage = JsonData.data.galleryUsage;
			return true;
		},

		_fetch: function (directory) {
			var directores = this._directoryTree.get(directory).directories;
			var items = [];
			var i;
			$A(directores).each( function(el) {
				items.push({
					title   : el.name,
					isFolder: el.hasSub,
					children: el.hasSub == 1 ? [] : undefined,
					directory: directory + '/' + el.name
				});
			});
			return items;
		},

		_fetchItems: function(keywordArgs, findCallback, errorCallback){
			if(this._loadList(keywordArgs.query.id) && typeof findCallback == 'function') {
				findCallback(this._fetch(keywordArgs.query.id), keywordArgs);
			} else {
				errorCallback(true,keywordArgs);
			}
		},

		getFiles: function(directory){
			if(this._loadList(directory)){
				var files = this._directoryTree.get(directory).files;
				if($A(files).length != 0){
					// list of allowed extensions
					var fileTypeArray = this._convertFileTypeArray(this.validFileTypes);

					$A(files).each(function (el) {
						el.title = el.name;
						el.directory = el.directory;
						el.path = el.path;
						el.canDelete='true';
						el.canChangeTitle='true';
						// toggle as disabled file?
						var isValidExt = false;
						var extension = el.extension.replace(/\W/g, ''); // ".gif" => "gif"
						if(fileTypeArray) {
							for( var j=0,jLength=fileTypeArray.length ; j<jLength ; j++ ) {
								if(extension.match(new RegExp(fileTypeArray[j], "i"))) {
									isValidExt = true;
								}
							}
						} else {
							isValidExt = true; //default case
						}
						if(!isValidExt) {
							el.disabled = true;
						} else {
							el.disabled = false;
						}
					});
					return files;
				}
			}
			return;
		},

		hasAttribute: function(node, attributeName){
			return node[attributeName] !== undefined;
		},

		getLabel: function(item){
			if(item.title !== undefined){
				return item.title;
			}
			return undefined;
		},

		getIdentity: function(item){
			if(item.directory !== undefined){
				return item.directory;
			}
			return undefined;
		},

		getValue: function(item, attribute){
			console.warn('getValue %s', attribute);
		},

		getValues: function(item, attribute){
			if (attribute == 'children' && this._loadList(item.directory)) {
				return this._fetch(item.directory);
			}
			else{
				console.error('getValues() unknown attribute', attribute);
			}
		},

		isItemLoaded: function(something){
			//console.debug('isItemLoaded');
			return true;
		},

		resetCache: function (directory) {
			this._directoryTree.get(directory).dirty = true;
		},

		recursiveResetCache: function (directory) {
			var keys = this._directoryTree.keys();
			var dirDel = directory + '/';
			var dirLen = dirDel.length;
			this._directoryTree.remove(directory);
			for( var i=0,iLength=keys.length ; i<iLength ; i++ ) {
				if (keys[i].substr(0, dirLen) == dirDel) {
					this._directoryTree.remove(keys[i]);
				}
			}
		},

		_send: function (params, opt) {
			if(params.ObjectID  == undefined){
				params.ObjectID = this.siteId;
			}
			var result  = this._JsonIo.loadSync(this.url, params);
			return result;

		},

		renameFile: function (directory,SourceFile,TargetFileName) {
			if(TargetFileName == undefined || TargetFileName == '') {
				return false;
			}

			var JsonData = undefined;
			var cleanSourceFile = this.removeMediaGalleryFromString(SourceFile);

			// nothing changed?
			if(TargetFileName === cleanSourceFile) {
				dojo.publish(this.id+'/onSuccess',[]);
				return TargetFileName;
			}

			JsonData = this._send({
				ChangeAction:   "JSONRenameFile",
				SourceFile:     cleanSourceFile,
				TargetFileName: TargetFileName,
				ViewAction:     this.actionViewResponse
			});
			if(typeof JsonData) {
				if(JsonData.data) {
					// filtered file name
					if(JsonData.data.ResultingFilename) {
						TargetFileName = JsonData.data.ResultingFilename;
					}

					this._directoryTree.get(directory).dirty = true;
					dojo.publish(this.id+'/renamedFile',[SourceFile,TargetFileName,directory]);
					dojo.publish(this.id+'/onSuccess',[]);
					return TargetFileName;
				}
				else {
					// error: target file already exists
					if(JsonData.error.data.Errors) {
						dojo.publish(this.id+'/onError',[{Errors: JsonData.error.data.Errors}]);
						return false;
					}
				}
			}
			else{
				return false;
			}
		},

		deleteFiles: function(selectedNodes,directory) {
			var selectedFiles = []; // Array with Filenames
			for( var i=0,iLength=selectedNodes.length ; i<iLength ; i++ ) {
				if(selectedNodes[i].canDelete){
					selectedFiles.push(this.removeMediaGalleryFromString(selectedNodes[i].path));
				}
			}
			if(selectedFiles.length > 0) {
				var jsonResult = this._send({
					ChangeAction: "JSONDeleteFile",
					File:         selectedFiles,
					ViewAction:   this.actionViewResponse
				});

				if(jsonResult) {
					this.resetDirectory(directory);
					dojo.publish(this.id+'/deleteFiles',[selectedFiles]);
					if(jsonResult.data && jsonResult.data.currentGallerySize) {
						dojo.publish(this.id+'/updateCurrentBytes', [ jsonResult.data.currentGallerySize ] );
					}
					return true;
				}
				else{
					return false;
				}
			}
		},

		getInfo: function (directory) {
			if (this._loadList(directory)){ // make sure that node exists
				return this._directoryTree.get(directory);
			}
			return undefined;
		},

		getNode: function(directory) {
			// also dirty infos contains correct node
			if (this._directoryTree.existsKey(directory)) {
				return this.getInfo(directory);
			}
			return undefined;
		},

		getNodeTitle: function (directory) {
			//return this.getNode(directory).title;
		},

		createDirectory: function (name,parentDirectory) {
			var info = this.getInfo(parentDirectory);
			var JsonData = undefined;
			var targetdirectory = this.removeMediaGalleryFromString(parentDirectory);
			JsonData = this._send({
				TargetDirectory: targetdirectory ? targetdirectory : "",
				ChangeAction:   "JSONCreateDirectory",
				DirectoryName:  name,
				ViewAction:     this.actionViewResponse
			});

			// different name was created?
			if(JsonData) {
				if(JsonData.data) {
					if(JsonData.data.ResultingDirectory) {
						name = JsonData.data.ResultingDirectory;
					}
					if(JsonData.data.currentGallerySize) {
						dojo.publish(this.id+'/updateCurrentBytes', [ JsonData.data.currentGallerySize ] );
					}
				}
				else {
					// error creating
					if(JsonData.error.data.Errors) {
						dojo.publish(this.id+'/onError',[{Errors: JsonData.error.data.Errors}]);
						return false;
					}
				}

				if(!info){
					info = this.getInfo(parentDirectory);
				} else {
					// add new directory to parent
					info.hasSub = true;
					info.directories.push({
						name: name,
						hasSub: 0
					});
				}
				// add new directory to cache + add node
				var directory = parentDirectory + '/' + name;
				this._directoryTree.set(directory, {
					directories : $A(),
					files       : [],
					title       : name,
					parent      : parentDirectory,
					node        : directory.node
				});

				dojo.publish(this.id+'/createDirectory',[directory]);
				return true;
			}
			else{
				return false;
			}
		},

		renameDirectory: function (name,oldName,directory) {
			if(name == undefined || name == ''){
				return false;
			}
			var info = this.getInfo(directory);
			var JsonData = undefined;
			JsonData = this._send({
				SourceDirectory: this.removeMediaGalleryFromString(directory),
				ChangeAction:   "JSONRenameDirectory",
				TargetDirectoryName:  name,
				ViewAction:     this.actionViewResponse
			});
			// different name was used for rename?
			if(typeof JsonData) {

				if(JsonData.data) {
					if(JsonData.data.ResultingDirectory) {
						name = JsonData.data.ResultingDirectory;
					}
				}
				else {
					// error : aleady exists!
					if(JsonData.error.data.Errors) {
						dojo.publish(this.id+'/onError',[{Errors: JsonData.error.data.Errors}]);
						return false;
					}
				}

				this.resetCache(info.parent);
				this.recursiveResetCache(oldName);

				dojo.publish(this.id+'/renameDirectory',[name,directory]);
				return name;
			}
			else{
				return false;
			}
		},

		deleteDirectory: function (directory) {
			var info = this.getInfo(directory);
			var jsonResult = this._send({
				Directory:      this.removeMediaGalleryFromString(directory),
				ChangeAction:   "JSONDeleteDirectory",
				ViewAction:     this.actionViewResponse
			});
			if(jsonResult){
				this.resetCache(info.parent);
				this.recursiveResetCache(directory);
				dojo.publish(this.id+'/deleteDirectory',[directory]);
				if(jsonResult.data && jsonResult.data.currentGallerySize) {
					dojo.publish(this.id+'/updateCurrentBytes', [ jsonResult.data.currentGallerySize ] );
				}
				return true;
			}
			else{
				return false;
			}
		},

		resetDirectory: function (directory) {
			var node = this.getNode(directory);
			this.resetCache(directory);
			this._loadList(directory);
			var info = this.getInfo(directory);
			info.node = node;
		},

		copyImageFromImageDb: function (directory, files) {
			var dir = this.removeMediaGalleryFromString(directory);
			var jsonResult = this._send({
				ChangeAction:     "JSONCopyImageFromImageDb",
				TargetDirectory: dir ? dir : "",
				SourceFile:       files,
				ViewAction:       this.viewAction
			});
			if(jsonResult){
				this.resetDirectory(directory);
				if(jsonResult.data && jsonResult.data.currentGallerySize) {
					dojo.publish(this.id+'/updateCurrentBytes', [ jsonResult.data.currentGallerySize ] );
				}
				return true;
			}
			else{
				return false;
			}
		},

		removeMediaGalleryFromString: function (/* String */ directory) {
		   // summary: removes "MediaGallery" string from given directory path
		   // description: If the given directory contains the string "MediaGallery", it removes
		   // 	the string. In addition a leading path slash (slash or backslash) is removed.
		   // example:
		   //    var jailedDir = removeMediaGalleryFromString('MediaGallery/test/mydir');
		   //		 will return 'test/mydir'.
		   // returns: directory name/path without "MediaGallery" | string
			if(!directory){
				return;
			}

			var str = directory.replace(/^MediaGallery/, '');
			str = str.replace(/^[\\\/]/, '');

			return str; // String
		},

		setFileTypes: function(/* String */ fileTypes) {
		   // summary: updates the list of allowed file extensions
			if(typeof(fileTypes) === "string" && (this.validFileTypes != fileTypes)) {
				this.validFileTypes = fileTypes;
			}
		},

		_convertFileTypeArray: function(/* String */ validFileTypeString) {
		   // summary: converts a string with a ";"-seperated list of file extensions into an array
		   // example:
		   //    var fileTypeArray = this._convertFileTypeArray(this.validFileTypes);
		   // returns: array of file extensions | array of string
			var fileTypeArray;
			if(validFileTypeString) {
				fileTypeArray = validFileTypeString.split(";");
			}
			return fileTypeArray;
		}

});

dojo.extend(epages.cartridges.de_epages.mediagallery.widget.Filestore,dojo.data.util.simpleFetch);