function Joist(depth,width,ei,ga,idx300,idx400,idx480,idx600) {
    this.depth = depth;
    this.width = width;
    this.ei = ei;
    this.ga = ga;
    this.idx300 = idx300;
    this.idx400 = idx400;
    this.idx480 = idx480;
    this.idx600 = idx600;

    this.flange = 'X';

    if (this.width == 47) {
        this.flange = 'A+';
    } else if (this.width == 63) {
        this.flange = 'B+';
    } else if (this.width == 72) {
        this.flange = 'C';
    } else if (this.width == 97) {
        this.flange = 'D';
    } else {
        this.flange = 'X';
    }

    this.getDeflection = function(span,load) {
        var w = load;
        var L = span;
        var EI = this.ei * Math.pow(10,9);
        var GA = this.ga * Math.pow(10,6);

        var lt = 5 * w * L*L*L*L;
        var lb = 384 * EI;
        var rt = w * L*L;
        var rb = 8 * GA;

        var l = lt / lb;
        var r = rt / rb;

        var deflection = l + r;

        return Math.ceil(deflection*100)/100;
    }
}

function generateJoists() {
    var data = new Array(26);
        data[0] = new Joist(145,47,139,0.55,0,0,0,0);    //  145 A

        data[1] = new Joist(195,47,305,0.90,50,20,10,1);    //  195 A
        data[2] = new Joist(195,63,424,0.90,60,33,17,4);    //      B
        data[3] = new Joist(195,72,505,0.98,64,37,19,6);    //      C
        data[4] = new Joist(195,97,740,0.98,80,54,38,16);   //      D

        data[5] = new Joist(220,47,407,1.08,57,30,13,2);    //  220 A
        data[6] = new Joist(220,63,588,1.08,68,41,22,8);    //      B
        data[7] = new Joist(220,72,667,1.17,79,53,36,15);   //      C
        data[8] = new Joist(220,97,941,1.17,88,69,49,28);   //      D

        data[9] = new Joist(235,47,472,1.19,58,32,14,3);    //  235 A
        data[10] = new Joist(235,63,678,1.19,71,43,25,9);   //      B
        data[11] = new Joist(235,72,771,1.29,83,56,42,20);  //      C
        data[12] = new Joist(235,97,1088,1.29,92,75,55,35);  //      D

        data[13] = new Joist(245,47,518,1.26,61,34,18,5);   //  245 A
        data[14] = new Joist(245,63,737,1.26,73,45,27,11);  //      B
        data[15] = new Joist(245,72,844,1.36,84,62,46,24);  //      C
        data[16] = new Joist(245,97,1195,1.36,94,81,65,44);  //      D

        data[17] = new Joist(300,47,816,1.65,67,39,21,7);   // 300  A
        data[18] = new Joist(300,63,1121,1.65,76,47,31,12);  //      B
        data[19] = new Joist(300,72,1319,1.77,87,66,48,26); //      C
        data[20] = new Joist(300,97,1899,1.77,97,85,74,52); //      D

        data[21] = new Joist(350,72,1899,2.15,89,70,51,29); // 350  C
        data[22] = new Joist(350,97,2647,2.15,98,91,82,63); //      D

        data[23] = new Joist(400,72,2673,2.53,93,77,59,40); // 400  C
        data[24] = new Joist(400,97,3428,2.53,99,95,86,72); //      D

        data[25] = new Joist(450,97,4170,2.90,100,96,90,78);   // 450  D

        return data;
}











function calc() {

    //
    //  Calculate the Engineering Span
    //
    var inSpan = parseFloat(document.getElementById("in_span").value);  // Get the Clear Span
    var radSupports = document.getElementsByName("rad_supports");       // Find the modification values
    var supportMod = 0;                                                 // Set up our mod. value
    for (var i = 0; i < radSupports.length; i++) {                      // For each possible value
        if (radSupports[i].checked) {                                   // See if it is selected
            supportMod = parseFloat(radSupports[i].value);              // Set it as the mod value
        }
    }
    var span = inSpan + supportMod;                                     // Combine values to get eng. span


    //
    //  Decide the Floor Loading
    //
    var radLoading = document.getElementsByName("rad_loading");         // Find all the loads
    var loading = 0;                                                    // Set up our load holder
    for (var i = 0; i < radLoading.length; i++) {                        // For each of the loads
        if (radLoading[i].checked) {                                    // See if it is selected
            loading = parseFloat(radLoading[i].value);                  // Set it as the load
        }
    }



    //
    //  Calculate the Deflection Limit
    //
    var absLimit = 12;                                                  // Set the absolute defln limit
    var facLimit = span * 0.003;                                        // Set the factor defln limit
    var limit = 12;                                                     // Set up the default limit
    if( absLimit > facLimit ) {                                         // If the abs. > fac. limit
        limit = facLimit;                                               // set the fac. limit as the limit
    } else {                                                            // if not
        limit = absLimit;                                               // set the abs. limit as the limit
    }



    var j = -1;
    results = new Array();

    for (var i = 0; i < joists.length; i++) {
        var load = 0;
        var defln = 0;
        load = loading * ( 600 / 1000 );
        defln = joists[i].getDeflection(span, load);
        if (defln <= limit) {
            j++;
            results[j] = new Array (joists[i].depth, joists[i].flange, joists[i].width, 600, defln, Math.floor(limit/defln*100)/100, joists[i].idx600);
        } else {
            load = loading * ( 480 / 1000 );
            defln = joists[i].getDeflection(span, load);
            if (defln <= limit) {
                j++;
                results[j] = new Array (joists[i].depth, joists[i].flange, joists[i].width, 480, defln, Math.floor(limit/defln*100)/100, joists[i].idx480);
            } else {
                load = loading * ( 400 / 1000 );
                defln = joists[i].getDeflection(span, load);
                if (defln <= limit) {
                    j++;
                    results[j] = new Array (joists[i].depth, joists[i].flange, joists[i].width, 400, defln, Math.floor(limit/defln*100)/100, joists[i].idx400);
                } else {
                    load = loading * ( 300 / 1000 );
                    defln = joists[i].getDeflection(span, load);
                    if (defln <= limit) {
                        j++;
                        results[j] = new Array (joists[i].depth, joists[i].flange, joists[i].width, 300, defln, Math.floor(limit/defln*100)/100, joists[i].idx300);
                    }
                }
            }
        }
    }

}

















function displayResults( target, okJoists, start ){
    var out = document.getElementById( target );                        // Select our output area

    var range = 5;
    var end = start+range;
    if ( end > okJoists.length ) {
        end = okJoists.length;
    }

    var pages = Math.ceil( okJoists.length / range);
    var page = Math.ceil( start / range) + 1;

    var data = '';

    if (pages > 0) {

        data += '   <table id="results" align="center">';
        data += '       <thead>';
        data += '           <tr>';
        data += '               <td width="65px">Joist</td>';
        data += '               <td>Size</td>';
        data += '               <td>Max. Centres</td>';
        data += '               <td>Deflection</td>';
        data += '               <td>SI</td>';
        data += '               <td>Cost Index</td>';
        data += '           </tr>';
        data += '       </thead>';
        data += '       <tbody>';

        for ( var i = start; i < end; i++ ) {
            data += '       <tr>';
            data += '           <td id="title">JJI ' + okJoists[i][0] + okJoists[i][1] + '</td>';
            data += '           <td> ' + okJoists[i][0] + 'x' + okJoists[i][2] + ' </td>';
            data += '           <td>' + okJoists[i][3] + ' mm</td>';
            data += '           <td>' + to2DecimalPlaces(okJoists[i][4]) + '</td>';
            data += '           <td>' + to2DecimalPlaces(okJoists[i][5]) + '</td>';
            data += '           <td>' + okJoists[i][6] + '</td>';
            data += '       </tr>';
        }


        data += '<tr><td colspan="6">Page ' + page + ' of ' + pages + ' page(s) of results.</td></tr>';
        data += '<tr><td colspan="6">Jump to page ';


        for ( var i = 0; i < pages; i++ ) {
            var startNum = i * range;
            data += '<a href="javascript://" onclick="displayResults(\'' + target + '\', results, ' + startNum + ');return true;" >&nbsp;' + (i+1) + '&nbsp;</a>';
            if ( i == pages - 1 ) {
                data += '. ';
            } else {
                data +=  ', ';
            }
        }

        data += '</td></tr>';
        data += '<tr><td colspan="6"><span class="explanation"><a href="javascript://" onClick="setOverlay();displayNotes();return true;">See Guidance Notes.</a></span></td></tr>';

        data += '       </tbody>';
        data += '   </table>';

    } else {
        data += '<br>There are no joists suitable for this clear span and loading combination. Please visit the Downloads section of our website and install JoistMaster which will allow you to specify any intermediate supports available for use or specify JJ-Glulam.';
    }

    out.innerHTML = data;
}






function to2DecimalPlaces(original){
	var source = original + '';
	var decimal = source.lastIndexOf('.');
	var pointat = source.length - decimal;
	
	if (decimal == -1) {
		source = source + '.00'
	} else {
		if (pointat == 2) {
			source = source + '0';
		} else if (pointat == 1) {
			source = source + '00'
		} else if (pointat ==3 ){
			source = source
		} else {
			source = source + '.00'
		}
	}
	
	return source;
}









function display() {
    displayResults("output",results,0);
}





function checkSpan() {
    var radSupports = document.getElementsByName("rad_supports");       // Find the modification values
    var supportType = 0;
    for (var i = 0; i < radSupports.length; i++) {                      // For each possible value
        if (radSupports[i].checked) {                                   // See if it is selected
            supportType = i;
        }
    }

    if (supportType == 0) {
        if ( parseFloat(document.getElementById("in_span").value) < 1 ) {
            document.getElementById("in_span").value = 1;
        }
        if ( parseFloat(document.getElementById("in_span").value) > 11800 ) {
            document.getElementById("in_span").value = 11800;
        }
    } else {
        if ( parseFloat(document.getElementById("in_span").value) < 151 ) {
            document.getElementById("in_span").value = 151;
        }
       if ( parseFloat(document.getElementById("in_span").value) > 12000 ) {
            document.getElementById("in_span").value = 12000;
        }
    }
}







function changeSupports(support) {

var offset = 0;

 if (support == 'hang') {
     offset = 2;
 } else {
     offset = 0;
 }

 document.getElementById("sup_left").src =preload[offset].src;
 document.getElementById("sup_right").src = preload[offset+1].src;

}

function sort() {
    function sizeAsc(a1, a2) {
        return  a1[0] < a2[0] ? -1 :
                a1[0] > a2[0] ? 1 :
                a1[1] < a2[1] ? -1 :
                a1[1] > a2[1] ? 1 : 0;
    }

    function sizeDesc(a1, a2) {
        return  a1[0] > a2[0] ? -1 :
                a1[0] < a2[0] ? 1 :
                a1[1] > a2[1] ? -1 :
                a1[1] < a2[1] ? 1 : 0;
    }

    function costAsc(a1, a2) {
        return  a1[6] < a2[6] ? -1 :
                a1[6] > a2[6] ? 1 : 0;
    }

    function costDesc(a1, a2) {
        return  a1[6] > a2[6] ? -1 :
                a1[6] < a2[6] ? 1 : 0;
    }

    var radKind = document.getElementsByName("rad_sort_kind");
    var kind = 0;
    for (var i = 0; i < radKind.length; i++) {
        if (radKind[i].checked) {
            kind = i;
        }
    }

    var radOrder = document.getElementsByName("rad_sort_order");
    var order = 0;
    for (var i = 0; i < radOrder.length; i++) {
        if (radOrder[i].checked) {
            order = i;
        }
    }

    if (kind == 1) {
        if (order == 1) {
            results.sort(costDesc);
        } else {
            results.sort(costAsc);
        }
    } else {
        if (order == 1) {
            results.sort(sizeDesc);
        } else {
            results.sort(sizeAsc);
        }
    }
}

function theMotions() {
    checkSpan();
    calc();
    sort();
    display();
    return true;
}

function sortAndGo() {
    sort();
    display();
    return true;
}


function setOverlay() {
	var overlay = document.getElementById('overlay_bg');
    overlay.style.width = "100%";
    overlay.style.height = "100%";
}

function clearOverlay() {
	var overlay = document.getElementById('overlay_bg');
    overlay.style.width = "0px";
    overlay.style.height = "0px";
}

function displayHelp() {
	var out = document.getElementById('overlay_content');
	out.innerHTML = '';
	out.innerHTML += '<p>This application will specify a list of acceptable JJI-Joists once you enter your support conditions, load case and clear span.</p>';
	out.innerHTML += '<p>Once these have been entered, the joists suitable for this application appear in the table below. They can then be sorted by either Size or Cost and in either Ascending or Descending order.</p>';
	out.innerHTML += '<p>Where more than six different joists sizes are suitable, they are split onto separate pages. At the bottom of the window, you can select which page of results you wish to view.</p>';
}

function displayNotes() {
	var out = document.getElementById('overlay_content');
	out.innerHTML = '';
	out.innerHTML += '<p>This application assumes the following:</p>';
	out.innerHTML += '<p>House Loading: 0.75kN/m<sup>2</sup> Dead Load + 1.5kN/m<sup>2</sup> Imposed Load.</p>';
	out.innerHTML += '<p>Flat Loading: 1.15kN/m<sup>2</sup> Dead Load + 1.5kN/m<sup>2</sup> Imposed Load.</p>';
	out.innerHTML += '<p>Deflection Limit: 0.003 x engineering span or 12mm whichever is lesser.</p>';
	out.innerHTML += '<p>It is assumed that for "Built-In" joists that the masonry is 100mm wide and for joists "On Hangers" the hanger has a 75mm bottom plate.</p>';
	out.innerHTML += '<p>"Max. Centres" is the maximum centres that this joist can be used for in this application. If a joist\'s "Max. Centres" is 600mm then the joist can be used at 300mm, 400mm, 480mm and 600mm centres. If it\'s Max. Centres is 300mm then it can only be used at 300mm centres.</p>';
	out.innerHTML += '<p>Cost Index is a rough estimate of the order of Joists and Centres, from cheapest to most expensive, based on RRP.</p>';
	out.innerHTML += '<p>These calculations are only to be used as a guide and for any further use including multi-span, multi-ply or non-uniformly loaded joists you should refer to JoistMaster, available from our Downloads section.</p>';
}
