function drawRamp() {
    if (modules.length === 0) {
        stage.batchDraw();
        return;
    }

    let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
    for (let i = 0; i < modules.length; i++) {
        minX = Math.min(minX, modules[i].x());
        minY = Math.min(minY, modules[i].y());
        maxX = Math.max(maxX, modules[i].x() + modules[i].width());
        maxY = Math.max(maxY, modules[i].y() + modules[i].height());
    }

    const pad = 50;
    const rampWidth = maxX - minX;
    const availW    = stage.width() - 2 * pad;
    const scale     = rampWidth > availW ? availW / rampWidth : 1;

    layer.scale({ x: scale, y: scale });
    layer.position({
        x: (stage.width() - rampWidth * scale) / 2 - minX * scale,
        y: pad - minY * scale,
    });

    stage.batchDraw();
}

function addModule(mod_name, mod_image, layer){
    index = modules.length;

    // Check compatibility
    if (!isCompatible(mod_name, last_mod, connect_dir) ) {
        return notCompatibleError();
    }

    // Reuse the already-decoded DOM img element from the module tab.
    // Creating a new Image() and reading naturalWidth synchronously returns 0
    // whenever the image isn't already decoded in memory, causing Konva to
    // fall back to the full intrinsic image size.
    var imageObj = document.getElementById(mod_name);

    var doubleScale = (
        mod_name == 'Module1N' || mod_name == 'Module1S' ||
        mod_name == 'Module1W' || mod_name == 'Module1E' ||
        mod_name == 'Module7BN' || mod_name == 'Module7BS' ||
        mod_name == 'Module7BW' || mod_name == 'Module7BE'
    );
    var imgWidth  = imageObj.naturalWidth  / (doubleScale ? 5 : 10);
    var imgHeight = imageObj.naturalHeight / (doubleScale ? 5 : 10);
    var drag = false;

    // This is the basic new module creation object
    modules[index] = new Konva.Image({
        x: connect_x,
        y: connect_y,
        image: imageObj,
        width: imgWidth,
        height: imgHeight,
        draggable: drag,
        name: mod_name
    });

    // Increase stage size if necessary to accommodate ramp
    modifyStageSize(index);

    // Remove object
    modules[index].on("dblclick dbltap", function() { removeLastModule(); });

    last_mod = mod_name;

    adjustPosition(modules[index], connect_dir);
    updateDirection(modules[index], connect_dir);

    directions[index]        = connect_dir;
    connect_x_history[index] = connect_x;
    connect_y_history[index] = connect_y;
    last_mod_history[index]  = last_mod;

    updateInfoBox();
    modifyStageSize(index);

    return modules[index];
}

function removeLastModule() {
    if (modules.length === 0) return;

    const i    = modules.length - 1;
    const prev = i - 1;

    modules[i].remove();

    connect_dir = directions[prev];
    connect_x   = connect_x_history[prev];
    connect_y   = connect_y_history[prev];
    last_mod    = last_mod_history[prev];

    modules.pop();
    updateInfoBox();

    if (modules.length) {
        toggleCompatibleModules(modules[prev].attrs.name);
    } else {
        document.querySelectorAll('#tabs li').forEach(function(tab) {
            if (tab.dataset.modType && tab.dataset.modType !== 'entry') {
                tab.style.display = 'none';
            } else {
                tab.style.display = '';
                const modId = tab.dataset.mod;
                if (modId) {
                    document.querySelectorAll('#' + modId + ' img').forEach(img => img.style.display = '');
                }
            }
        });
        checkRampComplete();
    }

    drawRamp();
    updateModuleList();

    if (prev < 0) location.reload();
}


// Measuring tool, check mouse down/move
moving = false;
var changes = 0;
background.on('mousedown', function(){
    if (moving) {
        moving = false;
        if(horizontal_dimension_selected){
            deactivateHorizontalDimension();
        }else if(vertical_dimension_selected){
            deactivateVerticalDimension();
        }
        layer.draw();
        measureLayer.draw();
    } else {
        if(horizontal_dimension_selected || vertical_dimension_selected){
            group_id += 1;
            group = new Konva.Group({
                id: group_id,
                draggable: true
            });

            group.on('click tap', function() {
                if (moving) {
                    moving = false;
                    if (horizontal_dimension_selected) {
                        deactivateHorizontalDimension();
                    } else if (vertical_dimension_selected) {
                        deactivateVerticalDimension();
                    }

                    layer.draw();
                    measureLayer.draw();
                }
            });

            group.on('mouseover', function() {
                document.body.style.cursor = 'move';
            });
            group.on('mouseout', function() {
                document.body.style.cursor = 'default';
            });

            group.on('dblclick dbltap', function() {
                this.hide();
                deactivateHorizontalDimension();
                deactivateVerticalDimension();
                measureLayer.draw();
            });


            var mousePos = stage.getPointerPosition();

            rect= new Konva.Rect({
                x: 22,
                y: 7,
                width: 10,
                height: 10,
                fill: 'gray',
                stroke: 'gray',
                strokeWidth: 2
            });

            measure = new Konva.Text({
                x: stage.width() / 2,
                y: 75,
                text: 'measure',
                fontSize: 20,
                fontFamily: 'Calibri',
                fill: 'black',
                align: 'center'
            });

            measure_bkg= new Konva.Rect({
                x: 0,
                y: 0,
                width: 43,
                height: 25,
                fill: 'white',
                stroke: 'white',
                strokeWidth: 1
            });

            endLine1 = new Konva.Rect({
                x: 22,
                y: 7,
                width: 0,
                height: 0,
                fill: 'gray',
                stroke: 'gray',
                strokeWidth: 2
            });

            endLine2 = new Konva.Rect({
                x: 22,
                y: 7,
                width: 0,
                height: 0,
                fill: 'gray',
                stroke: 'gray',
                strokeWidth: 2
            });


            //start point and end point are the same
            rect.x(mousePos.x);
            rect.y(mousePos.y);
            rect.width(0);
            rect.height(0);

            measure_bkg.x(measure.x());
            measure_bkg.y(measure.y());

            measure.text(mousePos.x);
            measure.x(mousePos.x);
            measure.y(mousePos.y);

            moving = true;
            //layer.draw();
            measureLayer.draw();
        }
    }

    if (group) {
        group.add(endLine1);
        group.add(endLine2);
        group.add(rect);

        group.add(measure_bkg);
        group.add(measure);

        measureLayer.add(group);
    }

    layer.draw();
    measureLayer.draw();
});

background.on('mousemove', function() {
    if (moving) {
        var mousePos = stage.getPointerPosition();
        var x = mousePos.x;
        var y = mousePos.y;

        if (y == stage.height()-10){
            stage.height(stage.height()+100);
            layer.draw();
        }

        //measure.text("Measure changed! x: " + x + " y: " + y);

        if(horizontal_dimension_selected){
            rect.width(mousePos.x-rect.x());

            // Set up the line endings
            endLine1.height(16);
            endLine1.x(rect.x());
            endLine1.y(rect.y()-8);
            endLine2.height(16);
            endLine2.x(rect.x()+rect.width());
            endLine2.y(rect.y()-8);

            measure.x(rect.x() + (rect.width()/2)-10);
            measure.y(rect.y()-10);

            // The Math
            theText = Math.round(rect.width()*10/304.8*10)/10;
            theText = theText.toFixed(1);
            measure.text(theText + "'");

            measure_bkg.x(measure.x()-5);
            measure_bkg.y(measure.y()-5);

        } else if (vertical_dimension_selected){

            rect.height(mousePos.y - rect.y());

            // Set the location of the measurement
            measure.x(rect.x() - 20);
            measure.y(rect.y() + (rect.height()/2));

            theText = Math.round(rect.height() * 10 / 304.8 * 10, 1) / 10;
            theText = theText.toFixed(1);

            measure.text(theText + "'");

            measure_bkg.x(measure.x());
            measure_bkg.y(measure.y());

            // Set up the line endings
            endLine1.width(16);
            endLine1.x(rect.x() - 8);
            endLine1.y(rect.y());
            endLine2.width(16);
            endLine2.x(rect.x() - 8);
            endLine2.y(rect.y() + rect.height());
        }

        layer.draw();
        measureLayer.draw();
    } else {
        //layer.draw();
    }
});


function modifyStageSize(index){
    if (modules[index].y() >= stage.height() - modules[index].height()) {
        stage.height(stage.height() + modules[index].height());
        background.height(stage.height());
    }
}


//#########################################################
//################## DIMENSION TOOLS ######################

// Dimension Tool
document.getElementById('icon-dimension-horizontal').addEventListener('click', function() {
    activateHorizontalDimension();
});

document.getElementById('icon-dimension-vertical').addEventListener('click', function() {
    activateVerticalDimension();
});

function activateHorizontalDimension(){
    if(!horizontal_dimension_selected){
        document.getElementById('icon-dimension-horizontal').style.boxShadow = '0 0 5px 5px #006288';
        horizontal_dimension_selected = true;
        deactivateVerticalDimension();
    } else {
        document.getElementById('icon-dimension-horizontal').style.boxShadow = 'none';
        horizontal_dimension_selected = false;
    }
}
function deactivateHorizontalDimension(){
    document.getElementById('icon-dimension-horizontal').style.boxShadow = 'none';
    horizontal_dimension_selected = false;
}
function activateVerticalDimension(){
    if(!vertical_dimension_selected){
        document.getElementById('icon-dimension-vertical').style.boxShadow = '0 0 5px 5px #006288';
        vertical_dimension_selected = true;
        deactivateHorizontalDimension();
    } else {
        document.getElementById('icon-dimension-vertical').style.boxShadow = 'none';
        vertical_dimension_selected = false;
    }
}
function deactivateVerticalDimension(){
    document.getElementById('icon-dimension-vertical').style.boxShadow = 'none';
    vertical_dimension_selected = false;
}
