pub const ACC_PUBLIC: u16 = 0x0001; // Declared public; may be accessed from outside its package.
pub const ACC_PRIVATE: u16 = 0x0002; // Declared private; usable only within the defining class.
pub const ACC_PROTECTED: u16 = 0x0004; // Declared protected; may be accessed within subclasses.
pub const ACC_STATIC: u16 = 0x0008; // Declared static

pub const ACC_FINAL: u16 = 0x0010; // Declared final; no subclasses allowed.
pub const ACC_SUPER: u16 = 0x0020; // (Class) Treat superclass methods specially when invoked by the invokespecial instruction.
pub const ACC_VOLATILE: u16 = 0x0040; // (Field) Declared volatile; cannot be cached.
pub const ACC_TRANSIENT: u16 = 0x0080; // (Field) Declared transient; not written or read by a persistent object manager.
pub const ACC_INTERFACE: u16 = 0x0200; // (Class) Is an interface, not a class.
pub const ACC_ABSTRACT: u16 = 0x0400; // (Class) Declared abstract; must not be instantiated.
pub const ACC_SYNTHETIC: u16 = 0x1000; // Declared synthetic; not present in the source code.
pub const ACC_ANNOTATION: u16 = 0x2000; // Declared as an annotation type.
pub const ACC_ENUM: u16 = 0x4000; // Declared as an enum type.

// Method-only constants
pub const ACC_SYNCHRONIZED: u16 = 0x0020; // (Method) Declared synchronized; invocation is wrapped by a monitor use.
pub const ACC_BRIDGE: u16 = 0x0040; // (Method) A bridge, generated by the compiler.
pub const ACC_VARARGS: u16 = 0x0080; // (Method) Declared with variable number of arguments.
pub const ACC_NATIVE: u16 = 0x0100; // (Method) Declared native; implemented in a language other than Java.
pub const ACC_ABSTRACT_M: u16 = 0x0400; // (Method) Declared abstract; no implementation is provided.
pub const ACC_STRICT: u16 = 0x0800; // (Method) Declared strictfp; floating-point mode is FP-strict.

//////////// CONSTANT POOL HANDLING

// CPType constants
pub const CP_UTF8: u8 = 1;
pub const CP_INTEGER: u8 = 3;
pub const CP_FLOAT: u8 = 4;
pub const CP_LONG: u8 = 5;
pub const CP_DOUBLE: u8 = 6;
pub const CP_CLASS: u8 = 7;
pub const CP_STRING: u8 = 8;
pub const CP_FIELDREF: u8 = 9;
pub const CP_METHODREF: u8 = 10;
pub const CP_INTERFACE_METHODREF: u8 = 11;
pub const CP_NAMEANDTYPE: u8 = 12;
pub const CP_METHODHANDLE: u8 = 15;
pub const CP_METHODTYPE: u8 = 16;
pub const CP_INVOKEDYNAMIC: u8 = 18;

#[derive(Clone, Debug)]
pub enum CpEntry {
    utf8 { val: String },
    integer { val: i32 },
    float { val: f32 },
    long { val: i64 },
    double { val: f64 },
    class { idx: u16 },
    string { idx: u16 },
    fieldref { clz_idx: u16, nt_idx: u16 },
    methodref { clz_idx: u16, nt_idx: u16 },
    interface_methodref { clz_idx: u16, nt_idx: u16 },
    name_and_type { name_idx: u16, type_idx: u16 },
}

impl CpEntry {
    pub fn separator(cp_type: u8) -> String {
        match cp_type {
            CP_FIELDREF => ".".to_string(),
            CP_METHODREF => ".".to_string(),
            CP_NAMEANDTYPE => ":".to_string(),
            _ => "".to_string(),
        }
    }
}

#[derive(Clone, Debug)]
pub struct CpAttr {
    name_idx: u16,
}

impl CpAttr {
    pub fn of(name_idx: u16) -> CpAttr {
        CpAttr { name_idx: name_idx }
    }
}

pub fn split_name_desc(name_desc: String) -> (String, String) {
    ("a".to_string(), "b".to_string())
}
