var counts = [0, 0, 0];
var eqCount = 12; //MAX EQ PER CANAL
var eqFreqDefault = 1000.0;
var eqFreqDefaultInit = [100,200,300,400,500,1000,2000,3000,4000,5000,10000,20000];
var eqGainDefault = 0.0;
var eqQDefault = 2.5;
var eqTypeDefault = "bell";
var freq_scale = [10,20,50,100,500,1000,2000,5000,10000,20000,22000];
var freq_scale_text = ["10","20","50","100","500","1k","2k","5k","10k","20k",""];
var freq_scale_line = [10,20,30,40,50,60,70,80,90,100,200,300,400,500,600,700,800,900,1000,2000,3000,4000,5000,6000,7000,8000,9000,10000,20000,22000];
var gain_scale = [18,12,6,0,-6,-12,-18,-24,-30,-36];

var widgetPEQX = 1200;
var widgetPEQY = 800;
var widgetPEQMarginLeft = 25;
var widgetPEQMarginRight = 5;
var widgetPEQMarginTop = 15;
var widgetPEQMarginBottom = 25;
var graphPEQHeight = 0;
var graphPEQWidth = 0;
var yZero = 0;
var scale = Math.log10(22000)-1;

var eqParam = {frequency: eqFreqDefault, gain : eqGainDefault,q : eqQDefault,type : eqTypeDefault};

var arrayEqParam;

var eqParamDraggable = new Object();
var arrayEqParamDraggable = new Array();
var drag = [];
var draggie = [];

$(document).ready(function() {
    //INITIAL EQ SETUP
    $(function() {
        arrayEqParam = new Array(eqCount);
        graphPEQHeight = widgetPEQY - widgetPEQMarginTop - widgetPEQMarginBottom;
        graphPEQWidth = widgetPEQX - widgetPEQMarginLeft - widgetPEQMarginRight;
        console.log("widget height : " + widgetPEQY + " // graph height : " + graphPEQHeight);
        console.log("widget width : " + widgetPEQX + " // graph width : " + graphPEQWidth);
        for(var i=0; i<eqCount; i++)
        {
            var t = eqParam;
            arrayEqParam[i] = t;
        }

        //BACKGROUND INIT
        var canvasPEQ = document.createElement("canvas");
        canvasPEQ.id = "canvasWidgetPEQ";
        canvasPEQ.width = widgetPEQX;
        canvasPEQ.height = widgetPEQY;
        $("#widgetParamEQ").append(canvasPEQ);

        //CURVE DRAWING AREA INIT
        var graphPEQ = document.createElement("canvas");
        graphPEQ.id = "graphWidgetPEQ";
        graphPEQ.width = graphPEQWidth;
        graphPEQ.height = graphPEQHeight;
        graphPEQ.style.marginTop = "" + widgetPEQMarginTop + "px";
        graphPEQ.style.marginLeft = "" + widgetPEQMarginLeft + "px";
        $("#widgetParamEQ").append(graphPEQ);

        //INIT EXTERNAL CANVAS
        var c = document.getElementById("canvasWidgetPEQ");
        var ctx = c.getContext("2d");
        c.style.width = widgetPEQX;
        c.style.height = widgetPEQY;

        ctx.beginPath();
        //BG COLOR
        ctx.rect(0, 0, widgetPEQX, widgetPEQY);
        ctx.fillStyle = "#0a1a29";
        ctx.fill();
        //EXTERNAL LINE
        ctx.strokeStyle = "#3e4954";
        ctx.strokeRect(widgetPEQMarginLeft, widgetPEQMarginTop, graphPEQWidth,graphPEQHeight);
        // c.style.opacity = '0.2'
        //GAIN AXE
        ctx.strokeStyle = "#3e4954";
        for(var i=0; i<gain_scale.length; i++)
        {
            var step = 54 / (gain_scale.length-1);
            step = step *graphPEQHeight /54;
            ctx.moveTo(widgetPEQMarginLeft, widgetPEQMarginTop + i * step);
            ctx.lineTo(widgetPEQX-widgetPEQMarginRight, widgetPEQMarginTop + i * step);
            ctx.stroke();
            ctx.font = "12px Arial";
            ctx.fillStyle = "white";
            ctx.textAlign = "right";
            ctx.fillText(gain_scale[i].toString(), widgetPEQMarginLeft-5, widgetPEQMarginTop + i * step +5); 
            if(gain_scale[i] == 0)
                yZero = i*step;
        }
        //FREQUENCY AXE
        ctx.strokeStyle = "#3e4954";
        var j=0
        for(var i=0; i<freq_scale_line.length-1; i++)
        {
            var scale = Math.log10(22000)-1;
            // console.log("scale : " + scale);
            var abc = graphPEQWidth / scale;
            var x = Math.log10(freq_scale_line[i]);
            // console.log("step : " + step + " // length : " + freq_scale_line.l:ength);
            ctx.moveTo((x-1) * abc, widgetPEQMarginTop);
            ctx.lineTo((x-1) * abc, widgetPEQY-widgetPEQMarginBottom);
            ctx.stroke();
            ctx.font = "12px Arial";
            ctx.fillStyle = "white";
            ctx.textAlign = "center";
            if(freq_scale.includes(freq_scale_line[i])!=0)
            {
                if(i==0)
                    ctx.fillText(freq_scale_text[j].toString(), widgetPEQMarginLeft, widgetPEQY-10);
                else
                    ctx.fillText(freq_scale_text[j].toString(), (x-1) * abc, widgetPEQY-10); 
            j++;
            }
            
        }
        ctx.strokeRect(widgetPEQMarginLeft, widgetPEQMarginTop, widgetPEQX-widgetPEQMarginLeft-widgetPEQMarginRight,widgetPEQY-widgetPEQMarginTop-widgetPEQMarginBottom);
    

        // Find a <table> element with id="myTable":
        var div1 = document.getElementById("parametersArea");
        var table = document.createElement("table");

        $(div1).append(table);
        // Create an empty <tr> element and add it to the 1st position of the table:
        for(var i=0;i<eqCount;i++)
        {
            var row = table.insertRow(i);

            // Insert new cells (<td> elements) at the 1st and 2nd position of the "new" <tr> element:
            var cell1 = row.insertCell(0);
            var cell2 = row.insertCell(1);
            var cell3 = row.insertCell(2);
            var cell4 = row.insertCell(3);
            var cell5 = row.insertCell(4);

            // Add some text to the new cells:
            cell1.innerHTML = "EQ n°"+(i+1);
            cell2.innerHTML = "Filter type : <select id=\"eqType"+i+"\"><option value=\"bellSym\">Bell-Sym</option><option value=\"Green\">Bell-ASym</option><option value=\"White\">Notch</option></select>";
            cell3.innerHTML = "Frequency : <input id=\"freq_text"+i+"\" type=\"text\"> ";
            cell4.innerHTML = "Gain : <input id=\"gain_text"+i+"\" type=\"text\">";
            cell5.innerHTML = "Q : <input id=\"q_text"+i+"\" type=\"text\">";
        }

        //INITALIZE PARAMETERS FIELDS
        //TARGET
        // <p>Filter type :
        //     <select id='myColors'>
        //     <option value="bellSym ">Bell-Sym</option>
        //     <option value="Green ">Bell-ASym</option>
        //     <option value="White ">Notch</option>
        //     </select>
        // Frequency : <input id="frequency_text" type="text"> 
        // Gain : <input id="gain_text" type="text" value="10"> 
        // Q : <input id="q_text" type="text" value="2.5 "></p>


        //INITIALIZE 12 PEQS
        // <div id="draggable1" class=" ui-widget-content ">
        // <p id="label1" class="labelEq">1</p>
        // </div>
        for(var i=0;i<eqCount;i++)
        {
            var divLabelGraphPEQ = document.createElement("div");
            divLabelGraphPEQ.id = "dragPEQ"+i;
            divLabelGraphPEQ.className = "circleEq";

            var bgCirclePEQ = document.createElement("div");
            bgCirclePEQ.className = "bgCircleEq";

            var labelGraphPEQ = document.createElement("p");
            labelGraphPEQ.id = "label"+i;
            labelGraphPEQ.className = "labelEq";

            var num = i+1;
            labelGraphPEQ.innerHTML= ""+num;
            $("#widgetParamEQ").append(divLabelGraphPEQ);
            
            var t = "#dragPEQ"+i;
            arrayEqParamDraggable[i] = $(t);
            
            arrayEqParamDraggable[i].append(bgCirclePEQ);
            arrayEqParamDraggable[i].append(labelGraphPEQ);

            // arrayEqParamDraggable[i].draggabilly({containment: "#graphWidgetPEQ"});
            // arrayEqParamDraggable[i].draggabilly();

            // drag[i] = $(".circleEq").draggabilly({containment: "#graphWidgetPEQ"});
            // drag[i].on("dragEnd",function(){
            //     console.log("dragend");
            // });
            // draggie[i] = drag[i].data("draggabilly");
            // drag[i].on("dragMove",function(){
            //     $.fn.drawWindows(draggie[i].position.x-15, draggie[i].position.y-3, 1)
            //     // console.log("ID: " + this.id + " // dragmoveX : " + draggie.position.x + " // dragmoveY : " + draggie.position.y);
            // });
        }

        for(var i=0;i<eqCount;i++)
        {
            var a = "#dragPEQ" + i;
            drag[i] = $(a).draggabilly({containment: "#graphWidgetPEQ"});
            drag[i].on("dragEnd",function(){
            //SEND EQ VALUES
            });
            draggie[i] = drag[i].data("draggabilly");
            drag[i].on("dragMove",function(){
            //FIND NUMBER IN ID (FROM 0 TO 11);
            var num = this.id.toString().match(/(\d+)/g).map(Number);
            $.fn.drawWindows(draggie[num].position.x, draggie[num].position.y, this.id);
            //EDIT GAIN TEXT FIELD AND GAIN VALUE
            var gain = "#gain_text"+num;
            arrayEqParam[num].gain = Math.round(gainFromY(draggie[num].position.y)*100)/100;
            $(gain).val(arrayEqParam[num].gain);
            //EDIT FREQUENCY TEXT FIELD AND GAIN VALUE
            var freq = "#freq_text"+num;
            arrayEqParam[num].frequency = Math.round(freqFromX(draggie[num].position.x));
            $(freq).val(arrayEqParam[num].frequency);
            });
        }
    });
    
    $(function () {
        for(var i=0; i<eqCount; i++)
        {
            arrayEqParam[i].frequency = eqFreqDefaultInit[i];
            // console.log("frequency ["+i+"]: " + arrayEqParam[i].frequency);
            arrayEqParamDraggable[i].draggabilly('setPosition',xFromFreq(arrayEqParam[i].frequency),yFromGain(arrayEqParam[i].gain));
            var gain = "#gain_text"+i;
            $(gain).val(arrayEqParam[i].gain);
            var freq = "#freq_text"+i;
            $(freq).val(arrayEqParam[i].frequency);
            var q = "#q_text"+i;
            $(q).val(arrayEqParam[i].q);
        }
    });

});

//RUN CODE WHEN PAGE IS COMPLETELY LOADED
$(window).bind("load", function() {
    $.fn.drawWindows(0,0,0);
 });

//REDRAW CURVES
$.fn.drawWindows = function(x, y, n) {
    // console.log("ID:" + n + " // X:" + Math.round(x*100)/100 + " // Y:" + Math.round(y*100)/100 + " // Freq:" + freqFromX(x) + " // gain:" + gainFromY(y));
    var c = document.getElementById("graphWidgetPEQ");
    var ctx = c.getContext("2d");
    ctx.strokeStyle = '#00a3e0';
    ctx.clearRect(0, 0, c.width, c.height);
    ctx.beginPath();
    ctx.lineWidth = 2;
    var a0,a1,a2,b1,b2;

    for(var i=0;i<1;i++)
    {
        var Fs = 48000;
        var V = Math.pow(10, Math.abs(arrayEqParam[i].gain) / 20);
        // displayVal("GAIN",arrayEqParam[i].gain);
        // displayVal("V",V);
        var K = Math.tan(Math.PI * arrayEqParam[i].frequency / Fs);
        // displayVal("FREQUENCY",arrayEqParam[i].frequency);
        // displayVal("K",K);
        var Q = arrayEqParam[i].q;
        
        // displayVal("Q",Q);
        if (arrayEqParam[i].gain >= 0) {
            norm = 1 / (1 + 1/Q * K + K * K);
            a0 = (1 + V/Q * K + K * K) * norm;
            a1 = 2 * (K * K - 1) * norm;
            a2 = (1 - V/Q * K + K * K) * norm;
            b1 = a1;
            b2 = (1 - 1/Q * K + K * K) * norm;
        }
        else {	
            norm = 1 / (1 + V/Q * K + K * K);
            a0 = (1 + 1/Q * K + K * K) * norm;
            a1 = 2 * (K * K - 1) * norm;
            a2 = (1 - 1/Q * K + K * K) * norm;
            b1 = a1;
            b2 = (1 - V/Q * K + K * K) * norm;
        }

        p1 = yZero;
        p2 = yZero;
    }
    ctx.moveTo(0, p1);

    // console.log("A0:" + a0 + " // A1:" + a1 + " // A2:" + a2 + " // B1:" + b1 + " // B2: " + b2);

    // for(var x=0;x<graphPEQWidth;x++)
    // {
    //     var f = freqFromX(x);
    //     f = Math.round(f);
    //     // displayVal("FREQ",f);
    //     // var len = 512;
    //     // var magPlot = [];
    //     // for (var idx = 0; idx < len; idx++) {
    //     var w;
    //     // if (plotType == "linear")
    //     //     w = idx / (len - 1) * Math.PI;	// 0 to pi, linear scale
    //     // else
    //     w = Math.exp(Math.log(1 / 0.001) * f / (graphPEQWidth - 1)) * 0.001 * Math.PI;	// 0.001 to 1, times pi, log scale
    //     // console.log("w" + w);
    //     var phi = Math.pow(Math.sin(w/2), 2);
    //     var y = Math.log(Math.pow(a0+a1+a2, 2) - 4*(a0*a1 + 4*a0*a2 + a1*a2)*phi + 16*a0*a2*phi*phi) - Math.log(Math.pow(1+b1+b2, 2) - 4*(b1 + 4*b2 + b1*b2)*phi + 16*b2*phi*phi);
    //     y = y * 10 / Math.LN10;
    //     // console.log("X=" + x + " // Y=" + y);
    //     // if (y == -Infinity)
    //     //     y = -200;

    //     // if (plotType == "linear")
    //     //     magPlot.push([idx / (len - 1) * Fs / 2, y]);
    //     // else
    //         // magPlot.push([idx / (len - 1) / 2, y]);

    //     if (y == 0)
    //         y = yZero;
    //     else if (y < -36)
    //         y = -36;
    //     else if (y > 18)
    //         y = 18;
    //     // }
    //     // displayValues("FREQ", f, "X",x);
    //     ctx.lineTo(x,yFromGain(y));//xFromFreq(f), yFromGain(y));
    //     // }
    //     // ctx.moveTo(0, yZero);
    //     // ctx.lineTo(draggie[i].position.x-22, draggie[i].position.y-1);
    //     // ctx.lineTo(graphPEQWidth, yZero);
    // }
    ctx.stroke();
};

//RETURN X VALUE FROM FREQUENCY IN PEQ
function xFromFreq(frequency) {
    var x = 0;
    var abc = graphPEQWidth / scale;
    x = Math.log10(frequency);
    return (x-1)*abc;       
}

//RETURN FREQ VALUE FROM X IN PEQ
function freqFromX(x) {
    // var ret;
    // ret = Math.log10(frequency);
    // ret = ret / ((Math.log10(22000) - 1) / 570);
    // ret = ret + 15;
    // return ret;
    var freq = 0;
    // console.log("scale:"+scale);
    var abc = (x/scale)+1;
    freq = Math.pow(10,abc);
    // console.log("x:"+x);
    // x = (graphPEQWidth/(Math.log10(22000)-1))*Math.log10(frequency) - 1/(Math.log10(22000)-1) * graphPEQWidth;
    //Math.round(freq*100)/100;

    var a = (Math.log10(22000) - 1);
    var b = a / graphPEQWidth;
    var c = x;
    c = c * b;
    c = c+1;
    c = Math.pow(10,c);

    return c;
}

//RETURN Y VALUE FROM GAIN IN PEQ
function yFromGain(gain) {
    var y = 0;
    y = -(graphPEQHeight/54)*gain + graphPEQHeight*(18/54);
    return y;
}

//RETURN GAIN VALUE FROM Y IN PEQ
function gainFromY(y) {
    var gain = 0;
    gain = (y-graphPEQHeight*(18/54))*-(54/graphPEQHeight);
    return Math.round(gain*100)/100;
}


function displayVal(a,b) {
    var text = "VAR " + a + " : ";
    console.log(text + b);
}
function displayValues(a,b,c,d) {
    var text = "VAR " + a + " : " + b + " \\ VAR " + c + " : " + d;
    console.log(text);
}


// case  0: return new FilterBellSymm      (*filter);
// case  1: return new FilterBellASymm     (*filter);
// case  2: return new FilterNotch         (*filter);
// case  3: return new FilterLowShelf1     (*filter);
// case  4: return new FilterLowShelf2     (*filter);
// case  5: return new FilterHighShelf1    (*filter);
// case  6: return new FilterHighShelf2    (*filter);
// case  7: return new FilterAllPass1      (*filter);
// case  8: return new FilterAllPass2      (*filter);
// case  9: return new FilterHighpass1     (*filter);
// case 10: return new FilterHighpass2     (*filter);
// case 11: return new FilterHighpass2VariQ(*filter);
// case 12: return new FilterLowpass1      (*filter);
// case 13: return new FilterLowpass2      (*filter);
// case 14: return new FilterLowpass2VariQ (*filter);
// case 15: return new FilterBandpass2     (*filter);

// // Filter #0: Bell Symmetric
// class FilterBellSymm : public FilterIIRSingle
// {
// public:
//   FilterBellSymm (double fx, double G, double Q) : FilterIIRSingle(fx, G, Q) {}
//   FilterBellSymm (const Filter& ref) : FilterIIRSingle(ref) {}

//   int  Type()              const { return 0; }
//   bool HasAdjustableGain() const { return true; }
//   bool HasAdjustableQ()    const { return true; }

// private:
//   void CalcCoefficients() const;
// };

// // Filter #0: Bell Symmetric
// function FilterBellSymm::CalcCoefficients() const
// {
//   // Standard biquad, both numerator and denominator 2nd order

//   var A     = pow(10,_A/20);
//   var wx    = M_PI*_f;
//   var w0    = 2*wx;
//   var c0    = cos(w0);
//   var sx    = sin(wx);
//   var alpha = sx*sx/(wx*_Q);

//   if (A >= 1)
//   {
//     var beta = A*alpha;
//     var k    = -2*c0;

//     _b[0] = 1+beta;
//     _b[1] = k;
//     _b[2] = 1-beta;
//     _a[0] = 1+alpha;
//     _a[1] = k;
//     _a[2] = 1-alpha;
//   }
//   else
//   {
//     var beta = alpha/A;
//     var k    = -2*c0;

//     _b[0] = 1+alpha;
//     _b[1] = k;
//     _b[2] = 1-alpha;
//     _a[0] = 1+beta;
//     _a[1] = k;
//     _a[2] = 1-beta;
//   }
// }