/**
   * Reads image meta data.
   *
   * @param oimage
   * @return
   */
  public static Map<String, String> readImageData(IIOImage oimage) {
    Map<String, String> dict = new HashMap<String, String>();

    IIOMetadata imageMetadata = oimage.getMetadata();
    if (imageMetadata != null) {
      IIOMetadataNode dimNode = (IIOMetadataNode) imageMetadata.getAsTree("javax_imageio_1.0");
      NodeList nodes = dimNode.getElementsByTagName("HorizontalPixelSize");
      int dpiX;
      if (nodes.getLength() > 0) {
        float dpcWidth = Float.parseFloat(nodes.item(0).getAttributes().item(0).getNodeValue());
        dpiX = (int) Math.round(25.4f / dpcWidth);
      } else {
        dpiX = Toolkit.getDefaultToolkit().getScreenResolution();
      }
      dict.put("dpiX", String.valueOf(dpiX));

      nodes = dimNode.getElementsByTagName("VerticalPixelSize");
      int dpiY;
      if (nodes.getLength() > 0) {
        float dpcHeight = Float.parseFloat(nodes.item(0).getAttributes().item(0).getNodeValue());
        dpiY = (int) Math.round(25.4f / dpcHeight);
      } else {
        dpiY = Toolkit.getDefaultToolkit().getScreenResolution();
      }
      dict.put("dpiY", String.valueOf(dpiY));
    }

    return dict;
  }
  /** Prototype give player a leveled up look */
  public void Opify(double Fac) {

    for (int i = 0; i < imgCHARAC.getWidth(); i++) {
      for (int j = 0; j < imgCHARAC.getHeight(); j++) {
        if (imgCHARAC.getRGB(i, j) != imgCHARAC.getRGB(2, 2)) {
          imgCHARAC.setRGB(i, j, (int) Math.round(imgCHARAC.getRGB(i, j) * Fac));
        }
      }
    }
  }
 private int scy(int py) {
   return (int) Math.round(py * scaley);
 }
 private int scx(int px) {
   return (int) Math.round(px * scalex);
 }
  /**
   * Constructor to create a character
   *
   * @param x X Position
   * @param y Y Position
   * @param w Width of Image
   * @param h Height of Image
   * @param FileN Name of image file
   * @param S Max number of frames
   */
  public GameCharacter(
      double x, double y, double w, double h, String FileN, int S, int Ty, String c) {
    // Set position and size
    X = x;
    Y = y;
    W = w;
    H = h;

    BASIC_PROCESS = new ProgressBar(new Font("Arial", 36, 36), this);
    BASIC_EFFECTS = new ProgressBar(new Font("Arial", 36, 36), this);
    // Add magic attacks
    // Fireball
    for (int i = 0; i < FIREBALL.length; i++) {
      FIREBALL[i] = new MagicAttack(-500, -500, 39, 41, "Fireball.png", 3, 1, 2, "Fireball");
      FIREBALL[i].STATS.setStats(new String[] {"Damage=10", "Points=10"});
      FIREBALL[i].CASTER = this;
    }
    // Shock
    for (int i = 0; i < SHOCK.length; i++) {
      SHOCK[i] = new MagicAttack(-500, -500, 39, 41, "Shock.png", 2, 1, 0, "Shock");
      SHOCK[i].STATS.setStats(new String[] {"Damage=20", "Points=15"});
      SHOCK[i].CASTER = this;
    }
    // Darkness
    for (int i = 0; i < DARKNESS.length; i++) {
      DARKNESS[i] = new MagicAttack(-500, -500, 165, 164, "Darkness.png", 3, 1, 2, "Darkness");
      DARKNESS[i].STATS.setStats(new String[] {"Damage=100", "Points=50"});
      DARKNESS[i].CASTER = this;
    }
    // Life Drain
    for (int i = 0; i < LIFE_DRAIN.length; i++) {
      LIFE_DRAIN[i] = new MagicAttack(-500, -500, 32, 32, "Life Drain.png", 7, 1, 0, "Life Drain");
      LIFE_DRAIN[i].STATS.setStats(new String[] {"Damage=50", "Points=25"});
      LIFE_DRAIN[i].CASTER = this;
    }
    // Get Image
    try {

      if (isJar()) {
        // Character
        imgCHARAC = getImage("/Graphics/Character/", FileN);

        // Blood
        int BloodType = (int) Math.round(Math.random() * 3) + 1;
        imgBLOOD = getImage("/Graphics/Effects/", "Dead" + BloodType + ".png");

        // Quest
        imgQStart = getImage("/Graphics/Effects/", "Quest_Start.png");
        imgQEnd = getImage("/Graphics/Effects/", "Quest_Complete.png");

      } else {
        // Character
        imgCHARAC = ImageIO.read(Paths.get(DIRECT + FileN).toFile());

        // Blood
        int BloodType = (int) Math.round(Math.random() * 3) + 1;
        imgBLOOD = ImageIO.read(Paths.get(DIRECT2 + "Dead" + BloodType + ".png").toFile());

        // Quest
        imgQStart = ImageIO.read(Paths.get(DIRECT2 + "Quest_Start.png").toFile());
        imgQEnd = ImageIO.read(Paths.get(DIRECT2 + "Quest_Complete.png").toFile());
      }

    } catch (Exception e) {
    }

    // Max number of frames
    SIZE = S;

    // Sprite type
    TYPE = Ty;

    // Assign class
    CLASS = c;
    Cl = c;

    // Add items and attacks according to class
    if (CLASS.equals("Player")) {

      // Add items
      INVENTORY.addItem(
          "Health Potion", 25, 1, "Health Pot.png", "Potion", new String[] {"Points=50"});
      INVENTORY.addItem(
          "Rusted Dagger",
          20,
          1,
          "Dagger_4.png",
          "Meele",
          new String[] {"Damage=10", "Attack Speed=1"});
      INVENTORY.addItem(
          "Wooden Staff",
          20,
          1,
          "Staff_1.png",
          "Meele",
          new String[] {"Damage=5", "Attack Speed=1"});

      // Equip items
      INVENTORY.ItemEffect(1, this);
      // MEELE_WEAPON=null;
      // Assign Magic
      SPELL_LIST.add(FIREBALL);

      // Inventory type
      INVENTORY.Type = "Player";
    } else if (CLASS.equals("Citizen")) {

      // Add items
      INVENTORY.addItem(
          "Health Potion", 25, 1, "Health Pot.png", "Potion", new String[] {"Points=50"});

      // Add Ai
      NAI = new NPCAI(this);

      // Add Gold
      this.GOLD = (int) Math.round(Math.random() * 15 + 5);

      INVENTORY.Type = "Friendly";
    } else if (CLASS.equals("Blacksmith")) {

      // Add items
      INVENTORY.addItem(
          "Silver Dagger",
          250,
          1,
          "Dagger_3.png",
          "Meele",
          new String[] {"Damage=10", "Attack Speed=1"});
      INVENTORY.addItem(
          "Steel Dagger",
          450,
          1,
          "Dagger_5.png",
          "Meele",
          new String[] {"Damage=35", "Attack Speed=1"});
      // INVENTORY.addItem("Assassin blade", 750,1, "Dagger_6.png","Meele",new
      // String[]{"Damage=45","Attack Speed=1"});
      // INVENTORY.addItem("Serpent Dagger", 5000,1, "Dagger_2.png","Meele",new
      // String[]{"Damage=50","Attack Speed=1"});
      // INVENTORY.addItem("Dagger of Time", 5050,1, "Dagger_1.png","Meele",new
      // String[]{"Damage=75","Attack Speed=1"});

      INVENTORY.addItem(
          "Steel Sword",
          450,
          1,
          "Sword_1.png",
          "Meele",
          new String[] {"Damage=30", "Attack Speed=0.65"});
      INVENTORY.addItem(
          "Iron Sword",
          50,
          1,
          "Sword_2.png",
          "Meele",
          new String[] {"Damage=15", "Attack Speed=0.65"});
      INVENTORY.addItem(
          "Silver Sword",
          100,
          1,
          "Sword_5.png",
          "Meele",
          new String[] {"Damage=20", "Attack Speed=0.5"});
      // INVENTORY.addItem("Iron Scimitar", 150,1, "Sword_7.png","Meele",new
      // String[]{"Damage=15","Attack Speed=0.75"});
      // INVENTORY.addItem("Steel Scimitar", 500,1, "Sword_4.png","Meele",new
      // String[]{"Damage=50","Attack Speed=0.75"});
      // INVENTORY.addItem("Steel Katana", 450,1, "Sword_6.png","Meele",new
      // String[]{"Damage=40","Attack Speed=0.95"});
      // INVENTORY.addItem("Butcher's Sword", 5000,1, "Sword_3.png","Meele",new
      // String[]{"Damage=100","Attack Speed=0.55"});
      // INVENTORY.addItem("Blood Thirster", 6000,1, "Sword_8.png","Meele",new
      // String[]{"Damage=200","Attack Speed=0.75"});

      INVENTORY.addItem(
          "Iron Hammer",
          150,
          1,
          "Hammer_1.png",
          "Meele",
          new String[] {"Damage=40", "Attack Speed=0.15"});
      // INVENTORY.addItem("Steel Hammer", 450,1, "Hammer_0.png","Meele",new
      // String[]{"Damage=60","Attack Speed=0.15"});
      // INVENTORY.addItem("Iron Mace", 50,1, "Mace_1.png","Meele",new String[]{"Damage=15","Attack
      // Speed=0.5"});

      INVENTORY.addItem("Steel Helmet", 250, 1, "Head_1.png", "H_armor", new String[] {"Armor=20"});
      INVENTORY.addItem("Iron Helmet", 150, 1, "Head_2.png", "H_armor", new String[] {"Armor=5"});
      // INVENTORY.addItem("Iron Horn Helmet", 350,1, "Head_6.png","H_armor",new
      // String[]{"Armor=50","Magic Resist=0"});
      // INVENTORY.addItem("Steel Horn Helmet", 500,1, "Head_7.png","H_armor",new
      // String[]{"Armor=80","Magic Resist=0"});
      // INVENTORY.addItem("Skysteel Helmet", 4000,1, "Head_4.png","H_armor",new
      // String[]{"Armor=60","Magic Resist=25"});

      INVENTORY.addItem(
          "Iron Cuirass", 250, 1, "Chest_4.png", "C_armor", new String[] {"Armor=20"});
      INVENTORY.addItem(
          "Steel Cuirass", 350, 1, "Chest_1.png", "C_armor", new String[] {"Armor=30"});
      // INVENTORY.addItem("Scale Cuirass", 550,1, "Chest_3.png","C_armor",new
      // String[]{"Armor=50"});
      // INVENTORY.addItem("Dark metal Cuirass", 750,1, "Chest_6.png","C_armor",new
      // String[]{"Armor=70"});
      // INVENTORY.addItem("Master Cuirass", 3050,1, "Chest_5.png","C_armor",new
      // String[]{"Armor=80","Magic Resist=25"});
      // INVENTORY.addItem("Legendary Cuirass", 3050,1, "Chest_2.png","C_armor",new
      // String[]{"Armor=100","Magic Resist=100"});

      INVENTORY.addItem(
          "Wooden Shield",
          50,
          1,
          "Shield_1.png",
          "Shield",
          new String[] {"Armor=5", "Magic Resist=0"});

      // Add AI
      NAI = new NPCAI(this);

      // Identify as trader
      INVENTORY.Type = "Trader";

      // Set Stats
      STATS.setStats(new String[] {"Level = 5 "});
      MAX_HEALTH = 200;
      HEALTH = (int) MAX_HEALTH;
    } else if (CLASS.equals("Alchemist")) {
      // Add Items
      INVENTORY.addItem(
          "Health Potion", 25, 50, "Health Pot.png", "Potion", new String[] {"Points=50"});
      INVENTORY.addItem(
          "Mana Potion", 20, 50, "Mana Pot.png", "Potion", new String[] {"Points=50"});
      INVENTORY.addItem(
          "Speed Potion", 10, 50, "Speed Pot.png", "Potion", new String[] {"Points=5"});
      // INVENTORY.addItem("Invisib Potion", 50, 10, "Invisibility Pot.png","Potion",new
      // String[]{"Points=5"});

      // Add AI
      NAI = new NPCAI(this);

      // Identify as trader
      INVENTORY.Type = "Trader";
    } else if (CLASS.equals("Inn Keeper")) {
      // Add Items
      INVENTORY.addItem("Roasted Fish", 15, 10, "Fish.png", "Food", new String[] {"Points=5"});
      INVENTORY.addItem("Apple", 15, 10, "Apple.png", "Food", new String[] {"Points=2"});

      // Add AI
      NAI = new NPCAI(this);

      // Identify as trader
      INVENTORY.Type = "Trader";
    } else if (CLASS.equals("Mage")) {

      INVENTORY.addItem(
          "Leather Cap",
          250,
          1,
          "Head_8.png",
          "H_armor",
          new String[] {"Armor=5", "Magic Resist=25"});
      INVENTORY.addItem(
          "Dark Leather Cap",
          300,
          1,
          "Head_9.png",
          "H_armor",
          new String[] {"Armor=5", "Magic Resist=50"});
      // INVENTORY.addItem("Jesters Cap", 500,1, "Head_5.png","H_armor",new
      // String[]{"Armor=10","Magic Resist=90"});
      // INVENTORY.addItem("Skull Helmet", 5000,1, "Head_3.png","H_armor",new
      // String[]{"Armor=100","Magic Resist=100"});
      INVENTORY.addItem(
          "Shock Spell Stone",
          250,
          1,
          "Stone_1.png",
          "SpellStoner",
          new String[] {"Damage=" + SHOCK[0].STATS.DAMAGE});
      // INVENTORY.addItem("Darkness Spell Stone", 500,1, "Stone_1.png","SpellStoner",new
      // String[]{"Damage="+DARKNESS[0].STATS.DAMAGE});
      INVENTORY.addItem(
          "Life Drain Spell Stone",
          300,
          1,
          "Stone_1.png",
          "SpellStoner",
          new String[] {"Damage=" + LIFE_DRAIN[0].STATS.DAMAGE});

      // Add AI
      NAI = new NPCAI(this);

      // Identify as trader
      INVENTORY.Type = "Trader";

    } else if (CLASS.equals("Skeleton")) {

      // Add items
      INVENTORY.addItem(
          "Bone Club", 5, 1, "Mace_2.png", "Meele", new String[] {"Damage=5", "Attack Speed=1"});

      // Add Gold
      this.GOLD = (int) Math.round(Math.random() * 10 + 2);

      // Use Item
      INVENTORY.ItemEffect(0, this);

      // Add AI
      EAI = new EnemyAI(this);
    } else if (CLASS.equals("Skeleton Chieftan")) {

      // Add Item
      INVENTORY.addItem(
          "Iron Sword",
          50,
          1,
          "Sword_2.png",
          "Meele",
          new String[] {"Damage=15", "Attack Speed=0.65"});
      INVENTORY.addItem(
          "Health Potion", 25, 1, "Health Pot.png", "Potion", new String[] {"Points=50"});

      // Add Gold
      this.GOLD = (int) Math.round(Math.random() * 50 + 25);

      // Use Item
      INVENTORY.ItemEffect(0, this);

      // Assign Stats
      STATS.LEVEL = 3;
      HEALTH = 250;
      MAX_HEALTH = 250;

      // Opify
      Opify(1 / 1.25);

      // Add AI
      EAI = new EnemyAI(this);
    } else if (CLASS.equals("Shaman")) {

      // Add items
      INVENTORY.addItem(
          "Health Potion", 25, 1, "Health Pot.png", "Potion", new String[] {"Points=50"});

      // Add Ai
      NAI = new NPCAI(this);

    } else if (CLASS.equals("Dark Elf")) {

      // Add items
      INVENTORY.addItem(
          "Rusted Dagger",
          20,
          1,
          "Dagger_4.png",
          "Meele",
          new String[] {"Damage=10", "Attack Speed=1"});
      INVENTORY.addItem("Iron Helmet", 150, 1, "Head_2.png", "H_armor", new String[] {"Armor=5"});

      // Assign Stats
      STATS.LEVEL = 2;
      HEALTH = 150;
      MAX_HEALTH = 150;

      // Add Gold
      this.GOLD = (int) Math.round(Math.random() * 15 + 2);

      // Use Item
      INVENTORY.ItemEffect(0, this);
      INVENTORY.ItemEffect(1, this);

      // Add Ai
      EAI = new EnemyAI(this);

    } else if (CLASS.equals("Prisoner")) {
      INVENTORY.addItem("Key", 0, 1, "Key.png", "Key", new String[] {});
      // NAI= new NPCAI(this);
    }
  }