var dsl_unit_meter = true;
var dsl_distance = 1000;
var m2ft = 3.2808399;
var dbm = 0.01381;
var dsltype = "adsl";

var networksize = 24;

function valid(ip) {
    var ipPattern = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
    var ipArray = ip.match(ipPattern);
    return (ipArray!=null);
}

function dot2bin(ip) {
    if (ip == "---") return ip;
    var parts = ip.split(".");
    var result = "";
    for(var i in parts) {
        var value = parseInt(parts[i]).toString(2);
        for ( j = value.length; j < 8; j++) {
            value = "0"+value;
        }
        result += value;
        if (i<3) result += ".";
    }
    return result;
}

function bits2d(binary) {
    var decimal = 0;
    if (binary > 0) {decimal = decimal + 128}
    if (binary > 1) {decimal = decimal + 64}
    if (binary > 2) {decimal = decimal + 32}
    if (binary > 3) {decimal = decimal + 16}
    if (binary > 4) {decimal = decimal + 8}
    if (binary > 5) {decimal = decimal + 4}
    if (binary > 6) {decimal = decimal + 2}
    if (binary > 7) {decimal = decimal + 1}
    return(decimal);
}

function mask2ip() {
    a = bits2d(networksize);
    b = bits2d(networksize - 8);
    c = bits2d(networksize - 16);
    d = bits2d(networksize - 24);
    return a+"."+b+"."+c+"."+d;
}

function ip2broadcast(ip) {
    ips = ip.split(".");
    masks = mask2ip().split(".");
    a = ips[0] | (~ masks[0] & 0xff);
    b = ips[1] | (~ masks[1] & 0xff);
    c = ips[2] | (~ masks[2] & 0xff);
    d = ips[3] | (~ masks[3] & 0xff);
    return a+"."+b+"."+c+"."+d;
}

function ip2net(ip) {
    ips = ip.split(".");
    masks = mask2ip().split(".");
    a = ips[0] & masks[0];
    b = ips[1] & masks[1];
    c = ips[2] & masks[2];
    d = ips[3] & masks[3];    
    return a+"."+b+"."+c+"."+d;
}

function getFirst(ip) {
    if (networksize == 32) {return ip};
    ips = ip2net(ip).split(".");
    a = ips[0];
    b = ips[1];
    c = ips[2];
    d = parseInt(ips[3])+1;
    return a+"."+b+"."+c+"."+d;
}

function getLast(ip) {
    ips = ip2net(ip).split(".");
    masks = mask2ip().split(".");
    broads = ip2broadcast(ip).split(".");
    if (networksize == 32) { 
        return "---";
    } else if (networksize == 31) {
        a = ips[0] | (~ masks[0] & 0xff);
        b = ips[1] | (~ masks[1] & 0xff);
        c = ips[2] | (~ masks[2] & 0xff);
        d = ips[3] | (~ masks[3] & 0xff);
        return a+"."+b+"."+c+"."+d;
    } else {
        a = broads[0];
        b = broads[1];
        c = broads[2];
        d = parseInt(broads[3])-1;
        return a+"."+b+"."+c+"."+d;
    }
}

function gethosts() {
    if (networksize == 32) return 1;
    else if (networksize == 31) return 2;
    else return Math.pow(2,32 - networksize) - 2;
}

function networkCalc() {
    var ip = $("#network-host").val();
    if (valid(ip)) {
        $("#network-netmask").val("/"+networksize);
        var netmask = mask2ip();
        $("#network-netmaskip").val(netmask);
        $("#network-netmaskbin").val(dot2bin(netmask));
        var net = ip2net(ip);
        $("#network-network").val(net+"/"+networksize);
        $("#network-networkbin").val(dot2bin(net));
        var broad = ip2broadcast(ip);
        $("#network-broadcast").val(broad);
        $("#network-broadcastbin").val(dot2bin(broad));
        var first = getFirst(ip);
        $("#network-first").val(first);
        $("#network-firstbin").val(dot2bin(first));        
        var last = getLast(ip);
        $("#network-last").val(last);
        $("#network-lastbin").val(dot2bin(last));
        $("#network-hosts").val(gethosts());
    }
}

function distanceValue() {
    if (dsl_unit_meter)
        $("#distance").val(dsl_distance+ ' m')
    else
        $("#distance").val( Math.round(dsl_distance*m2ft)+ ' ft');
    dslcalc();
}

function getADSL(x) {
    if (x < 2.1) return 8.0;
    else if (x < 2.5) return 7.6 - (x-2.5);
    else if (x < 2.9) return 7.0 - (x-2.9)*1.5;
    else if (x < 3.3) return 5.9 - (x-3.3)*2.75;
    else if (x < 3.7) return 4.6 - (x-3.7)*3.25;
    else if (x < 4.1) return 3.3 - (x-4.1)*3.25;
    else if (x < 4.5) return 2.1 - (x-4.5)*3;
    else if (x <= 4.9) return 1.2 - (x-4.9)*2.25;
    else return 0;
}

function getADSL2(x) {
    if (x < 0.5) return 24.0;
    else if (x < 0.9) return 23.0 - (x-0.9)*2.5;
    else if (x < 1.3) return 21.0 - (x-1.3)*5;
    else if (x < 1.7) return 19.0 - (x-1.7)*5;
    else if (x < 2.1) return 16.0 - (x-2.1)*7.5;
    else if (x < 2.5) return 12.0 - (x-2.5)*10;
    else if (x < 2.9) return 9.0 - (x-2.9)*7.5;
    else if (x < 3.3) return 7.0 - (x-3.3)*5;
    else if (x < 3.7) return 4.7 - (x-3.7)*5.75;
    else if (x < 4.1) return 3.6 - (x-4.1)*2.75;
    else if (x < 4.5) return 2.1 - (x-4.5)*3.75;
    else if (x <= 4.9) return 1.6 - (x-4.9)*1.25;
    else return 0;
}

function getVDSL8(x) {
    if (x < 300) return 60 - (x * .045931759);
    else if (x < 685) return 46 - ((x-300) *.023622047);
    else if (x < 1140) return 37 - ((x-685) *.030621172);
    else return 23 - ((x-1140) *.014581511);
}

function getVDSL17(x) {
    if (x < 300) return 78 - (x * .065616798);
    else if (x < 530) return 58 - ((x-300) *.048118985);
    else if (x < 685) return 47 - ((x-530) *.065616798);
    else if (x < 1140) return 37 - ((x-685) *.030621172);
    else return 23 - ((x-1140) *.014581511);
}

function dslcalc() {
    if (dsltype == "adsl" || dsltype=="adsl2") {
        $("#att").val( Math.round(dsl_distance*dbm*10)/10 + ' dB');
    } else {
        $("#att").val('--- dB');
    }
    if (dsltype == "adsl") {
        $("#down").val(Math.round(getADSL(dsl_distance/1000)*10)/10+' mbps');
    } else if (dsltype =="adsl2") {
        $("#down").val(Math.round(getADSL2(dsl_distance/1000)*10)/10+' mbps');
    } else if (dsltype =="vdsl8") {
        $("#down").val(Math.round(getVDSL8(dsl_distance)*10)/10+' mbps');
    } else {
        $("#down").val(Math.round(getVDSL17(dsl_distance)*10)/10+' mbps');
    }
}

function setSliderMax(max) {
    $("#slider-distance" ).slider( "option", "max", max );
    var value = $( "#slider-distance" ).slider( "option", "value" );
    $("#slider-distance").slider( "option", "value", value );
}

function hexFromRGB (r, g, b) {
    var hex = [
        r.toString(16),
        g.toString(16),
        b.toString(16)
    ];
    $.each(hex, function (nr, val) {
        if (val.length == 1) {
            hex[nr] = '0' + val;
        }
    });
    return hex.join('').toUpperCase();
}

function RGBfromhex(hex) {
    var ret = new Array(3);
    ret[0] = parseInt("0x"+hex.substring(1,3));
    ret[1] = parseInt("0x"+hex.substring(3,5));
    ret[2] = parseInt("0x"+hex.substring(5,7));
    return ret;
}

function updateInput(color) {
    var op = $.farbtastic("#colorpicker").hsl[2] > 0.5 ? '#000' : '#fff';
    $("#color").val(color).css("background-color",color).css("color",op);
}

function updateSlider(color) {
    var rgb = RGBfromhex(color);
    $("#red").slider("value", rgb[0]);
    $("#green").slider("value", rgb[1]);
    $("#blue").slider("value", rgb[2]);
    $("#rednum").val(rgb[0]);
    $("#greennum").val(rgb[1]);
    $("#bluenum").val(rgb[2]);
}

function updatePicker(color) {
    $.farbtastic("#colorpicker").setColor(color);
}

function changeColor(elem) {
    if (elem=="picker") {
        var k = $.farbtastic("#colorpicker").color;
        updateInput(k);
        updateSlider(k);
    } else if (elem=="slider") {
        var red = $("#red").slider("value");
        var green = $("#green").slider("value");
        var blue = $("#blue").slider("value");
        updatePicker("#"+hexFromRGB(red,green,blue));
        var kk = $.farbtastic("#colorpicker").color;
        updateInput(kk);
    } else if (elem=="input") {
        var kkk = $("#color").val();
        updateInput(kkk);
        updateSlider(kkk);
        updatePicker(kkk);
        $("#color").css("background-color",kkk);
    }
}
function refreshColorSlide() {
    changeColor("slider");
}

function initColor() {
    $('#colorpicker').farbtastic(function(){
        changeColor("picker");
    });
    $("#color").change(function(){
        changeColor("input");
    });
    $("#red, #green, #blue").slider({
            orientation: 'vertical',
            range: "min",
            max: 255,
            value: 127,
            slide: refreshColorSlide,
            change: refreshColorSlide
    });
    $.farbtastic("#colorpicker").setColor("#0073ea");
}

function initDSL() {
    $("#dslmeter").buttonset();
    $("#dsltype").buttonset();
    $("#adsl").click(function(){
        dsltype = "adsl";
        setSliderMax(4900);
        dslcalc();
        return false;
    });
    $("#adsl2").click(function(){
        dsltype = "adsl2";
        setSliderMax(4900);
        dslcalc();
        return false;
    });
    $("#vdsl8").click(function(){
        dsltype = "vdsl8";
        setSliderMax(1500);
        dslcalc();
        return false;
    });
    $("#vdsl17").click(function(){
        dsltype = "vdsl17";
        setSliderMax(1500);
        dslcalc();
        return false;
    });
    $("#meter").click(function(){
        dsl_unit_meter = true;
        distanceValue();
        return false;
    });
    $("#feet").click(function(){
        dsl_unit_meter = false;
        distanceValue();
        return false;
    });
    $("#slider-distance").slider({
        range: "min",
        value: 1000,
        min: 1,
        max: 4900,
        slide: function(event, ui) {
            dsl_distance = ui.value;
            distanceValue();
        }
    });
    $("#distance").val($("#slider-distance").slider("value") + ' m');
    dslcalc();
    $("#dsl-message").dialog({
        autoOpen: false,
        modal: true,
        buttons: {
            Ok: function() {
                $(this).dialog('close');
            }
        }
    });
    $('#dsl-open')
        .button({
            icons: {
                primary: 'ui-icon-help'
            }
        })
        .click(function() {
            $('#dsl-message').dialog('open');
        });
}

function initVDSL2tool() {
    $("a.fancybox").fancybox();
}

function initPhotoStats() {
    $("a.fancybox").fancybox();
}

function initNetwork() {
    $("#network-host").keypress(function() {
        networkCalc();
    });
    $("#network-calc").button().click(function(){
        networkCalc();
    });
    $("#slider-network").slider({
        range: "min",
        value: 24,
        min: 0,
        max: 32,
        slide: function(event, ui) {
            networksize = ui.value;
            networkCalc();
        }
    });
    networkCalc();
    $("#network-special-text").dialog({
        width:600,
        height:500,
        autoOpen: false,
        modal: true,
        buttons: {
            Ok: function() {
                $(this).dialog('close');
            }
        }
    });
    $('#network-special')
        .button({
            icons: {
                primary: 'ui-icon-help'
            }
        })
        .click(function() {
            $('#network-special-text').dialog('open');
        });
}

function initConvert() {
    $("#accordion").accordion({ autoHeight: false });
}

function init() {
    $("#tabs" ).tabs({
        load: function(event, ui) {
            if (ui.index==1) initVDSL2tool();
            else if (ui.index==2) initPhotoStats();
            else if (ui.index==3) initDSL();
            else if (ui.index==4) initColor();
            else if (ui.index==5) initNetwork();
            else if (ui.index==6) initConvert();
        }
    });
}