Ext.define("Ext.ux.file.util.Handler", {

	singleton: true,

	model: null,

	extensions: [
		"jpg",
		"jpeg",
		"png",
		"gif",
		"bmp",
		"pdf",
		"docx",
		"doc",
		"xls",
		"xlsx",
		"xlm",
		"xlt",
		"xlw",
		"ppt",
		"txt",
		"dwg"
	],

	imageExtension: [
		"jpg",
		"jpeg",
		"png",
		"gif",
		"bmp"
	],

	getRecordById: function(id, f_callback) {
		var i_self = this;
		var a_batch = [];

		a_batch.push({
			type: "get",
			dmd: "dmd/webshop.dmd",
			entity: "WSHFILET00",
			context: "grid",
			uiName: "portfolio",
			where: "FILFILTKN = " + id,
			page: 1,
			start: 0,
			limit: -1
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {

				var o_result = Ext.decode(o_response.responseText);
				var o_batch = o_result.batch[0];
				var i_record;

				Ext.Array.each(o_batch.rows, function(o_record) {
					var Model = i_self.getModel();
					i_record = Model.create(o_record);
				});

				f_callback(i_record);
			}
		});
	},

	getRecordsById: function(a_ids, f_callback) {
		var i_self = this;
		var a_batch = [];

		Ext.Array.each(a_ids, function (id) {
			a_batch.push({
				type: "get",
				dmd: "dmd/webshop.dmd",
				entity: "WSHFILET00",
				context: "grid",
				uiName: "portfolio",
				where: "FILFILTKN = " + id,
				page: 1,
				start: 0,
				limit: -1
			});
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var a_records = [];
				var a_batch = o_result.batch;
				Ext.Array.each(a_batch, function(o_batch) {
					Ext.Array.each(o_batch.rows, function(o_record) {

						var Model = i_self.getModel();

						var i_record = Model.create(o_record);
						a_records.push(i_record);
					});
				});
				f_callback(a_records);
			}
		});
	},

	getRecordByName: function(path, name, f_callback) {
		var i_self = this;
		var a_batch = [];

		a_batch.push({
			type: "get",
			dmd: "dmd/webshop.dmd",
			entity: "WSHFILET00",
			context: "grid",
			uiName: "portfolio",
			where: "FILPATH = \"" + path + "\" AND FILNAME = \"" + name + "\"",
			page: 1,
			start: 0,
			limit: -1
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var a_records = [];
				var batch = o_result.batch[0];
				Ext.Array.each(batch.rows, function(o_record) {

					var Model = i_self.getModel();
					var record = Model.create(o_record);

					a_records.push(record);
				});
				f_callback(a_records);
			}
		});
	},

	getRecordsByName: function(path, a_names, f_callback) {
		var i_self = this;
		var a_batch = [];
		var s_where = "";

		for (var i = 0; i < a_names.length; i++) {
			var value = a_names[i];
			var a_ext = value.split(".");
			var s_ext = a_ext.pop();
			value = a_ext.join("") + "." + s_ext;
			if (i === 0) {
				s_where = s_where + "'" + value + "'";
			}
			else {
				s_where = s_where + ",'" + value + "'";
			}
		}

		a_batch.push({
			type: "get",
			dmd: "dmd/webshop.dmd",
			entity: "WSHFILET00",
			context: "grid",
			uiName: "portfolio",
			where: "FILPATH = '" + path + "' AND FILNAME IN (" + s_where + ")",
			page: 1,
			start: 0,
			limit: -1
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var a_records = [];
				var batch = o_result.batch[0];
				Ext.Array.each(batch.rows, function(o_record) {

					var Model = i_self.getModel();
					var record = Model.create(o_record);

					a_records.push(record);
				});
				f_callback(a_records);
			}
		});
	},

	getRecordsByPath: function(path, f_callback) {

		var i_self = this;
		var a_batch = [];

		a_batch.push({
			type: "get",
			dmd: "dmd/webshop.dmd",
			entity: "WSHFILET00",
			context: "grid",
			uiName: "portfolio",
			where: "FILPATH = '" + path +"'",
			page: 1,
			start: 0,
			limit: -1
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var a_records = [];
				var batch = o_result.batch[0];
				Ext.Array.each(batch.rows, function(o_record) {

					var Model = i_self.getModel();
					var i_record = Model.create(o_record);

					a_records.push(i_record);
				});
				f_callback(a_records);
			}
		});
	},

	getFilesByPath: function(path, f_callback) {
		var i_self = this;
		Ext.Ajax.request({
			url: "/ip2-Services/webbios.aspx",
			method: "GET",
			params: {
				func: "listdir",
				path: path
			},
			success: function(o_response) {
				var a_files = Ext.decode(o_response.responseText);
				var a_result = Ext.Array.filter(a_files, function(o_file) {
					return Ext.Array.indexOf(i_self.extensions, o_file.ext.toLowerCase()) > -1;
				});
				f_callback(a_result);
			}
		});
	},

	getRecordListByPath: function(path, f_callback) {
		var i_self = this;
		i_self.getFilesByPath(path, function(a_files) {
			var a_records = [];
			Ext.Array.each(a_files, function(o_file) {
				o_record = {
					name: o_file.text,
					size: o_file.size
				};
				a_records.push(o_record);
			});
			i_self.createRecordsNoUploadNoImageInfo(path, a_records, function(a_records) {
				f_callback(a_records);
			});
		});
	},

	getPathById: function(id, f_callback) {
		var i_self = this;
		var a_batch = [];

		a_batch.push({
			type: "get",
			dmd: "dmd/webshop.dmd",
			entity: "WSHFILET00",
			context: "grid",
			uiName: "portfolio",
			where: "FILFILTKN = " + id,
			page: 1,
			start: 0,
			limit: -1
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var o_batch = o_result.batch[0];
				var i_record;
				Ext.Array.each(o_batch.rows, function(o_record) {

					var Model = i_self.getModel();
					i_record = Model.create(o_record);
				});
				f_callback(i_record.get("FILPATH") + i_record.get("FILNAME"));
			}
		});
	},

	getModel: function () {

		var i_self = this;
		var i_model = i_self.model;

		if (!i_model) {
			try {
				i_self.model = ip2.model({
					dmd: "dmd/webshop.dmd",
					entityName: "WSHFILET00",
					context: "grid",
					uiName: "portfolio"
				});
			}
			catch (err) {}
		}

		return i_self.model;
	},

	getPathsById: function(a_ids, f_callback) {

		var i_self = this;
		var a_batch = [];

		Ext.Array.each(a_ids, function (id) {
			a_batch.push({
				type: "get",
				dmd: "dmd/webshop.dmd",
				entity: "WSHFILET00",
				context: "grid",
				uiName: "portfolio",
				where: "FILFILTKN = " + id,
				page: 1,
				start: 0,
				limit: -1
			});
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var a_paths = [];
				var a_batch = o_result.batch;
				Ext.Array.each(a_batch, function(o_batch) {
					Ext.Array.each(o_batch.rows, function(o_record) {

						var Model = i_self.getModel();
						var i_record = Model.create(o_record);
						var s_path = i_record.get("FILPATH");
						var s_name = i_record.get("FILNAME");
						var s_filename = [s_path, s_name].join();

						a_paths.push(s_filename);
					});
				});
				f_callback(a_paths);
			}
		});
	},

	getUrlByExtension: function(s_path, b_noStringify) {

		var s_url = "";
		var s_extension = s_path.split(".").pop().toLowerCase();
		var a_extension_image = ["jpg","jpeg","png","gif", "bmp"];
		var a_docs = ["doc", "docx"];
		var a_xls = ["xls", "xlsx", "xlm","xlt", "xlw"];
		var s_pdf = "pdf";
		var s_ppt = "ppt";
		var s_dwg = "dwg";
		var s_youtube = "youtube.com";
		var a_videos = ["mp4", "mov", "mpeg4", "wmv", "flv", "avi"];

		if (a_extension_image.indexOf(s_extension) != -1) {
			if (!b_noStringify) {
				s_url = "\"" + s_path + "\"";
			}
			else {
				s_url = s_path;
			}
		}
		else {
			if (s_pdf == s_extension) {
				s_url = "/portfolio/styles/icon/flatui/media/pdf.png";
			}
			else if (s_ppt == s_extension) {
				s_url = "/portfolio/styles/icon/flatui/media/ppt.png";
			}
			else if (s_dwg == s_extension) {
				s_url = "/portfolio/styles/icon/flatui/media/dwg.png";
			}
			else if (a_docs.indexOf(s_extension) != -1) {
				s_url = "/portfolio/styles/icon/flatui/media/doc.png";
			}
			else if (a_xls.indexOf(s_extension) != -1) {
				s_url = "/portfolio/styles/icon/flatui/media/xls.png";
			}
			else if (s_path.indexOf(s_youtube) != -1 || a_videos.indexOf(s_extension) != -1) {
				s_url = "/portfolio/styles/icon/flatui/media/mg-type-video.png";
			}
			else {
				s_url = "/portfolio/styles/icon/flatui/media/generic-doc.png";
			}
		}
		return s_url;
	},

	getHives: (function() {

		var a_hives;

		var resolve = function(path, b_system, fn) {
			var hives = Ext.Array.filter(a_hives, function(o) {
				return o.parent == path
					|| "/" + o.parent == path
					|| "/" + path == o.parent
					|| o.parent + "/" == path
					|| path + "/" == o.parent
					|| "/" + o.parent + "/" == path
					|| "/" + path + "/" == o.parent;
			});
			hives = Ext.Array.map(hives, function(o_hive) {
				if (o_hive.type == "system") {
					if (b_system) {
						return {
							path: "/" + o_hive.alias + "/",
							text: ip2.i18n(Ext.decode(o_hive.title)),
							isHive: true,
							hasChild: false,
							allowDrop: o_hive.allowDrop !== undefined ? Ext.decode(o_hive.allowDrop) : false,
							allowImport: o_hive.allowImport !== undefined ? Ext.decode(o_hive.allowImport) : false,
							allowAdd: o_hive.allowAdd !== undefined ? Ext.decode(o_hive.allowAdd) : false,
							iconCls: o_hive.iconCls || "",
							type: o_hive.type || "",
							saveUrl: o_hive.saveUrl !== undefined ? Ext.decode(o_hive.saveUrl) : false || true

						};
					}
				}
				else {
					return {
						path: "/" + o_hive.alias + "/",
						text: ip2.i18n(Ext.decode(o_hive.title)),
						isHive: true,
						hasChild: true,
						allowDrop: o_hive.allowDrop !== undefined ? Ext.decode(o_hive.allowDrop) : false,
						allowImport: o_hive.allowImport !== undefined ? Ext.decode(o_hive.allowImport) : false,
						allowAdd: o_hive.allowAdd !== undefined ? Ext.decode(o_hive.allowAdd) : false,
						iconCls: o_hive.iconCls || "",
						type: o_hive.type || "",
						saveUrl: o_hive.saveUrl !== undefined ? Ext.decode(o_hive.saveUrl) : false || true
					};
				}
			});
			hives = Ext.Array.filter(hives, function(o) {
				return o !== undefined;
			});

			return hives;
		};

		return function(path, b_system, b_all) {

			path = path || "";

			if (!a_hives) {
				var responseText = ip2.sajax.request({
					url: "/ip2-services/webBios.aspx?func=getHives"
				});

				a_hives = Ext.decode(responseText);
				a_hives = a_hives.filter(function(o) {
					return o.filemanager;
				}).sort(function(a, b) {
					return a.alias.length - b.alias.length;
				});

				var _paths = {};

				a_hives.forEach(function(o) {

					o.parent = "$root$";

					for (var prop in _paths) {
						// prop = parent;
						// /abc is not parent of /abcdef
						// /abc is parent of /abc/def
						// /abc/ is parent of /abc/def
						if (o.alias.indexOf(prop) === 0 && (

							// If parent ends with / (eg. parent=/abc/, we=/abc/def)
							prop.slice(-1) == "/"

							// If we start with slash where parent ends (eg. parent=/abc, we=/abc/def)
							|| o.alias.slice(prop.length).charAt(0) == "/"
						)) {
							o.parent = prop;
						}
					}

					_paths[o.alias] = true;
				});
			}

			return b_all ? a_hives.slice() : resolve(path, b_system);
		};
	})(),

	getHiveByPath: function(s_path) {
		var i_self = this;
		var a_split = s_path.split("/");
		a_split = Ext.Array.filter(a_split, function(s_value) {
			return s_value !== "";
		});
		a_split.pop();
		var s_parent = a_split.join("/");
		var a_hives = i_self.getHives(s_parent, false, true).filter(function(o_hive) {
			return o_hive.alias == s_path
			|| "/" + o_hive.alias + "/" == s_path
			|| o_hive.alias + "/" == s_path
			|| "/" + o_hive.alias == s_path;
		});
		a_hives = Ext.Array.map(a_hives, function(o_hive) {
				if (o_hive.type == "system") {
					if (b_system) {
						return {
							path: "/" + o_hive.alias + "/",
							text: ip2.i18n(Ext.decode(o_hive.title)),
							isHive: true,
							hasChild: false,
							allowDrop: o_hive.allowDrop !== undefined ? Ext.decode(o_hive.allowDrop) : false,
							allowImport: o_hive.allowImport !== undefined ? Ext.decode(o_hive.allowImport) : false,
							allowAdd: o_hive.allowAdd !== undefined ? Ext.decode(o_hive.allowAdd) : false,
							iconCls: o_hive.iconCls || "",
							type: o_hive.type || "",
							saveUrl: o_hive.saveUrl !== undefined ? Ext.decode(o_hive.saveUrl) : false || true

						};
					}
				}
				else {
					return {
						path: "/" + o_hive.alias + "/",
						text: ip2.i18n(Ext.decode(o_hive.title)),
						isHive: true,
						hasChild: true,
						allowDrop: o_hive.allowDrop !== undefined ? Ext.decode(o_hive.allowDrop) : false,
						allowImport: o_hive.allowImport !== undefined ? Ext.decode(o_hive.allowImport) : false,
						allowAdd: o_hive.allowAdd !== undefined ? Ext.decode(o_hive.allowAdd) : false,
						iconCls: o_hive.iconCls || "",
						type: o_hive.type || "",
						saveUrl: o_hive.saveUrl !== undefined ? Ext.decode(o_hive.saveUrl) : false || true
					};
				}
			});
		a_hives = Ext.Array.filter(a_hives, function(o) {
			return o !== undefined;
		});
		return a_hives.length > 0 ? a_hives[0] : { saveUrl: true };
	},

	getImageInfo: function(a_records, f_callback) {
		var i_self = this;

		var a_batch = [];

		Ext.Array.each(a_records, function(o_record) {
			var filepath = o_record.get("FILPATH") + o_record.get("FILNAME");
			a_batch.push({
				type: "call",
				pgm: "imageIdentify",
				parms: {
					file: filepath
				}
			});
		});

		Ext.Ajax.request({
			url: "/ip2-services/ip2dmdProxy.aspx",
			timeout: "100000",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var a_batch = Ext.decode(o_response.responseText).batch;
				Ext.Array.each(a_batch, function(o_batch, n_index) {
					var width = o_batch.width || 0;
					var height = o_batch.height || 0;
					var size = o_batch.filesize || 0;
					a_records[n_index].set("FILWIDTH", width);
					a_records[n_index].set("FILHEIGHT", height);
					a_records[n_index].set("FILSIZE", size);
					a_records[n_index].set("FILMODIFY", ip2.date2dbDate(new Date()));
				});
				f_callback(a_records);
			}
		});
	},

	getUIConflickWindow: function(i_animateTarget, i_component, s_path, a_files, f_callback, use_handler) {

		var i_self = this;
		var i_el = i_component.bodyEl !== undefined ? i_component.bodyEl : i_component.getEl();
		var a_result = [];
		var b_usehandler = use_handler !== null ? use_handler : true;


		var i_window = Ext.widget("fileconflict", {
			files: a_files,
			animateTarget: i_animateTarget !== null ? i_animateTarget : "",
			path: s_path,
			width: 900,
			height: 600,
			okFn: function(a_override, a_rename) {

				var msg = "";
				var b_rename = false;
				var b_override = false;

				if (b_usehandler) {
					if (a_rename.length > 0) {

						b_rename = true;

						msg = a_rename.length > 1 ? ip2.i18n({
							da: "Opretter filer....",
							en: "Creating files..."
						}) : ip2.i18n({
							da: "Opretter file....",
							en: "Creating file..."
						});

						i_el.mask(msg);

						Ext.ux.file.util.Handler.createRecords(s_path, a_rename, true, function(a_records) {

							b_rename = false;

							Ext.Array.each(a_records, function(o_record) {
								a_result.push(o_record);
							});

							if (!b_override) {
								i_el.unmask();
								f_callback(false, a_result);
							}
						});
					}
					if (a_override.length > 0) {

						b_override = true;

						if (!b_rename) {

							msg = a_override.length > 1 ? ip2.i18n({
								da: "Overskriver filer....",
								en: "Overwriting files..."
							}) : ip2.i18n({
								da: "Overskriver file....",
								en: "Overwriting file..."
							});

							i_el.mask(msg);
						}

						var a_files = [];

						Ext.Array.each(a_override, function(o_overwrite) {
							a_files.push(o_overwrite.file);
						});

						Ext.ux.file.util.Handler.updateRecordsFileInfo(s_path, a_files, function(a_records) {
							b_override = false;
							Ext.Array.each(a_records, function(o_record) {
								a_result.push(o_record);
							});
							if (!b_rename) {
								i_el.unmask();
								f_callback(false, a_result);
							}
						});
					}
					if (a_override.length === 0 && a_rename.length === 0) {

						i_el.unmask();
						f_callback(false, a_result, false);
					}
				}
				else {
					i_el.unmask();
					f_callback(false, a_override, a_rename);
				}
			},
			cancelFn: function() {
				f_callback(true, a_result, []);
			}
		});
		i_window.show();
	},

	getUIGrid: function(o_config) {

		var i_selectionModel = Ext.create("Ext.selection.CheckboxModel", {
			mode: "MULTI",
			enableKeyNav: true
		});

		var o_gridConfig = {
			selModel: o_config.selMol !== undefined ? o_config.selMol : i_selectionModel,
			dmd: {
				path: "dmd/webshop.dmd",
				entityName: "WSHFILET00"
			},
			setPath: function(s_path) {

				var i_panel = this;
				var i_grid = i_panel.getGrid();
				var i_store = i_grid.getStore();
				var i_proxy = i_store.getProxy();
				var o_extraParams = i_proxy.getExtraParams();
				o_extraParams.where = "FILPATH like '" + path + "%'";
				i_store.currentPage = 1;
				i_store.load();
			}
		};

		Ext.apply(o_gridConfig, o_config);

		var i_panel = Ext.widget("ip2pagingGridOld", o_gridConfig);

		return i_panel;
	},

	getUITree: function(o_config) {

		var i_self = this;
		var path = o_config.path || "$root$";
		var b_system = o_config.useSystem !== undefined ? o_config.useSystem : true;
		var store = "";
		if (o_config.store) {
			store = o_config.store;
		}
		else {
			store = Ext.create("Ext.ux.file.store.TreeHive", {
				useSystem: b_system,
				root: {
					text: ip2.i18n({
						da: "...",
						en: "..."
					}),
					id: "/",
					path: path,
					expanded: false,
					selected: true,
					allowDrop: false
				}
			});
		}

		var i_tree = {
			layout: "fit",
			rootVisible: false,
			animate: false,
			useArrows: true,
			border: false,
			store: store,
			viewConfig: {
				loadMask: false
			},
			reload: function(node, reloadParent, select) {
				var i_tree = this;
				var i_store = i_tree.getStore();
				if (reloadParent) {
					if (node && node.parentNode) {
						var parent = node.parentNode;
						parent.removeAll(false);
						i_store.load({
							node: parent
						});
						if (select) {
							i_tree.getSelectionModel().select(parent);
						}
					}
				}
				else {
					if (node) {
						node.removeAll(false);
						i_store.load({
							node: node
						});
					}
				}
			}
		};

		Ext.Object.merge(i_tree, o_config);

		return Ext.widget("treepanel", i_tree);
	},

	getWindowSize: function () {

		var d = document;
		var root = d.documentElement;
		var body = d.body;
		var wid = window.innerWidth || root.clientWidth || body.clientWidth;
		var hi = window.innerHeight || root.clientHeight || body.clientHeight;

		var size = {
			width: wid,
			height: hi
		};

		return size;
	},

	/******
	    	@ path The path where to check if the files exist ex.  "/pp-static/images/..."
	   		@ a_files : Array of file object
	    	@ f_callback the function that will be called with the result of the check, returns {create : array, update : array}
	    *****/
	checkFiles: function(path, a_files, f_callback) {
		var a_batch = [];

		Ext.Array.each(a_files, function (o_file) {
			var s_path = ip2.cleanPath(path + "/" + o_file.name);
			if (!Ext.isNumber(o_file)) {
				a_batch.push({
					type: "call",
					pgm: "webbios",
					parms: {
						func: "checkstmf",
						file: s_path
					}
				});
			}
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {

				var o_json = Ext.decode(o_response.responseText, true);
				var a_create = [];
				var a_update = [];

				Ext.Array.each(o_json.batch, function (o_request, n_index) {
					var a_recepient = o_request.exists ? a_update : a_create;
					a_recepient.push(a_files[n_index]);
				});

				f_callback({
					update: a_update,
					create: a_create
				});
			}
		});
	},

	/******
    	@ path The path where to check if the files exist ex.  "/pp-static/images/"
   		@ a_records : Array of records of type file record
    	@ f_callback the function that will be called with the result of the check, returns {create : array, update : array}
    *****/

	checkRecords: function(path, a_records, f_callback) {
		var a_batch = [];

		Ext.Array.each(a_records, function (o_record) {
			if (!Ext.isNumber(o_record)) {
				a_batch.push({
					type: "call",
					pgm: "webbios",
					parms: {
						func: "checkstmf",
						file: ip2.cleanPath(path + "/" + o_record.get("FILNAME"))
					}
				});
			}
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {

				var o_json = Ext.decode(o_response.responseText, true);
				var a_create = [];
				var a_update = [];

				Ext.Array.each(o_json.batch, function (o_request, n_index) {
					var a_recepient = o_request.exists ? a_update : a_create;
					a_recepient.push(a_records[n_index]);
				});

				f_callback(a_create, a_update);
			}
		});
	},

	validateSuggestions: function(a_records, s_path, callback) {
		var i_self = this;
		var a_batch = [];

		Ext.Array.each(a_records, function(o_file) {
			a_batch.push({
				type: "call",
				pgm: "webbios",
				parms: {
					func: "checkstmf",
					file: s_path + "/" + o_file.suggestedName
				}
			});
		});

		Ext.Ajax.request({
			url: "/ip2-services/ip2dmdProxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var a_batch = Ext.decode(o_response.responseText).batch;
				var a_invalid = [];
				Ext.Array.each(a_batch, function(o_batch, n_index) {
					if (o_batch.exists) {
						a_invalid.push(a_records[n_index]);
					}
				});
				callback(a_invalid);
			}
		});
	},

	getSuggestions: function(a_files, s_path, f_callback) {
		var i_self = this;
		var a_batch = [];

		Ext.Array.each(a_files, function(o_file) {
			var b_external = o_file.external ? o_file.external : false;
			a_batch.push({
				type: "call",
				pgm: b_external ? "wshFilNamSuggest" : "wshgetsuggestedname",
				parms: {
					file: o_file.name,
					dir: s_path
				}
			});
		});

		Ext.Ajax.request({
			url: "/ip2-services/ip2dmdProxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var a_batch = Ext.decode(o_response.responseText).batch;
				var a_records = [];
				Ext.Array.each(a_batch, function(o_batch, n_index) {
					var o_record = {
						suggestion: o_batch.suggestedName
					};
					a_records.push(o_record);
				});

				f_callback(a_records);
			}
		});
	},

	deleteDirectory: function(path, f_callback) {
		var i_self = this;
		Ext.Ajax.request({
			url: "/ip2-Services/webbios.aspx",
			params: {
				func: "rmdir",
				name: ip2.cleanPath(path)
			},
			success: function(o_response) {
				var o_result = Ext.decode(o_response.responseText);
				f_callback(o_result.success);
			}
		});
	},

	deleteFiles: function(a_files, f_callback) {
		var a_batch = [];
		Ext.Array.each(a_files, function(o_file) {
			a_batch.push({
				type: "call",
				pgm: "webbios",
				parms: {
					func: "unlink",
					name: o_file.path
				}
			});
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				f_callback();
			}
		});
	},

	unlinkRecords: function(a_records, f_callback) {
		var i_self = this;
		var a_batch = [];
		Ext.Array.each(a_records, function(o_record) {
			if (!Ext.isNumber(o_record)) {
				a_batch.push({
					type: "call",
					pgm: "webbios",
					parms: {
						func: "unlink",
						name: o_record.get("FILPATH") + o_record.get("FILNAME")
					}
				});
			}
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				f_callback();
			}
		});
	},

	deleteRecords: function(a_records, f_callback) {
		var i_self = this;
		var a_batch = [];
		var Model = i_self.getModel();

		Ext.Array.each(a_records, function (o_record) {

			if (!Ext.isNumber(o_record)) {

				var o_key = {};

				o_key[Model.idProperty] = o_record.get("FILFILTKN");

				a_batch.push({
					type: "delete",
					dmd: "dmd/webshop.dmd",
					entity: "WSHFILET00",
					key: o_key
				});
			}
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				i_self.unlinkRecords(a_records, function() {
					f_callback(true);
				});
			}
		});
	},

	createDirectory: function(path, f_callback) {
		var i_self = this;
		Ext.Ajax.request({
			url: "/ip2-Services/webbios.aspx",
			params: {
				func: "mkdir",
				name: path
			},
			success: function(o_response) {
				var o_result = Ext.decode(o_response.responseText);
				f_callback(o_result.success);
			}
		});
	},

	createModel: function() {

		var i_self = this;
		var Model = i_self.getModel();

		var i_record = Model.create({
			FILPATH: "",
			FILORIPATH: "",
			FILCRTBY: ip2.navigator.user.id,
			FILNAME: "",
			FILMEDIA: "",
			FILCREATE: ip2.date2dbDate(new Date()),
			FILMODIFY: ip2.date2dbDate(new Date()),
			FILEXT: "",
			FILEXTERNAL: false
		});

		return i_record;
	},

	/**
	 * Used for testing purposes only
	 */
	createFakeRecords: function(seed) {

		var i_self = this;
		var Model = i_self.getModel();
		var a_records = [];

		for (var i = 1; i <= seed; i++) {

			var i_record = Model.create({
				FILFILTKN: i,
				FILPATH: "",
				FILORIPATH: "",
				FILCRTBY: ip2.navigator.user.id,
				FILNAME: "",
				FILMEDIA: "",
				FILCREATE: ip2.date2dbDate(new Date()),
				FILMODIFY: ip2.date2dbDate(new Date()),
				FILEXT: "",
				FILEXTERNAL: false
			});

			a_records.push(i_record);
		}

		return a_records;
	},

	createRecords: function(path, a_files, b_rename, f_callback) {

		var i_self = this;
		var Model = i_self.getModel();

		i_self.uploadFiles(path, a_files, b_rename, function(a_files) {
			path = ip2.cleanPath(path) + "/";
			var a_records = [];

			Ext.Array.each(a_files, function(o_file) {

				var s_extension = o_file.name.split(".").pop();
				s_extension = s_extension.toLowerCase();

				var i_record = Model.create({
					FILPATH: path,
					FILORIPATH: path + o_file.name,
					FILCRTBY: ip2.navigator.user.id,
					FILNAME: o_file.name,
					FILMEDIA: o_file.name,
					FILCREATE: ip2.date2dbDate(new Date()),
					FILMODIFY: ip2.date2dbDate(new Date()),
					FILEXT: s_extension,
					FILEXTERNAL: false
				});

				a_records.push(i_record);
			});

			i_self.getImageInfo(a_records, function(a_records) {
				i_self.upsertRecords(a_records, function(a_records) {
					f_callback(a_records);
				});
			});
		});
	},

	createRecordByUrlWithName: function(s_path, s_url, s_name, f_callback) {
		var i_self = this;
		var a_batch = [];
		a_batch.push({
			type: "call",
			pgm: "webbios",
			parms: {
				func: "httpRequest",
				parms: {
					request: {
						url: s_url,
						metode: "GET"
					},
					response: {
						outputFile: s_path + s_name
					}
				}
			}
		});
		Ext.Ajax.request({
			url: "/ip2-services/ip2dmdproxy.aspx?",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var o_batch = o_result.batch[0];
				if (o_batch.success) {

					var a_files = [{
						name: s_name
					}];

					i_self.createRecordsNoUpload(s_path, a_files, function(a_records) {
						Ext.Array.each(a_records, function(o_record) {
							o_record.set("FILORIPATH", s_url);
						});
						i_self.upsertRecords(a_records, function(a_records) {
							f_callback(a_records);
						});
					});
				}
			}
		});
	},

	createRecordByUrl: function(s_path, s_url, f_callback) {
		var i_self = this;
		var s_name = s_url.split("/").pop();
		var a_batch = [];
		a_batch.push({
			type: "call",
			pgm: "webbios",
			parms: {
				func: "httpRequest",
				parms: {
					request: {
						url: s_url,
						metode: "GET"
					},
					response: {
						outputFile: s_path + s_name
					}
				}
			}
		});
		Ext.Ajax.request({
			url: "/ip2-services/ip2dmdproxy.aspx?",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var o_batch = o_result.batch[0];
				if (o_batch.success) {

					var a_files = [{
						name: s_name
					}];

					i_self.createRecordsNoUpload(s_path, a_files, function(a_records) {
						Ext.Array.each(a_records, function(o_record) {
							o_record.set("FILORIPATH", s_url);
						});
						i_self.upsertRecords(a_records, function(a_records) {
							f_callback(a_records);
						});
					});
				}
			}
		});
	},

	createRecordsNoUpload: function(path, a_files, f_callback) {

		var i_self = this;
		var Model = i_self.getModel();
		var a_records = [];

		Ext.Array.each(a_files, function(o_file) {

			var s_extension = o_file.name.split(".").pop();
			s_extension = s_extension.toLowerCase();

			var i_record = Model.create({
				FILPATH: path,
				FILORIPATH: path + o_file.name,
				FILCRTBY: ip2.navigator.user.id,
				FILNAME: o_file.name,
				FILMEDIA: o_file.name,
				FILCREATE: ip2.date2dbDate(new Date()),
				FILMODIFY: ip2.date2dbDate(new Date()),
				FILEXT: s_extension,
				FILEXTERNAL: o_file.external || false
			});
			a_records.push(i_record);
		});

		i_self.getImageInfo(a_records, function(a_records) {
			f_callback(a_records);
		});
	},

	createRecordsNoUploadNoImageInfo: function(path, a_files, f_callback) {

		var i_self = this;
		var Model = i_self.getModel();
		var a_records = [];
		var index = 1;

		Ext.Array.each(a_files, function(o_file) {

			var s_extension = o_file.name.split(".").pop();
			s_extension = s_extension.toLowerCase();

			var i_record = Model.create({
				FILFILTKN: index,
				FILPATH: path,
				FILORIPATH: path + o_file.name,
				FILNAME: o_file.name,
				FILMEDIA: o_file.name,
				FILCREATE: ip2.date2dbDate(new Date()),
				FILMODIFY: ip2.date2dbDate(new Date()),
				FILEXT: s_extension,
				FILSIZE: o_file.size,
				FILEXTERNAL: o_file.external || false
			});

			a_records.push(i_record);

			index++;
		});

		f_callback(a_records);
	},

	createRecordsNoUploadNoImageInfoNoIndex: function(path, a_files, f_callback) {

		var i_self = this;
		var Model = i_self.getModel();
		var a_records = [];

		Ext.Array.each(a_files, function(o_file) {

			var s_extension = o_file.name.split(".").pop();
			s_extension = s_extension.toLowerCase();

			var i_record = Model.create({
				FILPATH: path,
				FILORIPATH: path + o_file.name,
				FILNAME: o_file.name,
				FILMEDIA: o_file.name,
				FILCREATE: ip2.date2dbDate(new Date()),
				FILMODIFY: ip2.date2dbDate(new Date()),
				FILEXT: s_extension,
				FILSIZE: o_file.size,
				FILEXTERNAL: o_file.external || false
			});

			a_records.push(i_record);
		});

		f_callback(a_records);
	},

	createRecordTemporary: function(path, o_file, f_callback) {
		var i_self = this;
		var Model = i_self.getModel();
		var a_records = [];
		i_self.uploadToTemp(o_file, function(o_result) {
			var name = o_result.name;
			var o_record = Model.create({
				FILPATH: o_result.tmpPath,
				FILORIPATH: path + o_file.name,
				FILCRTBY: ip2.navigator.user.id,
				FILNAME: o_result.tmpName,
				FILMEDIA: o_result.name,
				FILCREATE: ip2.date2dbDate(new Date()),
				FILMODIFY: ip2.date2dbDate(new Date()),
				FILEXT: o_result.extension,
				FILEXTERNAL: false
			});
			o_record.uploadname = o_result.uploadname;
			a_records.push(o_record);
			i_self.getImageInfo(a_records, function(a_records) {
				var o_record = a_records[0];
				delete o_record.extension;
				delete o_record.tmpPath;
				delete o_record.tmpName;
				o_record.set("FILNAME", name);
				o_record.set("FILPATH", path);
				f_callback(o_record);
			});
		});
	},

	createTags: function(a_records, s_tags, f_callback) {
		var i_self = this;
		Ext.Array.each(a_records, function(o_record) {
			o_record.set("FILTAG", s_tags);
		});

		i_self.upsertRecords(a_records, function(a_records) {
			f_callback(a_records);
		});
	},

	curlFileFromURL: function(s_path, s_url, f_callback) {
		var i_self = this;
		var s_name = s_url.split("/").pop();
		var a_batch = [];
		a_batch.push({
			type: "call",
			pgm: "webbios",
			parms: {
				func: "httpRequest",
				parms: {
					request: {
						url: s_url,
						metode: "GET"
					},
					response: {
						outputFile: s_path + s_name
					}
				}
			}
		});
		Ext.Ajax.request({
			url: "/ip2-services/ip2dmdproxy.aspx?",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var o_batch = o_result.batch[0];
				if (o_batch.success) {
					f_callback();
				}
			}
		});
	},

	curlFileFromURLWithName: function(s_path, s_url, s_name, f_callback) {
		var i_self = this;
		var a_batch = [];
		a_batch.push({
			type: "call",
			pgm: "webbios",
			parms: {
				func: "httpRequest",
				parms: {
					request: {
						url: s_url,
						metode: "GET"
					},
					response: {
						outputFile: s_path + s_name
					}
				}
			}
		});
		Ext.Ajax.request({
			url: "/ip2-services/ip2dmdproxy.aspx?",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				var o_batch = o_result.batch[0];
				if (o_batch.success) {
					f_callback();
				}
			}
		});
	},

	consulidateDirectory: function(path, f_callback) {
		var i_self = this;
		var a_new_records = [];
		var a_delete = [];
		i_self.getRecordsByPath(path, function(a_records) {
			i_self.getFilesByPath(path, function(a_files) {
				Ext.Array.each(a_records, function(i_record) {
					var b_found = false;
					Ext.Array.each(a_files, function(o_file) {
						var s_key = i_record.get("FILPATH") + i_record.get("FILNAME");
						if (s_key == (path + o_file.text)) {
							b_found = true;
							return false;
						}
					});
					if (!b_found) {
						a_delete.push(i_record);
					}
				});
				Ext.Array.each(a_files, function(o_file) {
					var b_found = false;
					Ext.Array.each(a_records, function(i_record) {
						var s_key = i_record.get("FILPATH") + i_record.get("FILNAME");
						if (s_key == (path + o_file.text)) {
							b_found = true;
							return false;
						}
					});
					if (!b_found) {
						var o_record = {
							name: o_file.text
						};
						a_new_records.push(o_record);
					}
				});
				if (a_new_records.length > 0) {
					i_self.createRecordsNoUploadNoImageInfoNoIndex(path, a_new_records, function(a_records) {
						if (a_delete.length > 0) {
							i_self.deleteRecords(a_delete, function(a_result) {
								f_callback(a_records, a_delete);
							});
						}
						else {
							f_callback(a_records, a_delete);
						}
					});
				}
				else {
					if (a_delete.length > 0) {
						i_self.deleteRecords(a_delete, function(a_result) {
							f_callback(a_new_records, a_delete);
						});
					}
					else {
						f_callback(a_new_records, a_delete);
					}
				}
			});
		});
	},

	hasFileManager: function() {

		var i_self = this;

		var o_dmd = ip2.resource.get("dmd/webshop.dmd");
		var o_model = o_dmd.model;
		var a_entities = o_model.entities;
		var b_result = false;

		var o_search = Ext.Array.findBy(a_entities, function(o_value) {
			return o_value.name == "WSHFILET00";
		});

		if (o_search) {
			b_result = true;
		}

		return b_result;
	},

	upsertRecords: function(a_records, f_callback) {
		var i_self = this;
		var a_batch = [];

		Ext.Array.each(a_records, function (o_record) {
			if (!Ext.isNumber(o_record)) {
				var key = {};
				key[o_record.idProperty] = o_record.get(o_record.idProperty);
				a_batch.push({
					type: "upsert",
					dmd: "dmd/webshop.dmd",
					entity: "WSHFILET00",
					key: key,
					row: o_record.data
				});
			}
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				var o_result = Ext.decode(o_response.responseText);
				Ext.Array.each(o_result.batch, function(o_batch, n_index) {
					Ext.Array.each(o_batch.row, function(value) {
						a_records[n_index].set("FILFILTKN", value);
					});
				});
				f_callback(a_records);
			}
		});
	},

	updateRecordsFileInfo: function(path, a_files, f_callback) {
		var i_self = this;
		i_self.uploadFiles(path, a_files, false, function(a_files) {
			var a_names = [];
			Ext.Array.each(a_files, function(o_file) {
				a_names.push(o_file.name);
			});
			i_self.getRecordsByName(path, a_names, function(a_records) {
				i_self.getImageInfo(a_records, function(a_records) {
					i_self.upsertRecords(a_records, function(a_records) {
						f_callback(a_records);
					});
				});
			});
		});
	},

	uploadFiles: function(s_path, a_files, b_rename, f_callback) {

		var i_self = this;

		var i_formData = new FormData();
		var i_xhr = new XMLHttpRequest();
		var a_records = [];

		i_self.processFiles(a_files, function(a_processed) {

			Ext.Array.each(a_processed, function(o_record) {

				var s_url;

				if (!b_rename) {
					s_url = ip2.cleanPath([s_path, o_record.name].join("/"));
					if (o_record.file) {
						i_formData.append(s_url, o_record.file, o_record.name);
					}
					else {
						i_formData.append(s_url, o_record);
					}
					a_records.push(o_record);
				}
				else {
					s_url = ip2.cleanPath([s_path, o_record.suggestedName].join("/"));
					i_formData.append(s_url, o_record.file, o_record.name);
					a_records.push({ name: o_record.suggestedName });
				}
			});

			i_xhr.onreadystatechange = function () {

				var a_data = [];
				var a_fail = [];

				if (i_xhr.readyState == 4 && i_xhr.status == 200) {
					var a_result;

					try {
						a_result = Ext.decode(i_xhr.responseText, true);
						f_callback(a_records);
					}
					catch (err) {
						f_callback([]);
					}
				}
			};

			i_xhr.open("POST", "ip2-services/webbios.aspx?action=movestmf", true);
			i_xhr.send(i_formData);
		});
	},

	uploadToTemp: function(o_file, f_callback) {
		var i_self = this;
		var i_formData = new FormData();
		var i_xhr = new XMLHttpRequest();

		var extension = o_file.name.split(".").pop().toLowerCase();
		var s_uploadname = "_upload" + ip2.getDcTimestamp() + "." + extension;
		var s_preset = ip2.preset.staticPath || "pp-static";

		var filepath = ip2.cleanPath(s_preset + "/" + s_uploadname);
		i_formData.append(filepath, o_file);

		i_xhr.onreadystatechange = function () {

			if (i_xhr.readyState == 4 && i_xhr.status == 200) {
				var o_result;

				try {
					o_result = Ext.decode(i_xhr.responseText, true);
				}
				catch (err) {}

				if (o_result) {
					o_result.name = o_file.name;
					o_result.extension = extension;
					o_result.uploadname = filepath;
					o_result.tmpName = s_uploadname;
					o_result.tmpPath = ip2.cleanPath(s_preset) + "/";
					f_callback(o_result);
				}
			}
		};

		i_xhr.open("POST", "ip2-services/webbios.aspx?action=movestmf", true);
		i_xhr.send(i_formData);
	},

	moveAndDeleteOldRecords: function(toPath, a_move, f_callback) {
		var i_self = this;
		var a_names = [];
		Ext.Array.each(a_move, function(o_record) {
			a_names.push(o_record.get("FILNAME"));
		});
		i_self.getRecordsByName(toPath, a_names, function(a_records) {
			i_self.deleteRecords(a_records, function(success) {
				i_self.moveRecords(toPath, a_move, function(a_result) {
					f_callback(a_result);
				});
			});
		});
	},

	moveFromRecords: function(fromPath, a_records, f_callback) {
		var i_self = this;
		var a_batch = [];

		Ext.Array.each(a_records, function (o_record) {
			if (!Ext.isNumber(o_record)) {
				a_batch.push({
					type: "call",
					pgm: "webbios",
					parms: {
						func: "rename",
						from: fromPath,
						to: o_record.get("FILPATH") + o_record.get("FILMEDIA"),
						replace: true
					}
				});
			}
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				Ext.Array.each(a_records, function(o_record) {
					o_record.set("FILFILIA", o_record.get("FILNAME"));
				});
				f_callback(a_records);
			}
		});
	},

	moveRecords: function(toPath, a_records, f_callback) {
		var i_self = this;
		var a_batch = [];

		Ext.Array.each(a_records, function (o_record) {
			if (!Ext.isNumber(o_record)) {
				a_batch.push({
					type: "call",
					pgm: "webbios",
					parms: {
						func: "rename",
						from: o_record.get("FILPATH") + o_record.get("FILMEDIA"),
						to: toPath + o_record.get("FILNAME"),
						replace: true
					}
				});
			}
		});

		Ext.Ajax.request({
			url: "/ip2-Services/ip2dmdproxy.aspx",
			jsonData: {
				batch: a_batch
			},
			success: function (o_response) {
				Ext.Array.each(a_records, function(o_record) {
					o_record.set("FILPATH", toPath);
					o_record.set("FILMEDIA", o_record.get("FILNAME"));
				});
				i_self.upsertRecords(a_records, function(a_records) {
					f_callback(a_records);
				});
			}
		});
	},

	processFiles: function(a_files, f_callback) {

		var i_self = this;

		f_callback = f_callback || Ext.emptyFn;

		var a_result = [];

		var n_count = a_files.length;

		var n_width = 600;

		Ext.Array.each(a_files, function(o_record) {

			var i_file = o_record.file || o_record;
			var s_extension = i_file.name.split(".").pop();

			if (Ext.Array.contains(i_self.imageExtension, s_extension)) {

				var i_fileReader = new FileReader();

				i_fileReader.onload = function () {

					var i_image = new Image();
					i_image.src = i_fileReader.result;

					i_image.onload = function () {

						var i_canvas = document.createElement("canvas");
						var i_context = i_canvas.getContext("2d");
						var i_outCanvas = document.createElement("canvas");
						var i_outContext = i_outCanvas.getContext("2d");

						if (i_image.width > n_width) {
							i_canvas.width = n_width; // destination canvas size
							i_canvas.height = i_canvas.width * i_image.height / i_image.width;

							var cur = {
								width: Math.floor(i_image.width * 0.5),
								height: Math.floor(i_image.height * 0.5)
							};

							i_outCanvas.width = cur.width;
							i_outCanvas.height = cur.height;

							i_outContext.drawImage(i_image, 0, 0, cur.width, cur.height);

							while (cur.width * 0.5 > n_width) {
								cur = {
									width: Math.floor(cur.width * 0.5),
									height: Math.floor(cur.height * 0.5)
								};
								i_outContext.drawImage(i_outCanvas, 0, 0, cur.width * 2, cur.height * 2, 0, 0, cur.width, cur.height);
							}

							i_context.drawImage(i_outCanvas, 0, 0, cur.width, cur.height, 0, 0, i_canvas.width, i_canvas.height);

							var s_name = i_file.name || "";

							if (Ext.browser.is.IE) {

								n_count--;

								var i_blob = i_canvas.msToBlob();
								i_blob.name = i_file.name;

								var i_newFile = {
									file: i_blob,
									name: s_name,
									type: i_file.type
								};

								a_result.push(i_newFile);

								if (n_count === 0) {

									f_callback(a_result);
								}
							}
							else {
								i_canvas.toBlob(function (i_blob) {

									n_count--;
									i_blob.name = i_file.name;

									var i_newFile = {
										file: i_blob,
										name: s_name,
										type: i_file.type
									};

									a_result.push(i_newFile);

									if (n_count === 0) {
										f_callback(a_result);
									}
								});
							}
						}
						else {
							a_result.push(i_file);
						}
					};
				};

				i_fileReader.readAsDataURL(i_file);
			}
			else {

				n_count--;

				a_result.push(i_file);

				if (n_count === 0) {
					f_callback(a_result);
				}
			}
		});
	}

});
