/**
 * @class elFinder command "getfile". 
 * Return selected files info into outer callback.
 * For use elFinder with wysiwyg editors etc.
 *
 * @author Dmitry (dio) Levashov, dio@std42.ru
 **/
(elFinder.prototype.commands.getfile = function() {
	"use strict";
	var self   = this,
		fm     = this.fm,
		filter = function(files) {
			var o = self.options,
				fres = true;

			files = $.grep(files, function(file) {
				fres = fres && (file.mime != 'directory' || o.folders) && file.read ? true : false;
				return fres;
			});

			return o.multiple || files.length == 1 ? files : [];
		};
	
	this.alwaysEnabled = true;
	this.callback      = fm.options.getFileCallback;
	this._disabled     = typeof(this.callback) == 'function';
	
	this.getstate = function(select) {
		var sel = this.files(select),
			cnt = sel.length;
			
		return this.callback && cnt && filter(sel).length == cnt ? 0 : -1;
	};
	
	this.exec = function(hashes) {
		var fm    = this.fm,
			opts  = this.options,
			files = this.files(hashes),
			cnt   = files.length,
			url   = fm.option('url'),
			tmb   = fm.option('tmbUrl'),
			dfrd  = $.Deferred()
				.done(function(data) {
					var res,
						done = function() {
							if (opts.oncomplete == 'close') {
								fm.hide();
							} else if (opts.oncomplete == 'destroy') {
								fm.destroy();
							}
						},
						fail = function(error) {
							if (opts.onerror == 'close') {
								fm.hide();
							} else if (opts.onerror == 'destroy') {
								fm.destroy();
							} else {
								error && fm.error(error);
							}
						};
					
					fm.trigger('getfile', {files : data});
					
					try {
						res = self.callback(data, fm);
					} catch(e) {
						fail(['Error in `getFileCallback`.', e.message]);
						return;
					}
					
					if (typeof res === 'object' && typeof res.done === 'function') {
						res.done(done).fail(fail);
					} else {
						done();
					}
				}),
			result = function(file) {
				return opts.onlyURL
					? opts.multiple ? $.map(files, function(f) { return f.url; }) : files[0].url
					: opts.multiple ? files : files[0];
			},
			req = [], 
			i, file, dim;

		for (i = 0; i < cnt; i++) {
			file = files[i];
			if (file.mime == 'directory' && !opts.folders) {
				return dfrd.reject();
			}
			file.baseUrl = url;
			if (file.url == '1') {
				req.push(fm.request({
					data : {cmd : 'url', target : file.hash},
					notify : {type : 'url', cnt : 1, hideCnt : true},
					preventDefault : true
				})
				.done(function(data) {
					if (data.url) {
						var rfile = fm.file(this.hash);
						rfile.url = this.url = data.url;
					}
				}.bind(file)));
			} else {
				file.url = fm.url(file.hash);
			}
			if (! opts.onlyURL) {
				if (opts.getPath) {
					file.path = fm.path(file.hash);
					if (file.path === '' && file.phash) {
						// get parents
						(function() {
							var dfd  = $.Deferred();
							req.push(dfd);
							fm.path(file.hash, false, {})
								.done(function(path) {
									file.path = path;
								})
								.fail(function() {
									file.path = '';
								})
								.always(function() {
									dfd.resolve();
								});
						})();
					}
				}
				if (file.tmb && file.tmb != 1) {
					file.tmb = tmb + file.tmb;
				}
				if (!file.width && !file.height) {
					if (file.dim) {
						dim = file.dim.split('x');
						file.width = dim[0];
						file.height = dim[1];
					} else if (opts.getImgSize && file.mime.indexOf('image') !== -1) {
						req.push(fm.request({
							data : {cmd : 'dim', target : file.hash},
							notify : {type : 'dim', cnt : 1, hideCnt : true},
							preventDefault : true
						})
						.done(function(data) {
							if (data.dim) {
								var dim = data.dim.split('x');
								var rfile = fm.file(this.hash);
								rfile.width = this.width = dim[0];
								rfile.height = this.height = dim[1];
							}
						}.bind(file)));
					}
				}
			}
		}
		
		if (req.length) {
			$.when.apply(null, req).always(function() {
				dfrd.resolve(result(files));
			});
			return dfrd;
		}
		
		return dfrd.resolve(result(files));
	};

}).prototype = { forceLoad : true }; // this is required command
