package dxg;

import java.util.*;
import java.nio.*;

public class GroupData {
    int nr;
    GroupHeader group_header;
    MeshData[] mesh_list;
    float[] verteces;	// float[verteces_nr * 3]
    float[] normals;	// float[normals_nr * 3]
    float[] uvs;	// float[uv_nr * 2]
    byte[] data_v;	// char[data_v_nr * 4]
    float[] weight_map;	// float[]

    GroupData(ByteBuffer bf, int nr, ArrayList<Span> ranges) {
	int i, n;
	this.nr = nr;
	Span span = new Span("グループ" + nr, bf.position(), -1, 1, -1);
	ranges.add(span);

	group_header = new GroupHeader(bf, ranges);
	mesh_list = new MeshData[group_header.flag_b3 & 255];
	for(i = 0; i < (group_header.flag_b3 & 255); i++)
	    mesh_list[i] = new MeshData(bf, i, ranges);

	// 頂点座標
	n = group_header.verteces_nr;
	ranges.add(new Span("  頂点座標", bf.position(), n * 3 * 4, n, 3 * 4));
	verteces = new float[n * 3];
	for(i = 0; i < n * 3; i++)
	    verteces[i] = bf.getFloat();

	// 法線ベクトル
	n = group_header.normals_nr;
	ranges.add(new Span("  法線ベクトル", bf.position(), n * 3 * 4, n, 3 * 4));
	normals = new float[n * 3];
	for(i = 0; i < n * 3; i++)
	    normals[i] = bf.getFloat();

	// UV座標
	n = group_header.uv_nr;
	ranges.add(new Span("  UV座標", bf.position(), n * 2 * 4, n, 2 * 4));
	uvs = new float[n * 2];
	for(i = 0; i < n * 2; i++)
	    if(i % 2 == 0)
		uvs[i] = bf.getFloat();
	    else
		uvs[i] = 1 - bf.getFloat();

	// データV
	n = group_header.data_v_nr;
	if(n > 0) {
	    ranges.add(new Span("  データV", bf.position(), n * 4, n, 4));
	    data_v = new byte[n * 4];
	    bf.get(data_v);
	} else {
	    data_v = new byte[0];
	}

	// ウェイトマップ
	n = group_header.weight_map_nr;
	if(n > 0) {
	    ranges.add(new Span("  ウェイトマップ", bf.position(), n * 4, n, 4));
	    weight_map = new float[n];
	    for(i = 0; i < n; i++)
		weight_map[i] = bf.getFloat();
	} else {
	    weight_map = new float[0];
	}

	// 残り
	n = span.start + group_header.offset_f1 + 8;
	if(n > bf.position()) {
	    ranges.add(new Span("不明2", bf.position(), n - bf.position(),
		    1, n - bf.position()));
	    bf.position(n);
	}

	span.setLength(bf.position() - span.start);
    }

    void show(int what) {
	System.out.printf("メッシュデータ%d\n", nr);
	group_header.show(what);
	// name_t.show(what)TODO
    }


    //----------------------------------------------------------------------

    public int getNrMeshes() {
	return mesh_list.length;
    }

    public float[] getVerteces(int meshId) {
	MeshData md = mesh_list[meshId];
	MeshHeader mh = md.mesh_header;
	float[] r = new float[mh.vertex_info_nr * 3];
	for(int i = 0; i < mh.vertex_info_nr; i++) {
	    r[i * 3 + 0] = verteces[md.vertex_lut[i] * 3 + 0];
	    r[i * 3 + 1] = verteces[md.vertex_lut[i] * 3 + 1];
	    r[i * 3 + 2] = verteces[md.vertex_lut[i] * 3 + 2];
	}
	return r;
    }

    public int[] getFaces(int meshId) {
	MeshData md = mesh_list[meshId];
	MeshHeader mh = md.mesh_header;
	int[] r = new int[mh.face_info_nr * 3];
	for(int i = 0; i < mh.face_info_nr; i++) {
	    r[i * 3 + 0] = md.face_info[i * 3 + 0];
	    r[i * 3 + 1] = md.face_info[i * 3 + 1];
	    r[i * 3 + 2] = md.face_info[i * 3 + 2];
	}
	return r;
    }

    public float[] getUvs(int meshId) {
	MeshData md = mesh_list[meshId];
	MeshHeader mh = md.mesh_header;
	float[] r = new float[mh.vertex_info_nr * 2];
	for(int i = 0; i < mh.vertex_info_nr; i++) {
	    r[i * 2 + 0] = uvs[md.uv_lut[i] * 2 + 0];
	    r[i * 2 + 1] = uvs[md.uv_lut[i] * 2 + 1];
	}
	return r;
    }
}
