// Path: src/main/java/com/github/worldsender/mcanm/client/mcanmmodel/stored/parts/RawBone.java
// public class RawBone {
// 	public String name;
// 	public Quat4f rotation;
// 	public Vector3f offset;
// 	/** Parent of this bone as array index. A value of 0xFF means no parent */
// 	public byte parent;
// 
// 	public static RawBone readBoneFrom(DataInputStream dis) throws IOException {
// 		RawBone bone = new RawBone();
// 		String name = Utils.readString(dis);
// 		Quat4f quat = Utils.readQuat(dis);
// 		Vector3f offset = Utils.readVector3f(dis);
// 		bone.name = name;
// 		bone.rotation = quat;
// 		bone.offset = offset;
// 		return bone;
// 	}
// 
// }
// 
// Path: src/main/java/com/github/worldsender/mcanm/common/exceptions/ModelFormatException.java
// public class ModelFormatException extends IllegalArgumentException {
// 	/**
// 	 *
// 	 */
// 	private static final long serialVersionUID = -4000239134878464297L;
// 
// 	public ModelFormatException() {
// 		super();
// 	}
// 
// 	public ModelFormatException(String message) {
// 		super(message);
// 	}
// 
// 	public ModelFormatException(Throwable cause) {
// 		super(cause);
// 	}
// 
// 	public ModelFormatException(String message, Throwable cause) {
// 		super(message, cause);
// 	}
// }
// 
// Path: src/main/java/com/github/worldsender/mcanm/common/skeleton/visitor/IBoneVisitor.java
// public interface IBoneVisitor {
// 	void visitParent(byte parentIndex);
// 
// 	void visitLocalOffset(Vector3f headPosition);
// 
// 	void visitLocalRotation(Quat4f rotation);
// 
// 	void visitEnd();
// }
// 
// Path: src/main/java/com/github/worldsender/mcanm/common/skeleton/visitor/ISkeletonVisitor.java
// public interface ISkeletonVisitor {
// 	IBoneVisitor visitBone(String name);
// 
// 	void visitEnd();
// }


import java.io.DataInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import com.github.worldsender.mcanm.client.mcanmmodel.stored.parts.RawBone;
import com.github.worldsender.mcanm.common.exceptions.ModelFormatException;
import com.github.worldsender.mcanm.common.skeleton.visitor.IBoneVisitor;
import com.github.worldsender.mcanm.common.skeleton.visitor.ISkeletonVisitor;
package com.github.worldsender.mcanm.common.skeleton.stored;



public class RawDataV1 implements IVersionSpecificData {

	private RawBone[] bones;

	@Override
	public void visitBy(ISkeletonVisitor visitor) {
		for (RawBone bone : bones) {
			IBoneVisitor boneVisitor = visitor.visitBone(bone.name);
			if (bone.parent != 0xFF) {
				boneVisitor.visitParent(bone.parent);
			}
			boneVisitor.visitLocalOffset(bone.offset);
			boneVisitor.visitLocalRotation(bone.rotation);
			boneVisitor.visitEnd();
		}
	}

	public static final RawDataV1 loadFrom(DataInputStream dis) throws IOException, ModelFormatException {
		RawDataV1 data = new RawDataV1();

		int nbrBones = dis.readUnsignedByte();
		// Read bones
		RawBone[] bones = new RawBone[nbrBones];
		Set<String> boneNameSet = new HashSet<>();
		for (int i = 0; i < nbrBones; i++) {
// Path: src/main/java/com/github/worldsender/mcanm/client/mcanmmodel/stored/parts/RawBone.java
// public class RawBone {
// 	public String name;
// 	public Quat4f rotation;
// 	public Vector3f offset;
// 	/** Parent of this bone as array index. A value of 0xFF means no parent */
// 	public byte parent;
// 
// 	public static RawBone readBoneFrom(DataInputStream dis) throws IOException {
// 		RawBone bone = new RawBone();
// 		String name = Utils.readString(dis);
// 		Quat4f quat = Utils.readQuat(dis);
// 		Vector3f offset = Utils.readVector3f(dis);
// 		bone.name = name;
// 		bone.rotation = quat;
// 		bone.offset = offset;
// 		return bone;
// 	}
// 
// }
// 
// Path: src/main/java/com/github/worldsender/mcanm/common/exceptions/ModelFormatException.java
// public class ModelFormatException extends IllegalArgumentException {
// 	/**
// 	 *
// 	 */
// 	private static final long serialVersionUID = -4000239134878464297L;
// 
// 	public ModelFormatException() {
// 		super();
// 	}
// 
// 	public ModelFormatException(String message) {
// 		super(message);
// 	}
// 
// 	public ModelFormatException(Throwable cause) {
// 		super(cause);
// 	}
// 
// 	public ModelFormatException(String message, Throwable cause) {
// 		super(message, cause);
// 	}
// }
// 
// Path: src/main/java/com/github/worldsender/mcanm/common/skeleton/visitor/IBoneVisitor.java
// public interface IBoneVisitor {
// 	void visitParent(byte parentIndex);
// 
// 	void visitLocalOffset(Vector3f headPosition);
// 
// 	void visitLocalRotation(Quat4f rotation);
// 
// 	void visitEnd();
// }
// 
// Path: src/main/java/com/github/worldsender/mcanm/common/skeleton/visitor/ISkeletonVisitor.java
// public interface ISkeletonVisitor {
// 	IBoneVisitor visitBone(String name);
// 
// 	void visitEnd();
// }


// Path: src/main/java/com/github/worldsender/mcanm/common/skeleton/stored/RawDataV1.java
import java.io.DataInputStream;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import com.github.worldsender.mcanm.client.mcanmmodel.stored.parts.RawBone;
import com.github.worldsender.mcanm.common.exceptions.ModelFormatException;
import com.github.worldsender.mcanm.common.skeleton.visitor.IBoneVisitor;
import com.github.worldsender.mcanm.common.skeleton.visitor.ISkeletonVisitor;

package com.github.worldsender.mcanm.common.skeleton.stored;



public class RawDataV1 implements IVersionSpecificData {

	private RawBone[] bones;

	@Override
	public void visitBy(ISkeletonVisitor visitor) {
		for (RawBone bone : bones) {
			IBoneVisitor boneVisitor = visitor.visitBone(bone.name);
			if (bone.parent != 0xFF) {
				boneVisitor.visitParent(bone.parent);
			}
			boneVisitor.visitLocalOffset(bone.offset);
			boneVisitor.visitLocalRotation(bone.rotation);
			boneVisitor.visitEnd();
		}
	}

	public static final RawDataV1 loadFrom(DataInputStream dis) throws IOException, ModelFormatException {
		RawDataV1 data = new RawDataV1();

		int nbrBones = dis.readUnsignedByte();
		// Read bones
		RawBone[] bones = new RawBone[nbrBones];
		Set<String> boneNameSet = new HashSet<>();
		for (int i = 0; i < nbrBones; i++) {
			RawBone newBone = RawBone.readBoneFrom(dis);