import {
    onAcidClick as selectionAcidClick,
    onAcidMouseLeave as selectionAcidMouseLeave,

    callbacks as selectionCbs
} from './selection.js'

import {
    onMousedOver as previewMouseOver,
    onMousedLeave as previewMouseLeave
} from './acidIndexPreview.js'

import {
    onSelectionFinalized as formattedSequenceSelectionFinalized,
    onSelectionCancled as formattedSequenceSelectionCancled
} from './formattedSequence.js'


disableSelection(document.getElementById("viz")) //disable text selection on entire body of page

juxtacbs.acidClick.push(selectionAcidClick);
//juxtacbs.acidMouseOver.push(selectionAcidMouseOver);
juxtacbs.acidMouseOver.push(previewMouseOver);
juxtacbs.acidMouseleave.push(selectionAcidMouseLeave);
juxtacbs.acidMouseleave.push(previewMouseLeave)

selectionCbs.firstSelection.push(juxtaSelected);
selectionCbs.finalizedSelection.push(juxtaSelected);
selectionCbs.cancelSelection.push(juxtaCanceled);

selectionCbs.finalizedSelection.push(formattedSequenceSelectionFinalized);
selectionCbs.cancelSelection.push(formattedSequenceSelectionCancled);


setMouseMove(viewer);
//setSelectFromViewerHandler(viewer);

parent.redrawAll = redrawAll;

function redrawAll() {

    // I'm keeping this here as a reminder of how much work this took to get off the ground.

    // //Wait until the molecule will be loaded into the Pv viewer
    // // and until all the loops are successfully loaded
    // var t = setInterval(function (n) {
    //     if (pdbFiles.length == ss.length
    //         && loops.length == pdbFiles.length
    //         && checkLoops()) {
    //         clearInterval(t);
    //         resolve("Success");
    //     }
    // }, 500);

    //load new pdbs and update viewer
    console.time("redraw", "redrawAll - start");

    viewer.clear();



    viewer.on('viewerReady', function (viewer) {
        console.timeLog("redraw", "viewerReady - start");

            //reset structures
        proteins = [];
        ss = [];
        highlighted = [];
        juxtaElementSet = true;
        loops = [];
        atomsFromPdb = [];

        let reloading_actions = [];

        for (var i = 0; i < pdbFiles.length; i++) {
            reloading_actions.push(loadMolecule(pdbFiles[i], i));
            reloading_actions.push(downloadBfactors(pdbFiles[i], i));
            reloading_actions.push(downloadLoops(pdbFiles[i].substring(pdbFiles[i].length - 8).substr(0, 4), i));
        }
        Promise.all(reloading_actions).then(
            () => {
                console.timeLog("redraw", "loading/downloading finished - start");
                //Get protein names
                proteins = [];
                let longestChain = 0;
                for (var i = 0; i < pdbFiles.length; i++) {
                    proteins.push(pdbFiles[i].substr(0, pdbFiles[i].indexOf('.pdb')).slice(-4));
                    findExtremeBfactors(i);
                    highlighted[i] = new Set();
                    if (ss[i].length > longestChain) {
                        longestChain = ss[i].length;
                    }
                }
                thisElementWidth = $("#viz").width() / longestChain;
                calculateGeometryPositions();

                juxtaposition.attr("height", 40 + 65 * (proteins.length));
                // loopDetail.attr("height", 100 + 55 * proteins.length);
                elementWidth = (width - 100) / ss[0].length;
                initShit();
                reference = 0;
                redrawD3();
                console.timeEnd("redraw");
                
            }
        );
    });

}

function storeLoops(data, i) {
    loops[i] = [];
    for (let index = 0; index < data.length; index++) {
        let tmp = data[index].split(/\s+/);
        let loop = {
            loop_id: null,
            pdb: null,
            chain: null,
            start: null,
            end: null,
            type: null,
            length: null,
            NtermLength: null,
            CtermLength: null,
            distance: null,
            theta: null,
            rho: null,
            delta: null,
            sequence: null,
            secondary_structure: null,
            exposition: null,
            ramachandran: null,
            classification: null,
            distance_pos: null,
            theta_pos: null,
            rho_pos: null,
            delta_pos: null
        };
        Object.keys(loop).forEach(function (key, indexx) {
            loop[key] = tmp[indexx];
        })
        //check if loops already contain loop with the same id
        var no = true;
        loops[i].forEach(function callback(loopI) {
            if (loopI.loop_id === loop.loop_id) no = false;
        });
        if (no) {
            loops[i].push(loop);
            //fill allLoops array with refence to extracted loops
            var ref_loop = loop;
            allLoops.push(ref_loop);
        }
    }
    loops[i].sort((a, b) => {
        return (Number(a.start) - Number(b.start));
    })
    // console.log(loops)
}

function calculateGeometryPositions() {
    let keys = ['distance', 'theta', 'rho', 'delta'];
    let poss = ['distance_pos', 'theta_pos', 'rho_pos', 'delta_pos'];
    for (var i = 0; i < keys.length; i++) {
        fillPos(keys[i], poss[i]);
    }
    fillPos('distance', 'distance_pos');
    // allLoops.find(function(n){return n.loop_id==="1H7C_A_49"}).chain = "KOKOKT";
}

function fillPos(key, pos) {
    let loopsNum = allLoops.length;
    allLoops.sort((a, b) => {
        return (Number(a[key]) - Number(b[key]));
    });
    let index = 0;
    allLoops.forEach(function (n) {
        n[pos] = index / loopsNum;
        index++;
    })
}

function downloadLoops(thisName, i) {
    return $.get("/loops", { name: thisName }, function (data) {
        storeLoops(data, i);
    })
}

function downloadBfactors(thisName, i) {
    // atomsFromPdb[i] = [];
    return $.get("/bfactors", { name: thisName }, function (data) {
        atomsFromPdb[i] = data;
    })
}

function findExtremeBfactors(i) {
    for (var j = 0; j < atomsFromPdb[i].length; j++) {
        let thisBfact = parseFloat(atomsFromPdb[i][j][10]);
        if (thisBfact > highestBfact) {
            // console.log(thisBfact)
            highestBfact = thisBfact;
        }
        if (thisBfact < lowestBfact) lowestBfact = thisBfact;
    }
}

redrawAll();
