/**
* MLJLib
* MeshLabJS Library
*
* Copyright(C) 2015
* Paolo Cignoni
* Visual Computing Lab
* ISTI - CNR
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See theGNU General Public License
* (http://www.gnu.org/licenses/gpl.txt) for more details.
*
*/
/**
* @file Defines MLJ.util namespace and AssociativeArray class
* @author Stefano Gabriele
*/
/**
* MLJ.util namespace
* @namespace MLJ.util
* @author Stefano Gabriele
*/
MLJ.util = {};
MLJ.util.loadFile = function (path, callback) {
if (!jQuery.isFunction(callback)) {
console.warn("The callback paramter must be a funciton.");
}
var tmpArray = [];
if (jQuery.isArray(path)) {
tmpArray = path;
} else {
tmpArray.push(path);
}
var results = new MLJ.util.AssociativeArray();
function _load(path, _callback) {
var fileName = path.substring(path.lastIndexOf('/')+1);
$.ajax({
url: path,
error: function (xhr, textStatus, errorThrown) {
var msg = "An error occurred. Status code: ";
console.warn(msg + xhr.status + ". Status text: " + textStatus);
results.set(fileName,"");
},
success: function (data) {
results.set(fileName,data);
_callback(data);
}
});
}
var i = 0;
function _loadNextFile() {
_load(tmpArray[i], function () {
i++;
if (i === tmpArray.length) {
callback(results);
return;
} else {
_loadNextFile();
}
});
}
_loadNextFile();
};
/**
* Returns an the value of a parameter specified in the URL
* something like http://www.meshlabjs.net/?filterName=Create%20Sphere
*
* @param {name} The name of the parameter to be retrieve
* @returns {Array} The string with the value of that parameter.
* Strings are URI decoded, so you can put %20 inside to specify a 'space'
* Returns an empty string if param with that name is found.
* It is used to specify name of a filter at startup;
*/
MLJ.util.getURLParam = function(name) {
name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
results = regex.exec(location.search);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
/**
* Returns an array without duplicates
* @param {type} array The array to be cleaned
* @returns {Array} The array without duplicates
*/
MLJ.util.arrayUnique = function (array) {
var a = array.concat();
for (var i = 0; i < a.length; ++i) {
for (var j = i + 1; j < a.length; ++j) {
if (a[i] === a[j])
a.splice(j--, 1);
}
}
return a;
};
/**
* @class Create an Associative array
* @memberOf MLJ.util
* @author Stefano Gabriele
* @example <caption>Usage example:</caption>
* var aa = new MLJ.util.AssociativeArray();
* aa.set("key1", obj1);
* aa.set("key2", obj2);
* var iter = aa.iterator();
* var obj;
* while(iter.hasNext()) {
* obj = iter.next();
* //do something with obj
* }
*/
MLJ.util.AssociativeArray = function () {
//Contains the keys (key = keys[0 ... _length-1])
var keys = [];
//Associative arrays (value = values[key]);
var values = [];
/**
* @class Create a new _Iterator
* @private
* @author Stefano Gabriele
*/
var _Iterator = function () {
var _ind = 0;
/**
* Returns true if the iteration has more elements
* @returns {Boolean} <code>true</code> if the iteration has more elements,
* <code>false</code> otherwise
*/
this.hasNext = function () {
return _ind < keys.length;
};
/**
* Returns the next element in the iteration
* @returns {Object} the next element in the iteration
*/
this.next = function () {
var next = values[keys[_ind]];
_ind++;
return next;
};
};
/**
* Returns the last inserted value of this associative array or
* <code>null</code> if the array is empty
* @returns the last inserted value or <code>null</code> if the array is empty
* @author Stefano Gabriele
*/
this.getLast = function() {
if(this.size() === 0)
return null;
return values[keys[0]];
};
/**
* Returns the first inserted value of this associative array or
* <code>null</code> if the array is empty
* @returns the first inserted value or <code>null</code> if the array is empty
* @author Stefano Gabriele
*/
this.getFirst = function() {
if(this.size() === 0)
return null;
return values[keys[keys.length - 1]];
};
/**
* Returns the value to which the specified key is mapped, or
* <code>undefined</code> if this array contains no mapping for the key
* @param {string} key the key whose associated value is to be returned
* @returns the value to which the specified key is mapped, or
* <code>undefined</code> if this array contains no mapping for the key
* @author Stefano Gabriele
*/
this.getByKey = function (key) {
return values[key];
};
/**
* Returns the number of elements in this array
* @returns {Integer} The number of elements in this array
* @author Stefano Gabriele
*/
this.size = function () {
return keys.length;
};
/**
* Inserts an element in this associative array. Note that if the array
* previously contained a mapping for the key, the old value is replaced
* @param {String} key The key with which the specified value is to be associated
* @param {Object} value The value to be associated with the specified key
* @author Stefano Gabriele
*/
this.set = function (key, value) {
//if key not exists
if (!values[key]) {
keys.push(key);
}
//Note that if key aleady exists, the new entry wll override the old
values[key] = value;
};
/**
* Removes an element from this associative array
* @param {String} key The key whose mapping is to be removed from the array
* @returns {Object} The removed element if the array contains a mapping for
* the key, <code>null</code> otherwise
*/
this.remove = function (key) {
var element = values[key];
delete values[key];
for (var i = 0, m = keys.length; i < m; i++) {
if (keys[i] === key) {
keys.splice(i, 1);
//we have finished
return element;
}
}
return null;
};
/**
* Returns an iterator over the elements in this array
* @returns {MLJ.util.AssociativeArray._Iterator}
*/
this.iterator = function () {
return new _Iterator();
};
/**
* Sorts the items of the <code>AssociativeArray</code> rearranging its keys
* in ascending (default) or descending order.
* @param {String} order The sort order: ascending (<code>up</code>) or
* descending (<code>down</code>)
* @author Stefano Gabriele
*/
this.sortByKey = function(order) {
keys.sort();
if(order === "down") {
keys.reverse();
}
};
};