
import * as POLYTOPES from './polytopes.js';

import * as CELLINDEX from './cellindex.js';

// script to help me label the vertices of one of the inscribed 600-cells of a 120-cell
// with Schoute's partition (which is used to label the main 600-cell)


function choice(a) {
    const r = Math.floor(Math.random() * a.length);
    return a[r];
}

export function nodes_links(links, nodeid) {
    return links.filter((l) => l.source === nodeid || l.target === nodeid);
}


export function linked(links, n1, n2) {
    const ls = nodes_links(nodes_links(links, n1), n2);
    if( ls.length ) {
        return ls[0]
    } else {
        return false;
    }
}


export function dist(n1, n2) {
    return Math.sqrt((n1.x - n2.x) ** 2 + (n1.y - n2.y) ** 2 + (n1.z - n2.z) ** 2 + (n1.w - n2.w) ** 2);
}


function round_dist(raw) {
    return Math.floor(raw * 1000) / 1000;
}

export function make_one_600cell() {
    const nodes = POLYTOPES.make_120cell_vertices();
    const links = POLYTOPES.auto_detect_edges(nodes, 4);
    for( const cstr in CELLINDEX.INDEX120 ) {
    	POLYTOPES.label_nodes(nodes, CELLINDEX.INDEX120[cstr], Number(cstr));
    }

    links.map((l) => l.label = 0);

    const nodes600 = nodes.filter((n) => n.label === 1);
    const links600 = POLYTOPES.auto_detect_edges(nodes600, 12);
    links600.map((l) => l.label = 1);


    return {
    	nodes: nodes600,
    	links: links600
    }
}


export function base_600cell() {
        const nodes  = POLYTOPES.make_600cell_vertices();
	const links = POLYTOPES.auto_detect_edges(nodes, 12);

	links.map((l) => l.label = 0);

	for( const p of [1, 2, 3, 4, 5]) {
		const nodes24 = nodes.filter((n) => n.label === p);
	}

	return {
	        nodes: nodes,
		links: links,
	};
}

export function distance_groups(shape) {
    // get list of other nodes by distance
    // sort them and dump them out
    const dists = {};

    shape.nodes.map((n) => {
        const draw = dist(shape.nodes[0], n);
        const dtrunc = round_dist(draw);
        if( !(dtrunc in dists) ) {
            dists[dtrunc] = [];
        }
        dists[dtrunc].push(n.id);
    });
    return dists; 
}

export function insc600_layers(cell600) {
    const layers = distance_groups(cell600);
/*    const sorted = Object.keys(layers).sort((a,b) => a - b);
    for( const d of sorted ) {
        const ids = layers[d].map((n) => n.id);
        console.log(`Layer at distance ${d}`);
        console.log(ids);
    } */
    return layers;
}

export function neighbours(shape, nid) {
    const links = shape.links.filter((l) => l.source === nid || l.target == nid );
    const nodes = links.map((l) => {
        if( l.source === nid ) {
            return l.target;
        } else {
            return l.source;
        }
    });
    return nodes;
}

export function neighbours_in_subset(shape, subset, nid) {
    // shape = nodes, links
    // subset = a list of ids
    // n = an id
    // returns all of n's neighbours which are in subset

    const all_nbors = neighbours(shape, nid);
    return all_nbors.filter((n) => subset.includes(n));
}

export function face_vertices(shape, f1, f2, f3) {
    // for f1/f2/f3 forming a triangular face, return the two vertices of the
    // adjacent tetrahedra

    const n1 = neighbours(shape, f1).filter((n) => n !== f2 && n !== f3);
    const n2 = neighbours(shape, f2).filter((n) => n !== f1 && n !== f3);
    const n3 = neighbours(shape, f3).filter((n) => n !== f1 && n !== f2);

    const ns = n1.filter((n) => n2.includes(n) && n3.includes(n));
    return ns;
}


export function shared_neighbours(shape, nodes) {

    let ns = shape.nodes.map((n) => n.id);
    for( const n of nodes ) {
        ns = neighbours_in_subset(shape, ns, n);
    }

    return ns;
}



export function layer_neighbours(cell600, layer) {
    console.log("Layer neighbours");
    for( const n of layer ) {
        console.log(`n = ${n}`);
        const nbors = neighbours_in_subset(cell600, layer, n);
        console.log(`   Vertex ${n} neighbours: ` + JSON.stringify(nbors));
    }
}


const ARCTIC_I_FACES = [
        [ 419, 223, 253 ],
        [ 419, 253, 331 ],
        [ 419, 331, 427 ],
        [ 419, 427, 339 ],
        [ 419, 339, 223 ],
        [ 253, 223, 265 ],
        [ 331, 253, 473 ],
        [ 427, 331, 539 ],
        [ 339, 427, 555 ],
        [ 511, 339, 223 ],
        [ 223, 511, 265 ],
        [ 253, 265, 473 ],
        [ 331, 473, 539 ],
        [ 427, 539, 555 ],
        [ 339, 555, 511 ],
        [ 393, 265, 511 ],
        [ 393, 473, 265 ],
        [ 393, 539, 473 ],
        [ 393, 555, 539 ],
        [ 393, 555, 511 ]
];

export const ARCTIC_FACES = ARCTIC_I_FACES.map((f) => {
    return f.map((nid) => CELLINDEX.CELL600_METAMAP[nid]);
});

export const TEMPERATE_PENTAGONS_I = [
    [ 499, 179, 471, 367, 131 ],
    [ 131, 367, 165, 313, 449 ],
    [ 131, 449, 185, 258, 499 ],
    [ 499, 258, 140, 274, 179 ],
    [ 179, 274, 527, 95, 471 ],
    [ 471, 95, 347, 165, 367 ],
    [ 347, 573, 105, 313, 165 ],
    [ 313, 105, 585, 185, 449 ],
    [ 185, 585, 306, 140, 258 ],
    [ 140, 306, 207, 527, 274 ],
    [ 527, 207, 573, 347, 95 ],
    [ 105, 573, 207, 306, 585 ],
]

export const TEMPERATE_PENTAGONS = TEMPERATE_PENTAGONS_I.map((f) => {
    return f.map((nid) => CELLINDEX.CELL600_METAMAP[nid])
});


export function layer_two(cell600, centre, faces) {

    for ( const face of faces ) {
        const n2 = face_vertices(cell600, face[0], face[1], face[2]);
        console.log(face, n2);
    }
}


export function layer_three(shape, pentagons) {
    for ( const pentagon of pentagons ) {
        console.log(pentagon);
        const s = shared_neighbours(shape, pentagon);
        console.log(s);
        console.log("\n");
    }
}


/*const cell600 = make_one_600cell();
const layered = insc600_layers(cell600);

for( const d in layered ) {
    console.log(`dist = ${d}`);
    layer_neighbours(cell600, layered[d]);
}

*/
