use super::RigResource;
use byteorder::{WriteBytesExt, LE};
use ltk_hash::elf;
use ltk_io_ext::WriterExt;
use std::cmp::Reverse;
use std::io;
use std::io::{Seek, SeekFrom, Write};
impl RigResource {
pub fn to_writer<W: Write + Seek + ?Sized>(&self, writer: &mut W) -> io::Result<()> {
writer.write_u32::<LE>(0)?; writer.write_u32::<LE>(Self::FORMAT_TOKEN)?;
writer.write_u32::<LE>(0)?;
writer.write_u16::<LE>(self.flags)?;
writer.write_u16::<LE>(self.joints.len() as _)?;
writer.write_u32::<LE>(self.influences.len() as _)?;
let joints_section_size = self.joints.len() * 100;
let joint_hash_ids_section_size = self.joints.len() * 8;
let influences_section_size = self.influences.len() * 2;
let joints_off = 64;
let joint_hash_ids_off = joints_off + joints_section_size;
let influences_off = joint_hash_ids_off + joint_hash_ids_section_size;
let joint_names_off = influences_off + influences_section_size;
writer.write_i32::<LE>(joints_off as i32)?;
writer.write_i32::<LE>(joint_hash_ids_off as i32)?;
writer.write_i32::<LE>(influences_off as i32)?;
let name_off_pos = writer.stream_position()?;
writer.write_i32::<LE>(-1)?;
let asset_name_off_pos = writer.stream_position()?;
writer.write_i32::<LE>(-1)?;
writer.write_i32::<LE>(joint_names_off as i32)?;
for _ in 0..5 {
writer.write_u32::<LE>(0xFFFFFFFF)?;
}
writer.seek(SeekFrom::Start(joint_names_off as u64))?;
let mut joint_name_offs = Vec::with_capacity(self.joints.len());
for j in &self.joints {
joint_name_offs.push(writer.stream_position()?);
writer.write_terminated_string(j.name())?;
}
writer.seek(SeekFrom::Start(joints_off as u64))?;
for (j, off) in self.joints.iter().zip(joint_name_offs.iter()) {
j.to_writer(writer, *off)?;
}
writer.seek(SeekFrom::Start(influences_off as u64))?;
for inf in &self.influences {
writer.write_i16::<LE>(*inf)?;
}
writer.seek(SeekFrom::Start(joint_hash_ids_off as u64))?;
let mut hash_ids = self
.joints
.iter()
.map(|j| (j.id(), elf::elf(j.name())))
.collect::<Vec<_>>();
hash_ids.sort_by_key(|(_, hash)| Reverse(*hash));
for (id, hash) in hash_ids {
writer.write_i16::<LE>(id)?;
writer.write_i16::<LE>(0)?;
writer.write_u32::<LE>(hash as u32)?; }
let name_off = writer.seek(SeekFrom::End(0))?;
writer.write_terminated_string(&self.name)?;
let asset_name_off = writer.stream_position()?;
writer.write_terminated_string(&self.asset_name)?;
let size = writer.stream_position()?;
writer.seek(SeekFrom::Start(name_off_pos))?;
writer.write_i32::<LE>(name_off as i32)?;
writer.seek(SeekFrom::Start(asset_name_off_pos))?;
writer.write_i32::<LE>(asset_name_off as i32)?;
writer.seek(SeekFrom::Start(0))?;
writer.write_u32::<LE>(size as u32)?;
Ok(())
}
}