pub mod weapon; 
pub mod armor; 
pub mod shield;
pub mod tool;

//use libpso::item;
use libpso::character::character;


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


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



#[derive(Clone, Debug, PartialEq)]
pub struct Weapon {
    pub equipped: bool,
    pub weapon: weapon::Weapon,
}

#[derive(Clone, Debug, PartialEq)]
pub struct Armor {
    pub equipped: bool,
    pub armor: armor::Armor,
}

#[derive(Clone, Debug, PartialEq)]
pub struct Shield {
    pub equipped: bool,
    pub shield: shield::Shield,
}

#[derive(Clone, Debug, PartialEq)]
pub struct Tool {
    pub tool: tool::ToolType,
}

impl Tool {
    pub fn as_bytes(&self) -> [u8; 16] {
        let mut result = [0; 16];
        result[0..3].copy_from_slice(&self.tool.value());
        result
    }
}

#[derive(Clone, Debug, PartialEq)]
pub enum ItemDetail {
    Weapon(Weapon),
    Armor(Armor),
    Shield(Shield),
    Tool(Tool),
}

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

    pub fn as_bytes(&self) -> [u8; 16] {
        match self {
            ItemDetail::Weapon(weapon) => weapon.weapon.as_bytes(),
            ItemDetail::Armor(armor) => armor.armor.as_bytes(),
            ItemDetail::Shield(shield) => shield.shield.as_bytes(),
            ItemDetail::Tool(tool) => tool.as_bytes(),
        }
    }
}


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