package vra;

import java.util.*;
import vfs.*;

/**
 * vraファイルの表示用データを表わすクラス
 */
public class Vra {
    // メッシュID -> メッシュ名
    private ArrayList<String> mMeshNames;
    // メッシュID -> マテリアルID
    private ArrayList<Integer> mMaterialIds;
    // マテリアルID -> DDSパス名
    private ArrayList<String> mDdsPaths;
    private String mDxgPath;

    private Vra() {
	mMeshNames = new ArrayList<String>();
	mMaterialIds = new ArrayList<Integer>();
	mDdsPaths = new ArrayList<String>();
	mDxgPath = null;
    }

    public int getNrMeshes() {
	return mMaterialIds.size();
    }

    public String getMeshName(int meshId) {
	return mMeshNames.get(meshId);
    }

    public int getMaterialId(int meshId) {
	return mMaterialIds.get(meshId).intValue();
    }

    public String getDdsPath(int materialId) {
	return mDdsPaths.get(materialId);
    }

    public String getDxgPath() {
	return mDxgPath;
    }

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

    /**
     * vraファイルをロードし、ルートのNodeオブジェクトを返す
     */
    public static Node getRootNode(Vfs vfs, String relPath) throws VraException {
	Context ctx = new Context();
	Node root = null;
	    root = ctx.load(vfs, relPath);
	return root;
    }

    /**
     * vraファイルをロードし、主要な情報のみを納めたVraオブジェクトを返す
     */
    public static Vra load(Vfs vfs, String relPath) throws VraException {
	Context ctx = new Context();
	Node root = ctx.load(vfs, relPath);
	Vra vra = new Vra();

	// ジオメトリデータ
	Node attrNode = root.findChild("attribute");
	if(attrNode == null)
	    throw new VraException("missing 'attrbute' node");
	Attr geomAttr = attrNode.getAttribute("Geometry");
	if(geomAttr == null)
	    throw new VraException("missing 'geometry' attribute");

	vra.mDxgPath = (String)geomAttr.getValues()[0];

	Node geomNode = root.findChild("geometry");
	if(geomNode == null)
	    throw new VraException("missing 'geometry' node");
	for(Node meshNode: geomNode.getChildren()) {
	    if(!meshNode.getName().equals("mesh"))
		continue;
	    Attr nameAttr = meshNode.getAttribute("name");
	    Node lodNode = meshNode.findChild("lod0");
	    if(lodNode == null)
		continue;
	    Attr idAttr = lodNode.getAttribute("material_id");
	    if(idAttr == null)
		continue;

	    vra.mMeshNames.add(nameAttr == null
			       ? "" : (String)nameAttr.getValues()[0]);
	    vra.mMaterialIds.add((Integer)idAttr.getValues()[0]);
	}

	// マテリアルセット
	Node msetNode = root.findChild("material_set");
	if(msetNode == null)
	    throw new VraException("missing 'material_set' node");
	for(Node materialNode: msetNode.getChildren()) {
	    Attr idAttr = materialNode.getAttribute("id");
	    if(idAttr == null)
		continue;
	    Node texNode = materialNode.findChild("texture");
	    if(texNode == null)
		continue;
	    Node diffNode = texNode.findChild("diffuse");
	    if(diffNode == null)
		continue;
	    Attr fnameAttr = diffNode.getAttribute("fname");
	    if(fnameAttr == null)
		continue;
	    Integer index = (Integer)idAttr.getValues()[0];
	    vra.mDdsPaths.add(index.intValue(),
			      (String)fnameAttr.getValues()[0]);
	}
	return vra;
    }

    public void print() {
	int mesh, material;
	System.out.println("dxg: " + mDxgPath);
	for(mesh = 0; mesh < mMeshNames.size(); mesh++) {
	    material = getMaterialId(mesh);
	    System.out.printf("mesh[%d] %s: material=%d dds=%s\n",
			      mesh, getMeshName(mesh),
			      material, getDdsPath(material));
	}
    }

    public static void main(String[] argv) {
	try {
	    Vfs vfs = Vfs.create(Vfs.SCHEME_FILE, argv[0]);
	    Node root = Vra.getRootNode(vfs, argv[1]);
	    root.print();

	    Vra vra = Vra.load(vfs, argv[1]);
	    vra.print();
	} catch(Exception e) {
	    e.printStackTrace();
	}
    }
}
