import { GSplatOctreeNode } from './gsplat-octree-node.js';
import { path } from '../../core/path.js';

class GSplatOctree {
		constructor(assetFileUrl, data){
				this.fileResources = new Map();
				this.files = data.filenames;
				this.lodLevels = data.lodLevels;
				this.assetFileUrl = assetFileUrl;
				this.baseDir = path.getDirectory(assetFileUrl);
				const leafNodes = [];
				this._extractLeafNodes(data.tree, leafNodes);
				this.nodes = leafNodes.map((nodeData)=>{
						const lods = [];
						for(let i = 0; i < this.lodLevels; i++){
								const lodData = nodeData.lods[i.toString()];
								if (lodData) {
										lods.push({
												file: this.files[lodData.file] || '',
												fileIndex: lodData.file,
												offset: lodData.offset || 0,
												count: lodData.count || 0
										});
								} else {
										lods.push({
												file: '',
												fileIndex: -1,
												offset: 0,
												count: 0
										});
								}
						}
						return new GSplatOctreeNode(lods, nodeData.bound);
				});
		}
		_extractLeafNodes(node, leafNodes) {
				if (node.lods) {
						leafNodes.push({
								lods: node.lods,
								bound: node.bound
						});
				} else if (node.children) {
						for (const child of node.children){
								this._extractLeafNodes(child, leafNodes);
						}
				}
		}
		getFullUrl(url) {
				return path.join(this.baseDir, url);
		}
		getFileResource(url) {
				return this.fileResources.get(url);
		}
		ensureFileResource(url, assetLoader) {
				if (this.fileResources.has(url)) {
						return;
				}
				const fullUrl = this.getFullUrl(url);
				const res = assetLoader.getResource(fullUrl);
				if (res) {
						this.fileResources.set(url, res);
						return;
				}
				assetLoader.load(fullUrl);
		}
}

export { GSplatOctree };
