////////////////////////////////////////////////////////////////////////
//
// Filename:    util.js
// Purpose:     Various JavaScript utility functions.
// Method:      JavaScript library
//
// Author:      J.van.der.Steen@gobase.org
// Date:        2010-03-07
//
////////////////////////////////////////////////////////////////////////

/*global debug */

/*
 * Get an array of DOM elements by supplied name (name or id)
 */
function getN(name)
{
    return document.getElementsByName(name);
}

/*
 * Get a DOM element by supplied id
 */
function getE(id)
{
    return document.getElementById(id);
}

/*
 * Show/hide supplied element or return its visibility
 */
function displayE(elem)
{
    var visible = arguments.length > 1 ? arguments[1] : null;

    if (visible === null) {
        if (elem.style === undefined) {
            return false;
        }
        return elem.style.display != 'none';
    }

    if (visible) {
        elem.style.display = '';
    } else {
        elem.style.display = 'none';
    }
}

/*
 * Manipulate the element class list
 */
function hasClassName(element, className)
{
    var elementClassName = element.className;

    return (elementClassName.length > 0 &&
           (elementClassName == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
}

function addClassName(element, className)
{
    if (!hasClassName(element, className)) {
        element.className += (element.className ? ' ' : '') + className;
    }

    return element;
}

function removeClassName(element, className)
{
    element.className = element.className.replace(
        new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();

    return element;
}

/**
 * Use the stored server date and elapsed time to calculate
 * and return the current server date.
 *
 * NOTE
 * This calculation will be off when the client clock runs
 * at an incorrect speed. The amount of drift will increase
 * in time while an investigator is logged on.
 */
function getServerDate()
{
    var now    = new Date();
    var passed = now.getTime() - config.clienttime;

    //
    // Estimate server date as: [original server date] + [passed milliseconds on client]
    //
    var estimated = new Date();
    estimated.setTime(config.serverdate.getTime() + passed);

    return estimated;
}

/**
 * Called when an investigator logged on.
 */
function storeServerDate(serverdate)
{
    //
    // Store server date
    //
    config.serverdate = serverdateISO2Date(serverdate);

    //
    // Store client time
    //
    var now = new Date();
    config.clienttime = now.getTime();
}

/*
 * Create popup window, size is limited
 */
function popup_window(name, loc, w, h)
{
    var win;
    var opt;

    if (w > config.wmax) { w = config.wmax; }
    if (h > config.hmax) { h = config.hmax; }

    opt  = 'width=' + w + ',height=' + h;
    opt += ',toolbar=0,status=0,location=0,menubar=0';
    opt += ',resizable=1,scrollbars=1';
    win = window.open(loc, name, opt);
    win.focus();

    if (win.opener === null) { win.opener = window; }

    return win;
}

/*
 * Deliver a new GUID
 */
function getGuid()
{
    var guid;

    if (false) {
        //
        // Prototype implementation
        //
        guid = Math.random();
        guid = guid * 1000000000;
        guid = Math.ceil(guid);
    } else {
        //
        // Production version
        //
        guid = "" + new UUID(macaddr);
    }
    return guid;
}

/*
 * Is supplied number a legal GUID?
 */
function legalGuid(guid)
{
    if (false) {
        //
        // Prototype implementation
        //
        guid = parseInt(guid, 10);
        if (typeof guid !== "number") {
            debug("legalGuid(): supplied guid '" + guid + "' is not a number");
            return false;
        }
        return guid > 0 ? true : false;
    }

    //
    // Production version
    //
    if (typeof guid === "number") {
        guid = parseInt(guid, 10);
        return guid > 0 ? true : false;
    }
    if (typeof guid === "string") {
        return guid.length !== 0;
    }
    return false;
}

/**
 * Format a text entered using a textarea
 */
function fmtText(text)
{
    if (text === null) {
        return '';
    }
    //
    // Replace multiple newlines with <p>.
    // Replace newlines with <br>.
    //
    text = text.replace(/\n[\n]+/g, '<p>');
    text = text.replace(/\n/g     , '<br>');

    return text;
}

/*
 * Truncate string at maximal max characters, split at word boundary.
 */
function stringTruncate(str, max, elipse)
{
    var words;
    var phrase = "";
    var sep    = " ";
    var len;

    if (elipse === null) {
        elipse = "...";
    }
    len = elipse.length;

    if (str.length <= max-len) {
        //
        // We're done
        //
        return str;
    }

    words = str.split(sep);

    for (var i = 0; i < words.length; i++) {
        if (len + words[i].length > max) {
            if (i === 0) {
                //
                // Return elipse + tail
                //
                phrase = elipse + str.substr(-1 * (max-len));
            } else {
                phrase += elipse;
            }
            break;
        }
        if (words[i].length) {
            if (phrase !== "") {
                phrase += sep;
            }
            phrase += words[i];
            len = phrase.length;
        }
    }
    return phrase;
}

/*
 * Return icon to denote mimetype based on extension of supplied filename
 */
function iconByFilename(filename)
{
    var icons = { 'png'    : 'picture.gif'
                , 'jpg'    : 'picture.gif'
                , 'jpeg'   : 'picture.gif'
                , 'gif'    : 'gif.gif'
                , 'bmp'    : 'bmp.gif'
                , 'zip'    : 'zip.gif'
                , 'rar'    : 'rar.gif'
                , '7z'     : 'rar.gif'
                , 'gz'     : 'rar.gif'
                , 'bz'     : 'rar.gif'
                , 'ace'    : 'rar.gif'
                , 'uha'    : 'rar.gif'
                , 'bat'    : 'cmd.gif'
                , 'com'    : 'cmd.gif'
                , 'exe'    : 'exe.gif'
                , 'setup'  : 'setup.gif'
                , 'msi'    : 'setup.gif'
                , 'iso'    : 'cd.gif'
                , 'bin'    : 'cd.gif'
                , 'txt'    : 'text.gif'
                , 'js'     : 'js.gif'
                , 'htm'    : 'html.gif'
                , 'html'   : 'html.gif'
                , 'shtml'  : 'html.gif'
                , 'php'    : 'php.gif'
                , 'tpl'    : 'tpl.gif'
                , 'cfg'    : 'cfg.gif'
                , 'fla'    : 'fla.gif'
                , 'swf'    : 'swf.gif'
                , 'pps'    : 'pps.gif'
                , 'xls'    : 'excel.gif'
                , 'doc'    : 'doc.gif'
                , 'sig'    : 'sig.gif'
                , 'asc'    : 'sig.gif'
                , 'fh10'   : 'fh10.gif'
                , 'pdf'    : 'pdf.gif'
                , 'psd'    : 'psd.gif'
                , 'rm'     : 'real.gif'
                , 'ram'    : 'real.gif'
                , 'mpg'    : 'video.gif'
                , 'mpeg'   : 'video.gif'
                , 'mov'    : 'video.gif'
                , 'avi'    : 'video.gif'
                , 'wmv'    : 'video.gif'
                , 'eps'    : 'eps.gif'
                , 'pls'    : 'm3u.gif'
                , 'm3u'    : 'm3u.gif'
                , 'mp3'    : 'music.gif'
                , 'wma'    : 'music.gif'
                } ;

    filename = filename.toLowerCase();

    if (filename && typeof filename === 'string') {
        var comp = filename.split('.');
        var ext  = comp.pop();
        if (icons[ext] !== undefined) {
            return 'ico/' + icons[ext];
        }
    }

    //
    // Alternatively: 'ico/unknown.gif'
    //
    // return 'ico/unknown.gif';
    return 'img/1x1.gif';
}

/*
 * Capitalize every word in supplied string
 */
function myCapitalize(line)
{
    var words = '';
    var sep   = '';

    line = line.split(' ');
    for (var w = 0; w < line.length; w++) {
        words += sep + line[w].substring(0, 1).toUpperCase() + line[w].substring(1, line[w].length).toLowerCase();
        sep    = ' ';
    }
    return words;
}

/*
 * Return ASCII representation of the creation time
 */
function dateToISOTime(dateJS)
{
    var dateISO = '';

    var hour  = dateJS.getHours();
    var min   = dateJS.getMinutes();
    var sec   = dateJS.getSeconds();

    if (hour < 10) {
        hour = '0' + hour;
    }
    if (min < 10) {
        min = '0' + min;
    }
    if (sec < 10) {
        sec = '0' + sec;
    }
    dateISO += hour + ':'
             + min  + ':'
             + sec
             ;

    return dateISO;
}

/*
 * Return ASCII representation of the creation date
 */
function dateToISO(dateJS)
{
    var dateISO;
    var year  = dateJS.getFullYear();
    var month = dateJS.getMonth() + 1;
    var day   = dateJS.getDate();
    var full  = arguments.length > 1 ? arguments[1] : 0;

    if (month < 10) {
        month = '0' + month;
    }
    if (day < 10) {
        day = '0' + day;
    }
    dateISO = year  + '-'
            + month + '-'
            + day
            ;

    if (full) {
        dateISO += ' ' + dateToISOTime(dateJS);
    }

    return dateISO;
}

/*
 * Convert a server ISO date string like "2008-10-20 12:56:54" to a Date() object.
 */
function serverdateISO2Date(value)
{
    var a;

    if (typeof value === 'string') {
        a = /^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/.exec(value);
        if (a) {
            return new Date(+a[1], +a[2]-1, +a[3], +a[4], +a[5], +a[6]);
        } else {
            return getServerDate();
        }
    }
    return value;
}

/*
 * Convert an ISO date string like "2008-10-20T12:56:54Z" to a Date() object.
 */
function dateISO2Date(value)
{
    var a;

    if (typeof value === 'string') {
        a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);
        if (a) {
            return new Date(Date.UTC(+a[1], +a[2] -1, +a[3], +a[4], +a[5], +a[6]));
        } else {
            return getServerDate();
        }
    }
    return value;
}

/**
 * Trim whitespace off supplied string
 */
function trim(src)
{
    if (src !== null) {
        return src.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
    }
    return src;
}

/*
 * Returns the filename component of the path.
 * Strip suffix when it's supplied.
 * This function can deal with both UNIX as DOS path separators.
 */
function basename(path)
{
    var suffix = arguments.length > 1 ? arguments[1] : null;
    var b = path.replace(/^.*[\/\\]/g, '');
    
    if (typeof suffix === "string" && b.substr(b.length-suffix.length) == suffix) {
        b = b.substr(0, b.length-suffix.length);
    }

    // debug("basename(): src: '" + path + "', dst: '" + b + "'");

    return b;
}

/*
 * Escape pattern in supplied string using "escaped" characters
 */
function myEscape(s, pattern, escaped)
{
    var expr = new RegExp(pattern, 'g');

    return s.replace(expr, escaped);
}


