/* Adds string.trim() function if it doesn't exist */
if(!String.prototype.trim) {
    String.prototype.trim = function() {
        return this.replace(/^\s+|\s+$/g, '');
    }
}

function Browser() {
    var ua, s, i;

    this.isIE    = false;  // Internet Explorer
    this.isOP    = false;  // Opera
    this.isNS    = false;  // Netscape
    this.version = null;

    ua = navigator.userAgent;

    s = "Opera";
    if (window.opera) {
        this.isOP = true;
        this.version = parseFloat(ua.substr(i + s.length));
        return;
    }

    s = "Netscape6/";
    if ((i = ua.indexOf(s)) >= 0) {
        this.isNS = true;
        this.version = parseFloat(ua.substr(i + s.length));
        return;
    }

    // Treat any other "Gecko" browser as Netscape 6.1.

    s = "Gecko";
    if ((i = ua.indexOf(s)) >= 0) {
        this.isNS = true;
        this.version = 6.1;
        return;
    }

    s = "MSIE";
    if ((i = ua.indexOf(s))) {
        this.isIE = true;
        this.version = parseFloat(ua.substr(i + s.length));
        return;
    }
}
var browser = new Browser();


function get_window_size()
{
    /* http://www.howtocreate.co.uk/tutorials/javascript/browserwindow */
    var myWidth = 0, myHeight = 0;
    if( typeof( window.innerWidth ) == 'number' ) {
        //Non-IE
        myWidth = window.innerWidth;
        myHeight = window.innerHeight;
    } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
        //IE 6+ in 'standards compliant mode'
        myWidth = document.documentElement.clientWidth;
        myHeight = document.documentElement.clientHeight;
    } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
        //IE 4 compatible
        myWidth = document.body.clientWidth;
        myHeight = document.body.clientHeight;
    }
    
    var x = new Object();
    x.width = myWidth;
    x.height = myHeight;
    return x;    
}

function get_scrolled_area() {
    var xy = new Object();
    xy.x = 0;
    xy.y = 0;
    
    if(document.documentElement && typeof(document.documentElement.scrollLeft) == "number") {
        xy.x = Math.max(xy.x, document.documentElement.scrollLeft);
        xy.y = Math.max(xy.y, document.documentElement.scrollTop);
    }
    if(document.body && typeof(document.body.scrollLeft) == "number") {
        xy.x = Math.max(xy.x, document.body.scrollLeft);
        xy.y = Math.max(xy.y, document.body.scrollTop);
    }
    if(typeof(window.scrollX) == "number") {
        xy.x = Math.max(xy.x, window.scrollX);
        xy.y = Math.max(xy.y, window.scrollY);
    }
    if(typeof(window.pageXOffset) == "number") {
        xy.x = Math.max(xy.x, window.pageXOffset);
        xy.y = Math.max(xy.y, window.pageYOffset);
    }
    
    xy.top = xy.y;
    xy.left = xy.x;
    return xy;
}

function get_scrolled_size()
{
    var xy;
    xy = new Object();
    xy.width = 0;
    xy.height = 0;
    
    var window_size = get_window_size();
    var document_size = get_document_size();
    var scrolled_area = get_scrolled_area();
    
    /* Skrolano */
    xy.width = scrolled_area.x;
    xy.height = scrolled_area.y;
    
    /* Prozor */
    xy.width += window_size.width;
    xy.height += window_size.height;
    
    /* Dokument */
    xy.width = Math.min(xy.width, document_size.width);
    xy.height = Math.min(xy.height, document_size.height);
    
    /*
    var maxX, maxY
    if (browser.isIE) {
        maxX = Math.max(document.documentElement.scrollLeft, document.body.scrollLeft) +
            (document.documentElement.clientWidth != 0 ? document.documentElement.clientWidth : document.body.clientWidth);
        maxY = Math.max(document.documentElement.scrollTop, document.body.scrollTop) +
            (document.documentElement.clientHeight != 0 ? document.documentElement.clientHeight : document.body.clientHeight);
    }
    if (browser.isOP) {
        maxX = document.documentElement.scrollLeft + window.innerWidth;
        maxY = document.documentElement.scrollTop  + window.innerHeight;
    }
    if (browser.isNS) {
        maxX = window.scrollX + window.innerWidth;
        maxY = window.scrollY + window.innerHeight;
    }
    
    xy.width = maxX;
    xy.height = maxY;
    */
    
    //alert(xy.width + "x" + xy.height);
    return xy;
}

function get_document_size()
{
    var xy = new Object();
    xy.width = 0;
    xy.height = 0;
    
    if(document.body.scrollHeight) {
        xy.width = Math.max(xy.width, document.body.scrollWidth);
        xy.height = Math.max(xy.height, document.body.scrollHeight);
    }
    if(document.body.parentNode.scrollHeight) {
        xy.width = Math.max(xy.width, document.body.parentNode.scrollWidth);
        xy.height = Math.max(xy.height, document.body.parentNode.scrollHeight);
    }
    
    return xy;
}

function addEvent( obj, type, fn ) {
  if ( obj.attachEvent ) {
    obj['e'+type+fn] = fn;
    obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
    obj.attachEvent( 'on'+type, obj[type+fn] );
  } else
    obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
  if ( obj.detachEvent ) {
    obj.detachEvent( 'on'+type, obj[type+fn] );
    obj[type+fn] = null;
  } else
    obj.removeEventListener( type, fn, false );
}


function format_bytes(bytes){
    if (bytes >= 1073741824) {
        return Math.round(bytes / 1073741824 * 100) / 100 + " GiB";
    } else if (bytes >= 1048576) {
        return Math.round(bytes / 1048576 * 100) / 100 + " MiB";
    } else if (bytes >= 1024) {
        return Math.round(bytes / 1024 * 100) / 100 + " KiB";
    } else {
        return bytes + " B";
    }
}

function scroll_to_element(theElement) {
    if(theElement == null || theElement == undefined) {
        return;
    }
    var selectedPosX = 0;
    var selectedPosY = 0;
    
    while(theElement != null){
        selectedPosX += theElement.offsetLeft;
        selectedPosY += theElement.offsetTop;
        theElement = theElement.offsetParent;
    }

    var scrolled = get_scrolled_area();
    if(scrolled.top < selectedPosX) {
        return;
    }
    
    window.scrollTo(selectedPosX,selectedPosY);
}

function is_applet_loaded(applet_id) {
    try {
        var element = document.getElementById(applet_id);
        if (!element.isActive()) {
            return false;
        }
        return true;
    } catch(err) {
        return false;
    }
}

function rgbToHex(rgb) { 
    if (rgb.match(/^#[0-9A-Fa-f]{6}$/)) {
        return rgb;
    }
    var rgbvals = /rgb\((.+),(.+),(.+)\)/i.exec(rgb);
    if (!rgbvals) {
        return rgb;
    }
    var rval = parseInt(rgbvals[1]);
    var gval = parseInt(rgbvals[2]);
    var bval = parseInt(rgbvals[3]);
    var pad = function(value) {
        return (value.length < 2 ? '0' : '') + value;
    };
    return '#' + pad(rval.toString(16)) + pad(gval.toString(16)) + pad(bval.toString(16));
}

//window.console
if(console === undefined) {
    var console = {};
}
if(!console.log) console.log = function() {};
if(!console.warn) console.warn = function() {};
if(!console.error) console.warn = function() {};
if(!console.group) console.group = function() {};
if(!console.groupEnd) console.groupEnd = function() {};
if(!console.groupCollapsed) console.groupCollapsed = function(q) { console.group(q); };

//TODO: group in cms.ajax object
//TODO: rest, return type, ...
function ajax_call_sync(func, data_encoded, data) {
    // data is encoded with json to keep null, string, bool, integer data types

    if(data === undefined) {
        data = [];
    }
    var ajax_output;
    var settings = $.extend({}, _v1_ajax_settings_default,
        {
            data : {
                json : JSON.stringify({
                        _method : '_obj_call_',
                        _func : func,
                        _dataEncoded : data_encoded,
                        data : data
                    })
            },
            success : function(data, textStatus, jXHR) {
                //console.log('okej', data, textStatus, jXHR);
                ajax_output = data;
            },
            error : function(jXHR, textStatus, errorThrown) {
                //console.log('error', jXHR, textStatus, errorThrown);
                $.error("Error in AJAX call");
                ajax_output = null;
            }
        }
    );
    $.ajax(settings);
    return ajax_output;
}


var _v1_ajax_async_seq = {};
function ajax_call_async(func, data_encoded, data, callback) { // optional params: seq, delay, seq_number
    if(data === undefined) {
        data = [];
    }
    
    // If browser makes two ajax calls with the same seq(ence) only the newest will make it to callback  
    var args = ajax_call_async.arguments;
    var seq = null;
    var this_seq_id = null;
    var delay = 0;
    
    if(args.length > 4) {
        seq = args[4];
    }
    if(args.length > 5) {
        delay = args[5];
    }
    if(args.length > 6) {
        this_seq_id = args[6];
    }
    
    
    if(seq !== null) {
        if(_v1_ajax_async_seq.seq === undefined) {
            _v1_ajax_async_seq.seq = 0;
        }
        
        if(this_seq_id !== null) {
            if(this_seq_id != _v1_ajax_async_seq.seq) {
                return;
            }
        } else {
            _v1_ajax_async_seq.seq++;
            this_seq_id = _v1_ajax_async_seq.seq;
        }
        //console.log(seq, this_seq_id);
    }
    
    
    if(delay > 0) {
        setTimeout(function() {
            ajax_call_async(func, data_encoded, data, callback, seq, 0, this_seq_id)
            }, delay
        );
        return;
    }
    
    var settings = $.extend({}, _v1_ajax_settings_default,
        {
            async : true,
            data : {
                json : JSON.stringify({
                        _method : '_obj_call_',
                        _func : func,
                        _dataEncoded : data_encoded,
                        data : data
                    })
            },
            success : function(data, textStatus, jXHR) {
                //console.log('okej', data, textStatus, jXHR);
                if(seq === null || _v1_ajax_async_seq.seq == this_seq_id) {
                    //console.log(seq, this_seq_id, _v1_ajax_async_seq.seq);
                    callback(data);
                } else {
                    //console.log('Ajax return is ignored because newer call has been made');
                }
            },
            error : function(jXHR, textStatus, errorThrown) {
                //console.log('error', jXHR, textStatus, errorThrown);
                $.error("Error in AJAX call");
            }
        }
    );
    $.ajax(settings);
}

function html_select_reset(select, options, empty_text) {
    select = $(select);
    select.empty();
    var selected = select.attr("data-selected");
    if(empty_text !== null) {
        var option = $("<option value=''></option>");
        option.text = empty_text;
        select.append(option);
    }
    for(i = 0; i < options.length; i++) {
        var option = $("<option></option>");
        option.val(options[i].value);
        option.text(options[i].text);
        if(selected == options[i].value) {
            option.attr('selected', '');
        }
        select.append(option);
    }
    select.attr("data-selected", selected);
}

