use crate::document::HeaderVariables;
use crate::io::dwg::dwg_stream_writers::DwgBitWriter;
use crate::io::dwg::dwg_version::DwgVersion;
use crate::types::DxfVersion;
fn dwg_internal_version(version: DxfVersion) -> i16 {
match version {
DxfVersion::AC1012 => 19,
DxfVersion::AC1014 => 21,
DxfVersion::AC1015 => 23,
DxfVersion::AC1018 => 25,
DxfVersion::AC1021 => 27,
DxfVersion::AC1024 => 29,
DxfVersion::AC1027 => 31,
DxfVersion::AC1032 => 33,
_ => 23, }
}
fn dwg_maintenance_version(version: DxfVersion) -> i16 {
match version {
DxfVersion::AC1021 => 25, DxfVersion::AC1024 => 30, DxfVersion::AC1027 => 29, DxfVersion::AC1032 => 4, _ => 0,
}
}
pub fn write_aux_header(version: DxfVersion, header: &HeaderVariables) -> Vec<u8> {
let dwg_version = DwgVersion::from_dxf_version(version)
.unwrap_or(DwgVersion::AC15);
let mut writer = DwgBitWriter::new(dwg_version, version);
let internal_ver = dwg_internal_version(version);
let maintenance_ver: i16 = dwg_maintenance_version(version);
writer.write_byte(0xFF);
writer.write_byte(0x77);
writer.write_byte(0x01);
writer.write_raw_short(internal_ver);
writer.write_raw_short(maintenance_ver);
writer.write_raw_long(1);
writer.write_raw_long(-1);
writer.write_raw_short(1);
writer.write_raw_short(0);
writer.write_raw_long(0);
writer.write_raw_short(internal_ver);
writer.write_raw_short(maintenance_ver);
writer.write_raw_short(internal_ver);
writer.write_raw_short(maintenance_ver);
writer.write_raw_short(0x0005);
writer.write_raw_short(0x0893);
writer.write_raw_short(0x0005);
writer.write_raw_short(0x0893);
writer.write_raw_short(0);
writer.write_raw_short(1);
for _ in 0..5 {
writer.write_raw_long(0);
}
let (create_day, create_ms) = julian_from_f64(header.create_date_julian);
writer.write_8bit_julian_date(create_day, create_ms);
let (update_day, update_ms) = julian_from_f64(header.update_date_julian);
writer.write_8bit_julian_date(update_day, update_ms);
let handseed = if header.handle_seed <= 0x7FFFFFFF {
header.handle_seed as i32
} else {
-1
};
writer.write_raw_long(handseed);
writer.write_raw_long(0);
writer.write_raw_short(0);
writer.write_raw_short(1);
writer.write_raw_long(0);
writer.write_raw_long(0);
writer.write_raw_long(0);
writer.write_raw_long(1);
writer.write_raw_long(0);
writer.write_raw_long(0);
writer.write_raw_long(0);
writer.write_raw_long(0);
if version >= DxfVersion::AC1032 {
writer.write_raw_short(0);
writer.write_raw_short(0);
writer.write_raw_short(0);
}
writer.into_bytes()
}
fn julian_from_f64(julian: f64) -> (i32, i32) {
let day = julian as i32;
let fraction = julian - day as f64;
let ms = (fraction * 86_400_000.0) as i32;
(day, ms)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dwg_internal_version() {
assert_eq!(dwg_internal_version(DxfVersion::AC1012), 19);
assert_eq!(dwg_internal_version(DxfVersion::AC1015), 23);
assert_eq!(dwg_internal_version(DxfVersion::AC1018), 25);
assert_eq!(dwg_internal_version(DxfVersion::AC1032), 33);
}
#[test]
fn test_julian_from_f64() {
let (day, ms) = julian_from_f64(2451544.5);
assert_eq!(day, 2451544);
assert!(ms > 0);
}
#[test]
fn test_write_aux_header_starts_with_magic() {
let header = HeaderVariables::default();
let data = write_aux_header(DxfVersion::AC1015, &header);
assert_eq!(data[0], 0xFF);
assert_eq!(data[1], 0x77);
assert_eq!(data[2], 0x01);
}
#[test]
fn test_write_aux_header_contains_version() {
let header = HeaderVariables::default();
let data = write_aux_header(DxfVersion::AC1015, &header);
assert_eq!(data[3], 23);
assert_eq!(data[4], 0);
}
#[test]
fn test_write_aux_header_r2018_longer() {
let header = HeaderVariables::default();
let data_2000 = write_aux_header(DxfVersion::AC1015, &header);
let data_2018 = write_aux_header(DxfVersion::AC1032, &header);
assert_eq!(data_2018.len(), data_2000.len() + 6);
}
}