VAR = {};

VAR.whitespaceCharacters = " \t\n\r";

VAR.isUndefined = function(property) {
  return (typeof property == 'undefined');
}

VAR.isEmpty = function(s) {
    return ((s == null) || (s.length == 0))
}

VAR.isNumber = function(s, min, max) {
    var n;
    n = Number(s);
    if ((!VAR.isWhitespace(s)) && !isNaN(n) && (VAR.isUndefined(min) || (n >= min)) && (VAR.isUndefined(max) || (n <= max))) {
        return true;
    } else {
        return false;
    }
}

VAR.isWhitespace = function(s) {
    var i;
    // Is s empty?
    if (s == '') {
        return true;
    }
    // Search through string's characters one by one
    // until we find a non-whitespace character.
    // When we do, return false; if we don't, return true.
    for (i = 0; i < s.length; i++) {
        // Check that current character isn't whitespace.
        var c = s.charAt(i);
        if (VAR.whitespaceCharacters.indexOf(c) == -1) {
            return false;
        }
    }
    // All characters are whitespace.
    return true;
}

VAR.isEmail = function(s, canBeEmpty) {
    if (canBeEmpty == null) {
        canBeEmpty = false;
    }

    if (s == '') {
        return canBeEmpty ? true : false;
    }
    
    // is s whitespace?
    if (VAR.isWhitespace(s)) {
        return canBeEmpty ? true : false;
    }
    
    // checking for separators (, or ;)
    var addresses = s.split(/[;,]/);
    if (addresses) {
        for(i = 0; i < addresses.length; i++) {
            if (this.validateEmail(addresses[i])) {
                continue;
            } else {
                return false;
            }
        }
        return true;
    } else {
        return this.validateEmail(s);
    }
}

VAR.validateEmail = function(s)
{
    // there must be >= 1 character before @, so we
    // start looking at character position 1
    // (i.e. second character)
    var i = 1;
    var sLength = s.length;
    
    // look for @
    while ((i < sLength) && (s.charAt(i) != "@")) {
        i++
    }
    
    if ((i >= sLength) || (s.charAt(i) != "@")) {
        return false;
    } else {
        i += 2;
    }
    
    // look for .
    while ((i < sLength) && (s.charAt(i) != ".")) {
        i++
    }
    
    // there must be at least one character after the .
    if ((i >= sLength - 1) || (s.charAt(i) != ".")) {
        return false;
    } else {
        return true;
    }
}

VAR.isArray = function(a) {
    return typeof a == 'object' && a.constructor == Array;
}

VAR.removeWhitespace = function(s) {
    var i, s2;
    for (i=0; i<s.length; i++) {
        var c = s.charAt(i);
        if (VAR.whitespaceCharacters.indexOf(c) == -1) {
            break;
        }
    }
    
    s=s.substr(i);
    
    for (i=s.length; i>0; i--) {
        var c = s.charAt(i);
        if (VAR.whitespaceCharacters.indexOf(c) == -1) {
            break;
        }
    }
    
    s = s.substr(0, i+1);
    return s;
}

VAR.addWord = function(str, word) {
    if (VAR.hasWord(str, word)) {
        return str;
    } else {
        return str + ' ' + word;
    }
}

VAR.splitBySpaces = function(str) {
    var words = [];
    var start = 0, end;
    while (true) {
        end = str.indexOf(' ', start);
        if (end != -1) {
            if (end > start) {
                words.push(str.substring(start, end));
            }
            start = end + 1;
        } else {
            if (str.length > start) {
                words.push(str.substring(start));
            }
            return words;
        }
    }
}

VAR.removeWord = function(str, word) {
    var list, i, str2 = '', c = 0;
    list = VAR.splitBySpaces(str);
    for (i = 0; i < list.length; i++) {
        if (list[i] != word) {
            if (c) {
                str2 += ' ';
            }
            str2 += list[i];
            c++;
        }
    }
    return str2;
}

VAR.cutText = function(str, maxLength)
{
    if (str.length > maxLength)
        return str.substr(0, maxLength) + '...';
    else
        return str;
}

VAR.hasWord = function(str, word) {
    var words = [];
    var start = 0, end;
    while (true) {
        end = str.indexOf(' ', start);
        if (end != -1) {
            if (end > start) {
                if (word == str.substring(start, end)) {
                    return true;
                }
            }
            start = end + 1;
        } else {
            if (str.length > start) {
                if (word == str.substring(start)) {
                    return true;
                }
            }
            return false;
        }
    }
}

VAR.endsWith = function(complete_string, part) {
    var pos = complete_string.length - part.length;
    if (complete_string.substr(pos) == part) {
        return complete_string.substr(0, pos);
    } else {
        return false;
    }
}

VAR.startsWith = function(complete_string, part) {
    if (complete_string.substr(0, part.length) == part) {
        return complete_string.substr(part.length);
    } else {
        return false;
    }
}

// Gets the index of an element of an array or false if it doesn't exist
VAR.indexOf = function(arr, item) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] == item) {
            return i;
        }
    }
    return -1;
}

// Removes an element from an array (it returns true if the element was there)
VAR.remove = function(arr, item) {
    var index = VAR.indexOf(arr, item);
    if (index == -1) {
        return false;
    } else {
        arr.splice(index, 1);
        return true;
    }
}

// Ensures an element is present on an array depending on the "contains" argument
//  if contains == true it returns the index of the item, otherwise it returns false
VAR.setContains = function(arr, item, contains) {
    var index = VAR.indexOf(arr, item);
    var isContained = index != -1;
    if (isContained == contains) {
        return index;
    }
    if (contains) {
        arr.push(item);
        return arr.length - 1;
    } else {
        VAR.remove(arr, item);
        return false;
    }
}

// Makes a copy of an object, recursively (if its elements are arrays or objects,
//  they will be copied)
VAR.clone = function(variable) {
    if (typeof variable != 'object') {
        return variable;
    }
    var item, out;
    if (VAR.isArray(variable)) {
        out = [];
    } else {
        out = {};
    }
    for (item in variable) {
        out[item] = VAR.clone(variable[item])
    }
    return out;
}

VAR.shallowClone = function(obj) {
    var item, out;
    if (obj.constructor == Array) {
        out = [];
    } else {
        out = {};
    }
    for (item in obj) {
        out[item] = obj[item];
    }
    return out;
}

VAR.getKeys = function(object) {
    var keys = [];
    for (var item in object) {
        keys.push(item);
    }
    return keys;
}

VAR.filter = function(func, list) {
    var newList = [];
    for (var i = 0; i < list.length; ++i) {
        if (func(list[i])) {
            newList.push(list[i]);
        }
    }
    return newList;
}

VAR.getFileNameFromUrl = function(url) {
    var start = url.lastIndexOf('/');
    if (start == -1) {
        return url;
    }
    var end = url.indexOf('?', start);
    if (end == -1) {
        return url.substring(start + 1);
    }
    return url.substring(start + 1, end);
}

VAR.forEach = function(list, callback) {
    for (var i = 0; i < list.length; ++i) {
        callback(list[i]);
    }
}

VAR.removeAccents = function(text) {
    var accented = 'ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÑÒÓÔÕÖØÙÚÛÜÝàáâãäåçèéêëìíîïñòóôõöøùúûüýÿ';
    var notAccented = 'SZszYAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy';
    var out = "", chr, indexOf;
    for(var i = 0; i < text.length; i++) {
        var chr = text.charAt(i);
        indexOf = accented.indexOf(chr);
        if (indexOf != -1) {
            out += notAccented[indexOf];
        } else {
            out += chr;
        }
    }
    return out;
}

VAR.getPathHeadAndTail = function(path) {
    var index = path.indexOf('/');
    if (index == -1) {
        return [path, ''];
    } else {
        return [path.substr(0, index), path.substr(index + 1)];
    }
}

VAR.createCaller = function(object, methodName, params) {
    var f;
    if (params) {
        f = function() {
            return object[methodName].apply(object, params);
        }
    } else {
        f = function() {
            return object[methodName].apply(object, arguments);
        }
    }
    return f;
}

// Get an array from an array-like object (like dom node container or an "arguments" variable)
VAR.getArray = function(listObject) {
    var list = [];
    var l = listObject.length;
    for (var i = 0; i < l; ++i) {
        list.push(listObject[i]);
    }
    return list;
}

if (Array.map) {
    VAR.map = Array.map;
} else {
    VAR.map = function(list, callback) {
        var out = [];
        for (var i = 0; i < list.length; ++i) {
            out.push(callback(list[i]));
        }
        return out;
    }
}

// [1, 2, 3], 'x' -> [1, 'x', 2, 'x', 3]
VAR.getArrayWithSeparators = function(listObject, separator) {
    var list = [];
    for (var i = 0; i < listObject.length; ++i) {
        if (i > 0) {
            list.push(separator);
        }
        list.push(listObject[i]);
    }
    return list;
}

VAR.covertStringToCamelCase = function(stringVar) {
    var wordArray = stringVar.split(' ');
    var returnString = '';
    for (var i = 0; i < wordArray.length; ++i) {
        returnString += wordArray[i].substr(0,1).toUpperCase() + wordArray[i].substr(1);
    }
    return returnString;
}

VAR.objectUpdate = function(originalObj, newObj) {
  if(typeof originalObj == 'undefined') {
    return newObj;
  }
  for( var item in newObj) {
    if(typeof originalObj[item] == 'undefined') {
      originalObj[item] = newObj[item];
    }
  }
  return originalObj;
}