function uuid() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = Math.floor(Math.random()*0x10);
        return ((c == 'x') ? r : (r&0x3|0x8)).toString(16);
    }).toUpperCase();
}

function zeroPad(n, width) {
    var s = n.toString();
    var zeros = width - s.length;
    for (var i = 0; i < zeros; i++) {
        s = '0' + s; 
    }
    return s;
}

function equals(a, b){
    for (var i = 1; i < arguments.length; b = arguments[++i]) {
        if (a === b) {
            continue;
        } else if (!(a instanceof Object) || !(b instanceof Object)) {
            return false; 
        } else {
            for (var name in b) {
                if (!equals(a[name], b[name])) { return false; }
            }
        }
    }
    
    return true;
}

String.prototype.normalizeSpace = function() {
	return this.replace(/^\s+|\s+$/g, "").replace(/\s+/, " ");
}

String.prototype.capitalize = function () {
    return this.charAt(0).toUpperCase() + this.slice(1).toLowerCase();
};

String.prototype.toTitleCase = function () {
    var str = "";
    var words = this.split(" ");
    for (var i = 0; i < words.length; i++) {
        str += (i ? " " : "") + words[i].capitalize();
    }
    return str;
};

var longMonths = ["January", "February", "March", "April", "May", "June",
                   "July", "August", "September", "October", "November", "December"];
var shortMonths = ["Jan", "Feb", "Mar", "Apr", "May", "Jun",
                    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var longDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var shortDays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];

Date.prototype.strftime = function (format) {
    var year = this.getFullYear();
    var month = this.getMonth();
    var day = this.getDate();
    var weekday = this.getDay();
    var hours = this.getHours();
    var minutes = this.getMinutes();
    var seconds = this.getSeconds();

    return format.replace(/\%([aAbBcdDHiImMpSwyY])/g, function (part) {
        switch(part[1]) {
            case 'a': return shortDays[weekday];
            case 'A': return longDays[weekday];
            case 'b': return shortMonths[month];
            case 'B': return longMonths[month];
            case 'c': return this.toString();
            case 'd': return day;
            case 'D': return zeroPad(day, 2);
            case 'H': return zeroPad(hours, 2);
            case 'i': return ((hours === 12 || hours === 0) ? 12 : (hours + 12) % 12);
            case 'I': return zeroPad(((hours === 12 || hours === 0) ? 12 : (hours + 12) % 12), 2);
            case 'm': return zeroPad(month + 1, 2);
            case 'M': return zeroPad(minutes, 2);
            case 'p': return hours > 11 ? "PM" : "AM";
            case 'S': return zeroPad(seconds, 2);
            case 'w': return weekday;
            case 'y': return zeroPad(year % 100);
            case 'Y': return year;
        }
    });
};

function escapeXML(str) {
    if (!str) { return ""; }
    return (str.toString()
               .replace(/&(?!\w{2,5};)/g, "&amp;")
               .replace(/\s/g, "&ensp;")
               .replace(/\"/g, "&quot;")
               .replace(/</g, "&lt;")
               .replace(/>/g, "&gt;")
               .replace(/\n/g, '<br/>'));
}

var minimizable = {'base':true, 'meta':true, 'link':true, 'hr':true, 'br':true,
                   'param':true, 'img':true, 'area':true, 'input':true, 'col':true};

function jsonify(ob) {
    result = {}
    $.each(ob, function (name, value) {
        result[name] = JSON.stringify(value);
    });
    
    return result;
}

function fbconnect_loggedin() {
    var c = document.cookie;
    c = c.split(";");
    var d;
    for (var k = 0; k < c.length; k++) {
        if (c[k].indexOf("f014be20587b0a763a00861cf60cbf0a_user") != -1) { // APIKEY_user
            return true;
        }
    }
    return false;
}

function parseColor(color) {
    if (color.charAt(0) == "#") {
        return color.substring(1, 7);
    } else {
        return rgb2hex(color);
    }
}

function rgb2hex(rgb) {
    var parts = rgb.match(/^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/);
    // parts now should be ["rgb(0, 70, 255", "0", "70", "255"]

    delete (parts[0]);
    for (var i = 1; i <= 3; ++i) {
        parts[i] = parseInt(parts[i]).toString(16);
        if (parts[i].length == 1) parts[i] = '0' + parts[i];
    }

    // returns w/o leading #
    return parts.join('');
}

// converts hex to rgb w/ option to reduce brightness given % of original brightness
function hex2rgb(hex, br) {
    function cutHex(h) { return (h.charAt(0)=="#") ? h.substring(1,7):h }

    var r = parseInt((cutHex(hex)).substring(0,2),16);
    var g = parseInt((cutHex(hex)).substring(2,4),16);
    var b = parseInt((cutHex(hex)).substring(4,6),16);

    return 'rgb(' + Math.ceil(r*(br/100)) + ', ' + Math.ceil(g*(br/100)) + ', '+ Math.ceil(b*(br/100)) + ')';
}

function millisecondsToDate(milliseconds) {
    var date = new Date(milliseconds);
    var month = date.getMonth() + 1;
    var day = date.getDate();
    var year = date.getFullYear();
    
    return month + "/" + day + "/" + year;
}

function Element(tag, attributes, text) {
    var el = $('<' + tag + '>').text(text ? text : "");
    for (var name in attributes) {
        if (attributes[name]) { el.attr(name, attributes[name]); }
    }
    return el;
}

function isEmptyObject(obj) {
    for (var name in obj) {
    	return false;
    }
    return true;
}

function indexByKeyName(obj, array) {
    var index = -1;
    $.each(array, function (i, a) {
        if (a.key_name == obj.key_name) { index = i; }
    });
    return index;
}

function indexByParent(obj, array) {
    var index = -1;
    $.each(array, function (i, a) {
        if (a.key_name == obj.parent_style) { index = i; }
    });
    return index;
}
