pub mod weapon; 
pub mod armor; 
pub mod shield;
pub mod tool;
pub mod tech;
pub mod unit;
pub mod mag;

use crate::entity::character::CharacterEntityId;

#[derive(PartialEq, Copy, Clone, Debug, Hash, Eq)]
pub struct ItemEntityId(pub u32);
#[derive(Hash, PartialEq, Eq, Debug, Clone)]
pub struct ItemId(u32);
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BankName(String);

#[derive(Clone, Debug, PartialEq)]
pub enum ItemLocation {
    Inventory {
        character_id: CharacterEntityId,
        index: usize,
        equipped: bool,
    },
    Bank {
        character_id: CharacterEntityId,
        slot: BankName,
    },
    Floor {
        // floor: eventually
        // x y z: ?????
    },
    /*Destroyed {
        // marks an item that has been consumed in some way
    },
    Transformed {
        item_id,
        change_event
    }
*/
}

#[derive(Debug, PartialEq)]
pub struct Meseta(pub u32);

impl Meseta {
    pub fn as_bytes(&self) -> [u8; 16] {
        let mut result = [0; 16];
        result[12..16].copy_from_slice(&u32::to_le_bytes(self.0));
        result
    }
}


#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ItemType {
    Weapon(weapon::WeaponType),
    Armor(armor::ArmorType),
    Shield(shield::ShieldType),
    Unit(unit::UnitType),
    Tool(tool::ToolType),
    TechniqueDisk(tech::Technique),
    Mag(mag::MagType),
}


#[derive(Clone, Debug, PartialEq)]
pub enum ItemDetail {
    Weapon(weapon::Weapon),
    Armor(armor::Armor),
    Shield(shield::Shield),
    Unit(unit::Unit),
    Tool(tool::Tool),
    TechniqueDisk(tech::TechniqueDisk),
    Mag(mag::Mag),
}

impl ItemDetail {
    pub fn is_stackable(&self) -> bool {
        match self {
            ItemDetail::Tool(tool) => tool.tool.is_stackable(),
            _ => false,
        }
    }

    pub fn item_type(&self) -> ItemType {
        match self {
            ItemDetail::Weapon(w) => ItemType::Weapon(w.weapon),
            ItemDetail::Armor(a) => ItemType::Armor(a.armor),
            ItemDetail::Shield(s) => ItemType::Shield(s.shield),
            ItemDetail::Unit(u) => ItemType::Unit(u.unit),
            ItemDetail::Tool(t) => ItemType::Tool(t.tool),
            ItemDetail::TechniqueDisk(d) => ItemType::TechniqueDisk(d.tech),
            ItemDetail::Mag(m) => ItemType::Mag(m.mag),
        }
    }
}

#[derive(Clone, Debug, PartialEq)]
pub struct NewItemEntity {
    pub location: ItemLocation,
    pub item: ItemDetail,
}

#[derive(Clone, Debug, PartialEq)]
pub struct ItemEntity {
    pub id: ItemEntityId,
    pub location: ItemLocation,
    pub item: ItemDetail,
}