use std::collections::BTreeMap;
use super::*;
pub(super) fn compact(plan: &mut AppearancePlan, types: &BTreeMap<u32,IfcType>) -> Result<BTreeMap<u32,u32>,String> {
plan.created.sort_unstable_by_key(|entity|entity.express_id);
let ids:BTreeMap<_,_>=plan.created.iter().enumerate()
.map(|(index,entity)|(entity.express_id,plan.next_express_id+index as u32)).collect();
let mut values=Vec::new();
for entity in &mut plan.created {
entity.express_id=ids[&entity.express_id];
let slots:&[usize]=match entity.r#type.as_str() {
"IfcTriangulatedFaceSet"|"IfcSurfaceStyleShading"|"IfcSurfaceStyleWithTextures"=>&[0],
"IfcShapeRepresentation"=>&[0,3], "IfcPresentationLayerAssignment"=>&[2],
"IfcStyledItem"=>&[0,1], "IfcIndexedTriangleTextureMap"=>&[0,1,2],
"IfcSurfaceStyle"=>&[2], "IfcImageTexture"=>&[3],
"IfcSurfaceStyleRendering"=>&[0,2,3,4,5,6],
"IfcCartesianPointList3D"|"IfcTextureVertexList"|"IfcColourRgb"=>&[],
name=>return Err(format!("Unsupported generated appearance reference layout: {name}")),
};
values.extend(entity.attributes.iter_mut().enumerate().filter_map(|(index,value)|slots.contains(&index).then_some(value)));
}
for edit in &mut plan.edits {
match (types.get(&edit.express_id),edit.index) {
(Some(IfcType::IfcShapeRepresentation),3)
| (Some(IfcType::IfcProductDefinitionShape),2)
| (Some(IfcType::IfcStyledItem),1)=>values.push(&mut edit.value),
(Some(IfcType::IfcShapeRepresentation),1|2)=>{},
_=>return Err("Unsupported evaluated appearance reference edit".into()),
}
}
while let Some(value)=values.pop() {
match value {
Value::String(text)=> {
if let Some(id)=text.strip_prefix('#').and_then(|id|id.parse::<u32>().ok()).and_then(|id|ids.get(&id)) {
*text=format!("#{id}");
}
},
Value::Array(items)=>values.extend(items.iter_mut()),
_=>{},
}
}
for item in &mut plan.items { if let Some(&id)=ids.get(&item.geometry_item_id) {item.geometry_item_id=id;} }
for item in &mut plan.conversions {
if let Some(&id)=ids.get(&item.geometry_item_id) {item.geometry_item_id=id;}
if let Some(&id)=ids.get(&item.representation_id) {item.representation_id=id;}
}
plan.next_available_express_id=plan.next_express_id+plan.created.len() as u32;
Ok(ids)
}