var camera, controls, scene, renderer;

const N = 24;
function ind2ind(x,y,z) {
    return (x*N+y)*N+z;
}

function vadd(x, y) {
    return x.map(function (_,i) {
        return x[i]+y[i];
    });
}
function vmod(x ,y) {
    return x.map(function (_,i) {
        return x[i]%y[i];
    });
}

function drawPercolationLattice(inp_lattice, lattice_mapping, maxN) {
    var maxN = maxN | 24;
    
    function lattice(x,y,z) {
        return inp_lattice[ind2ind(x,y,z)];
    }
    
    vertices = []
    colors = []
    for (var h=0; h<maxN; ++h)
        for (var k=0; k<maxN; ++k)
            for (var l=0; l<maxN; ++l)
                if (lattice(h, k, l) < 0 )
                    [[1,1,0],[1,0,1],[0,1,1],[1,-1,0],[1,0,-1],[0,1,-1]].forEach(function (neighbour) {
                        
                        var n = vadd([h,k,l], neighbour);
                        
                        if(n[2]<0 || n[2]==maxN)    
                            return;
                        
                        
                        var [nh, nk, nl] = vmod(n, [N,N,N]);

                        
                        if (lattice(nh,nk,nl)<0 && lattice(h,k,l)<0) {
                            vertices.push(new THREE.Vector3(h-maxN/2, k-maxN/2, l-maxN/2));
                            vertices.push(new THREE.Vector3(n[0]-maxN/2, n[1]-maxN/2, n[2]-maxN/2));
                            
                            

                            var mapColor = function (h,k,l) {
                                var v = lattice_mapping[ind2ind(h,k,l)];
            					var c = new THREE.Color( 0xffffff );
                                
                                c.setHSL( Math.max( 0, v/N/2 ), 0.7, 0.5);
                                if(currently_drawing === 'clusters')
            					   c.setHSL( Math.max( 0, v*7/22 % 1 ), 0.7, 0.5);
                                return c;
                            };
                            
                            colors.push(mapColor(h,k,l));
                            colors.push(mapColor(nh,nk,nl));
//                            colors.push(new THREE.Color( lattice(h,k,l)>0 ? 'red' : 'green' ));
//                            colors.push(new THREE.Color( lattice(nh,nk,nl)>0 ? 'red' : 'green' ));
                        }
                    });

    var geometry = new THREE.Geometry();
    geometry.vertices = vertices;
    geometry.colors = colors;

    var material = new THREE.LineBasicMaterial( { color: 0xffffff, opacity: 1, linewidth: 3, vertexColors: THREE.VertexColors } );
    var line = new THREE.LineSegments( geometry, material );
    
    clearScene();
    
    scene.add( line );
    
    render();
}

function loadAndDrawStructure(filename) {
    jQuery.get(filename, function(structure) {
        var h = document.getElementById('header');
        h.innerHTML = filename;
        current_structure = filename;
        
        var mapping = {'distances_x':'distance_mapping_x',
                       'distances_y':'distance_mapping_y',
                       'distances_z':'distance_mapping_z',
                       'clusters':'node_mapping'}[currently_drawing];
        
        if(typeof structure==='string')
            structure = JSON.parse(structure);
        
        
//        if(structure.permeation_clusters.length>0)
            drawPercolationLattice(structure.lattice, fromKVpairs(structure.permeation_cluster[mapping]));
//        else{
//            clearScene();
//            render();
//        }
            
    });
}

function clearScene(){
    while(scene.children.length > 0){ 
        scene.remove(scene.children[0]); 
    }
}

function zipmap(keys, vals) {
    var res = {};
    keys.forEach(function (_,i) {
        res[keys[i]] = vals[i];
    });
    return res;
}

function fromKVpairs(keyvals) {
    var res = {};
    keyvals.forEach(function ([k,v]){
        res[k]=v;
    });
    return res;
}

var currently_drawing = 'distances_z';
var current_structure = '2/for_site/J2_0.5_T_4.35.json';

function init() {
    scene = new THREE.Scene();
    scene.fog = new THREE.FogExp2( 0xffffff, 0.0002 ); //0xcccccc

    renderer = new THREE.WebGLRenderer();
    renderer.setClearColor( 0x000000  ); //scene.fog.color
    renderer.setPixelRatio( window.devicePixelRatio );

    var width=800;
    var height=800;

    renderer.setSize(width, height);

    var container = document.getElementById( 'renderingContainer' );
    container.appendChild( renderer.domElement );

    camera = new THREE.OrthographicCamera( width / -2, width / 2, height / 2, height / -2, -100, 100 );//new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 1, 1000 );
    camera.position.z = 10;
    camera.zoom=60;
    camera.updateProjectionMatrix();

    controls = new THREE.OrbitControls( camera, renderer.domElement );
    controls.addEventListener( 'change', render ); // remove when using animation loop
    //enable animation loop when using damping or autorotation
    //controls.enableDamping = true;
    //controls.dampingFactor = 0.25;
    controls.enableZoom = true;
    
    loadAndDrawStructure(current_structure);
}

function render() {
    renderer.render( scene, camera );
}

window.onload = init;