function done() {
    document.getElementById("status").innerHTML = "";
}

function init(number) {
        preset_voyager();
	document.getElementById("framelength").value = "2048";
}

function preset_voyager() {
        document.getElementById("voyager").checked = true;
        document.getElementById("rate").value = "2";
        document.getElementById("K").value = "7";
        document.getElementById("P1").value = "109";
        document.getElementById("P2").value = "79";
        codeparams_lock();
}

function preset_nasadsn() {
        document.getElementById("rate").value = "2";
        document.getElementById("K").value = "7";
        document.getElementById("P1").value = "91";
        document.getElementById("P2").value = "79";
        codeparams_lock();
}

function preset_nasagsfc() {
        document.getElementById("rate").value = "2";
        document.getElementById("K").value = "7";
        document.getElementById("P1").value = "79";
        document.getElementById("P2").value = "91";
        codeparams_lock();
}

function preset_wimax() {
        document.getElementById("rate").value = "2";
        document.getElementById("K").value = "7";
        document.getElementById("P1").value = "121";
        document.getElementById("P2").value = "91";
        codeparams_lock();
}

function preset_cdma() {
        document.getElementById("rate").value = "2";
        document.getElementById("K").value = "9";
        document.getElementById("P1").value = "491";
        document.getElementById("P2").value = "369";
        codeparams_lock();
}

function preset_lte() {
        document.getElementById("rate").value = "3";
        document.getElementById("K").value = "7";
        document.getElementById("P1").value = "91";
        document.getElementById("P2").value = "117";
        document.getElementById("P3").value = "121";
        codeparams_lock();
}

function preset_uwb() {
        document.getElementById("rate").value = "3";
        document.getElementById("K").value = "7";
        document.getElementById("P1").value = "121";
        document.getElementById("P2").value = "117";
        document.getElementById("P3").value = "91";
        codeparams_lock();
}

function preset_cdma2k() {
        document.getElementById("rate").value = "4";
        document.getElementById("K").value = "9";
        document.getElementById("P1").value = "501";
        document.getElementById("P2").value = "441";
        document.getElementById("P3").value = "331";
        document.getElementById("P4").value = "315";
        codeparams_lock();
}

function preset_cassini() {
        document.getElementById("rate").value = "6";
        document.getElementById("K").value = "15";
        document.getElementById("P1").value = "17817";
        document.getElementById("P2").value = "20133";
        document.getElementById("P3").value = "23879";
        document.getElementById("P4").value = "30451";
        document.getElementById("P5").value = "32439";
        document.getElementById("P6").value = "26975";
        codeparams_lock();
}

function preset_mars() {
        document.getElementById("rate").value = "6";
        document.getElementById("K").value = "15";
        document.getElementById("P1").value = "17817";
        document.getElementById("P2").value = "20133";
        document.getElementById("P3").value = "30451";
        document.getElementById("P4").value = "23879";
        document.getElementById("P5").value = "32439";
        document.getElementById("P6").value = "26975";
        codeparams_lock();
}

function codeparams_lock(){
        document.getElementById("rate").disabled = false;
        document.getElementById("K").disabled = false;
        hide_polys(document.getElementById("rate").value);
        var i = 1;
        for (i=1; i<=6; i++)
              document.getElementById("P"+i).disabled = false;
	validatePolys();
}

function preset_custom() {
        document.getElementById("rate").disabled = false;
        document.getElementById("K").disabled = false;
        hide_polys(document.getElementById("rate").value);
        var i = 1;
        for (i=1; i<=6; i++)
              document.getElementById("P"+i).disabled = false;
}

function hide_polys(r) {
        var i = 1;
        for (i=1; i<=parseInt(r); i++)
              document.getElementById("P"+i).style.visibility = 'visible';
        for (i=parseInt(r)+1; i<=6; i++){
              document.getElementById("P"+i).style.visibility = 'hidden';
	      document.getElementById("P"+i).value = "1";
	}
}

function jumptocustom() {
	document.getElementById("custom").checked = true;
}

function validateRate() {
        if (justnumbers(document.getElementById("rate").value)){
                var r = parseInt(document.getElementById("rate").value);
                if ((r>=2)&&(r<=6))
                        return true;
        }
	return false;
}

function newrate() {
	jumptocustom();
	if (validateRate()){
               hide_polys(document.getElementById("rate").value);
	}else{
              alert("Error: Rate must be a fraction between 1/2 and 1/6");
        }
}

function validateK(){
        if (justnumbers(document.getElementById("K").value)){
                var r = parseInt(document.getElementById("K").value);
                if ((r>=6)&&(r<=20))
                        return true;
        }
	return false;
}

function newK() {
	jumptocustom();
	if (validateK()){
               validatePolys();
	}else{
              alert("Error: K must be an integer between 6 and 20");
        }
}


function newP() {
        var i = 1;
	jumptocustom();
        var validate = true;
        for (i=1; i<=parseInt(document.getElementById("rate").value); i++){
        	if ((!justnumbers(document.getElementById("P"+i).value))||(parseInt(document.getElementById("P"+i).value)<1))
			validate = false;
	}
        if (!validate){
              alert("Error: Polynomials must be odd integers between 2^(K - 1) and 2^K - 1");
        }
        else 
               validatePolys();
}

function validatePolys() {
        var i = 1;
	var k = parseInt(document.getElementById("K").value);
	var validate = true;
        for (i=1; i<=parseInt(document.getElementById("rate").value); i++){
		var p = parseInt(document.getElementById("P"+i).value); 
		if ( (p >= Math.pow(2,k)) || (p <= Math.pow(2,k-1)) || (p % 2 == 0))
			validate = false;
	}
	if (!validate){
		document.getElementById("comment").innerHTML = "Error: Polynomials must be odd integers between 2^(K - 1) and 2^K - 1";
		return false;
	}
	else{
		document.getElementById("comment").innerHTML = "";
		return true;
	}
}	


function justnumbers(s) {
        if (s.match(/^\d+$/) == null)
                return false;
        else
                return true;
}

function resetText() {
        preset_voyager();
	document.getElementById("framelength").value = "2048";
}

function validateFL(){
        if (justnumbers(document.getElementById("framelength").value)){
                var r = parseInt(document.getElementById("framelength").value);
                if (r>=1)
                        return true;
        }
	return false;
}

function newFL() {
	if (validateFL()){
              ;
	}else{
              alert("Error: Frame Length must be an integer bigger than 1");
        }
}

function validateAll() {
	if (!validateRate()) {
	alert("Error: Rate must be a fraction between 1/2 and 1/6");
	return false;
	}
	if (!validateK()) {
	alert("Error: K must be an integer between 6 and 20");
	return false;
	}
	if (!validatePolys()) {
	alert("Error: Polynomials must be odd integers between 2^(K - 1) and 2^K - 1");
	return false;
	}
	if (!validateFL()) {
	alert("Error: Frame length must be an integer bigger than 1");
	return false;
	}
	return true;
}

function go() {
    if  (!validateAll()) {
	return;
    }
    var rate = document.getElementById("rate").value;
    var K = document.getElementById("K").value;
    var P1 = document.getElementById("P1").value;
    var P2 = document.getElementById("P2").value;
    var P3 = document.getElementById("P3").value;
    var P4 = document.getElementById("P4").value;
    var P5 = document.getElementById("P5").value;
    var P6 = document.getElementById("P6").value;
    var framelength = document.getElementById("framelength").value;
    var isa = document.getElementById("isa").value;

    newwindow = window.open('http://spiral.ece.cmu.edu/vitgen/gen.php?'
                + 'rate='+rate
		+ '&K='+K
		+ '&P1='+P1
		+ '&P2='+P2
		+ '&P3='+P3
		+ '&P4='+P4
		+ '&P5='+P5
		+ '&P6='+P6
		+ '&framelength='+framelength
		+ '&isa='+isa,
	'gen', "resizable, scrollbars, height = 450, width = 450");

    if (window.focus) {
	newwindow.focus();
    }
}

function est() {
}


function newWindow(url, name) {
    var newWindow;
    newWindow = open(url, name, "resizable, scrollbars, height = 250, width = 450")
}

function newWindowBig(url, name) {
    var newWindow;
    newWindow = open(url, name, "resizable, scrollbars, height = 400, width = 752")
}



function nChange() {
    updateP();
    updateFIFO();
    est();
}

function widthChange() {
    updateTWidth();
    updateFIFO();
    est();
}


function pChange() {
    updateFIFO();
    est();
}

function updateTWidth() {
    
    var p = document.getElementById("idP").value;
    var width_index = document.getElementById("idWidth").selectedIndex;

    var twSelect = document.getElementById("idTWidth");

    //if width is decreasing, get rid of twiddleWidth values > width
      var count=0;
    for (i=twSelect.options.length; i>width_index+2; i--) {
        if (twSelect.options[i] != null) {
            if (twSelect.options[i].selected == true)
              count++;
        }
        twSelect.options[i] = null;
        
    }

    var length = twSelect.options.length;
    var length2 = length;

    if (count != 0)
      twSelect.options[length-1].selected=true;


    var foo=(twSelect.options[length-1].value);
    var foo2= foo-0;
    foo2 = foo2+2;

    for (i=foo2; i<=(document.getElementById("idWidth").value); i=i+2) {
        twSelect.options[length2] = new Option(i, i);
        length2++;
    }

    // update twiddle width range
      text = "2&ndash;";
    text = text + (i-2);
    document.getElementById("tRange").innerHTML = text;

}

function updateFIFO() {

    var p = document.getElementById("idP").value;
    var n = document.getElementById("idN").value;
    
    var width = document.getElementById("idWidth").value;

    fifoSelect = document.getElementById("idFIFO");

    // Clear FIFO select values
      var count = 0;
    for (i=fifoSelect.options.length; i >= 0; i--) 
      fifoSelect.options[i] = null;   

    var length = 0;

    // add new FIFO values  
      for (i=2; i <= n/(2*p); i=i*2) {
//          var txt = i + " (" + getbramFIFO(i) + ", " + slicesAllFIFOS(2*width, i, n, p) + ")";
        var txt = i;
          fifoSelect.options[length] = new Option(txt,i);
          length++;
      }
    
    // if p == n/2, we have no FIFOs at all
      if (p == (n/2)) {
          fifoSelect.options[fifoSelect.options.length] = new Option("No FIFOs used", 1);
          text = "No FIFOs used";
          fifoSelect.options[fifoSelect.options.length-1].selected = 1;
      }
      else {
          text = "2&ndash;";
          text = text + (i/2);
      }
    
    document.getElementById("fRange").innerHTML = text;
    
}

function updateP() {

    n_index = document.getElementById("idN").selectedIndex;
    n = document.getElementById("idN").value;

    //  alert(n_index);
    //  alert(n);

    pSelect = document.getElementById("idP");
    var count=0;

    // if n is decreasing, get rid of p values > n/2
      for (i=pSelect.options.length; i>n_index+1; i--) {
          if (pSelect.options[i] != null) {
              if (pSelect.options[i].selected == true)
                count++;
          }
          pSelect.options[i] = null;
      }
    
    var length = pSelect.options.length;        
    var length2 = length; 

    // if the previously-selected p value cannot be selected due to a change in n,
    // select the largest p possible for this n size.
      if (count != 0)
        pSelect.options[length-1].selected=true;

    // if n is increasing, add p values <= n/2
      for (i=(pSelect.options[length-1].value)*2; i<=n/2; i=i*2) {
          pSelect.options[length2] = new Option(i, i);
          length2++;
      }

    // write range of p
      var text = "1&ndash;";
    text = text + (i/2);
    document.getElementById("pRange").innerHTML = text;

}

function getbramFIFO(thresh) {
    var i=4;
    var n = document.getElementById("idN").value;
    var p = document.getElementById("idP").value;
    var totBRAMS = 0;
    var w = document.getElementById("idWidth").value;
    if (w <= 8)
      w = 8;
    else if (w <= 16)
      w = 16;
    else if (w <= 32)
      w = 32;   

    var totBRAMS = 0;
    for (i=4; i <= n/p; i=i*2) {
        totBRAMS += sizeFIFO(thresh, i, w);
    }

    return totBRAMS*p;
}

function bramFIFO() {
    var thresh = document.getElementById("idFIFO").value;

        var i=4;
        var n = document.getElementById("idN").value;
        var p = document.getElementById("idP").value;
        var totBRAMS = 0;
        var w = document.getElementById("idWidth").value;
        if (w <= 8)
          w = 8;
        else if (w <= 16)
          w = 16;
        else if (w <= 32)
          w = 32;   

        var totBRAMS = 0;
        for (i=4; i <= n/p; i=i*2) {
            totBRAMS += sizeFIFO(thresh, i, w);
        }

}

function sizeFIFO(thresh, m, width) {
    var usage, temp_size;

    if (m/4 >= thresh) {
        usage = m/4;        
        usage = 2*numBRAMS_FIFO(usage, width);
        if (2*width == 64)
          usage *= 2;
        return usage;
    }
    else {
        return 0;
    }
}

function numBRAMS_FIFO(size, width) {
    if (2*width == 16) {
        var t = size/1024;
        if (size <= 512) {
            return Math.ceil(t);
        }
        else {
            return 2*Math.ceil(t);
        }
    }
    else if (2*width == 32 || 2*width == 64) {
        t = size/512;
        return Math.ceil(t);
    }
}

function calcTwiddleROMS() {
    if (document.getElementById("idTwiddle").value == 0)
      var numb = 0;

    else {
        var size = findROMSize();

        twidth = document.getElementById("idTWidth").value;
        
        if (twidth <= 8)
          twidth = 8;
        else if (twidth <= 16)
          twidth = 16;
        else
          twidth = 32;

        var numb = numBRAMs(size, twidth);
        numb = numb * document.getElementById("idP").value;
    }

    if (numb == 1)
      var text = "1 BRAM used";
    else
      var text = numb + " BRAMs used";
    
    document.getElementById("tBRAMS").innerHTML = text;
}

function findROMSize() {
    var n = document.getElementById("idN").value;
    var p = document.getElementById("idP").value;
    var romSize;
    var logN = Math.log(n) / Math.LN2;

    //update the number of block RAMs used by twiddles  
      if (p > logN) {
          romSize = n*logN/(2*p);   
          romSize = Math.log(romSize) / Math.LN2;
          romSize = Math.ceil(romSize);
          romSize = Math.pow(2, romSize);
          return romSize;
      }
      else 
        return n/2;        
}

function numBRAMs(size, width) {
    var counter = 0;
    var temp, t;

    if (width == 8) {
        t = size/2048;
        if (size <= 1024)
          return Math.ceil(t);
        else
          return Math.ceil(t)*2;
    }

    else if (width == 16) {
        t = size/1024;
        if (size <= 512)
          return Math.ceil(t);
        else
          return Math.ceil(t)*2;
    }

    else if (width == 32) {
        t = size/512;
        if (size <= 256)
          return Math.ceil(t);
        else
          return Math.ceil(t)*2;
    }
}

function slices_FIFO(width, depth) {
    if (depth <= 32)
      return width;
    else {
        var temp = Math.log(depth)/Math.LN2;
        temp = Math.ceil(temp);
        temp -= 4;
        temp = Math.pow(2, temp);
        return temp*width;
    }
}

function slicesAllFIFOS(width, threshold, n, p) {
    var m;
    var slices = 0;
    for (m = 4; m <= n/p; m = m*2) {
        var depth = m/4;        
        if (depth < threshold) {
            slices += 2*slices_FIFO(width, depth);
        }
    }

    return slices;
}

