/*
 *  Initiative - A role playing utility to track turns
 *  Copyright (C) 2002 Devon D Jones
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  The author of this program grants you the ability to use this code
 *  in conjunction with code that is covered under the Open Gaming License
 *
 * XMLCombatant.java
 *
 * Created on January 24, 2002, 11:15 AM
 *
 * This file is Open Game Content, covered by the OGL.
 */

package org.evilsoft.gaming.Init;

import org.jdom.*;
import org.jdom.output.XMLOutputter;
import org.evilsoft.gaming.*;
import org.evilsoft.gaming.System.SystemInitiative;
import org.evilsoft.gaming.System.SystemAttribute;
import org.evilsoft.gaming.System.SystemHP;
import java.util.Vector;

/**
 *
 * @author  devon
 * @version
 */
public class XMLCombatant implements InitHolder {

    public SystemInitiative init;

    private SystemHP hitPoints;
    private String holderType = "XMLCombatant";
//    private Document XMLCombatant;
    private Element combatant;
    private String status = "";
    private final boolean DEBUG = false;
    private int number;


    /** Creates new XMLCombatant */
    public XMLCombatant(Element combatant) {
        this.combatant = combatant;
        try {
            if(!DEBUG) {
                System.out.println("OGC: The Initiative bonus is based off of the Dexterity modifier");
                System.out.println("Code: ");
                System.out.println("int dexVal = combatant.getChild(\"Attributes\").getChild(\"Dexterity\").getAttribute(\"value\").getIntValue();");
                System.out.println("String sInitBonus = combatant.getChild(\"Combat\").getChild(\"Initiative\").getAttribute(\"Misc\").getValue();");
                System.out.println("int initBonus = 0;");
                System.out.println("if(sInitBonus.startsWith(\"+\")) {");
                System.out.println("  sInitBonus = sInitBonus.substring(1);");
                System.out.println("  initBonus = Integer.parseInt(sInitBonus);");
                System.out.println("}");
                System.out.println("else {");
                System.out.println("  initBonus = Integer.parseInt(sInitBonus);");
                System.out.println("}");
                System.out.println("SystemAttribute dex = new SystemAttribute(\"Dexterity\", dexVal);");
                System.out.println("init = new SystemInitiative(dex, initBonus);");
            }
            int dexVal = combatant.getChild("Attributes").getChild("Dexterity").getAttribute("value").getIntValue();
            int conVal = combatant.getChild("Attributes").getChild("Constitution").getAttribute("value").getIntValue();
            int hpVal = combatant.getChild("Combat").getChild("HitPoints").getAttribute("value").getIntValue();
            int hpCurrVal = combatant.getChild("Combat").getChild("HitPoints").getAttribute("current").getIntValue();
            String sInitBonus = combatant.getChild("Combat").getChild("Initiative").getAttribute("Misc").getValue();
            int initBonus = 0;
            if(sInitBonus.startsWith("+")) {
                sInitBonus = sInitBonus.substring(1);
                initBonus = Integer.parseInt(sInitBonus);
            }
            else {
                initBonus = Integer.parseInt(sInitBonus);
            }
            createSystemVals(dexVal, conVal, hpVal, hpCurrVal, initBonus);
            //SystemAttribute dex = new SystemAttribute("Dexterity", dexVal);
            //init = new SystemInitiative(dex, initBonus);
            //hitPoints = new SystemHP(new SystemAttribute("Constitution", conVal), hpVal, hpCurrVal);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

    public XMLCombatant(String name, String player, int dexVal, int conVal, int hpVal, int hpCurrVal, int initBonus) {
        createSystemVals(dexVal, conVal, hpVal, hpCurrVal, initBonus);
        int dexMod = init.getAttribute().getModifier();
        int miscMod = initBonus - dexMod;
        combatant = new Element("Character");
        combatant.setAttribute("name", name);
        combatant.setAttribute("player", player);
        Element attributes = new Element("Attributes");
        attributes.addContent(new Element("Dexterity").setAttribute("value", dexVal + ""));
        attributes.addContent(new Element("Constitution").setAttribute("value", dexVal + ""));
        combatant.addContent(attributes);
        Element combat = new Element("Combat");
        combat.addContent(new Element("Initiative").setAttribute("mod", formatBonus(initBonus)).setAttribute("Dex", formatBonus(dexMod)).setAttribute("Misc", formatBonus(miscMod)));
        combat.addContent(new Element("HitPoints").setAttribute("value", hpVal + "").setAttribute("current", hpCurrVal + ""));
        combatant.addContent(combat);
    }

    private void createSystemVals(int dexVal, int conVal, int hpVal, int hpCurrVal, int initBonus) {
        init = new SystemInitiative(new SystemAttribute("Dexterity", dexVal), initBonus);
        hitPoints = new SystemHP(new SystemAttribute("Constitution", conVal), hpVal, hpCurrVal);
    }

    private String formatBonus(int bonus) {
        if(bonus >= 0) {
            return "+" + bonus;
        }
        else {
            return "-" + bonus;
        }
    }

    public String getPlayer() {
        return combatant.getAttribute("player").getValue();
    }

    public SystemInitiative getInitiative() {
        return init;
    }

    public SystemHP getHP() {
        return hitPoints;
    }

    public String getName() {
        return combatant.getAttribute("name").getValue();
    }

    public String getHolderType() {
        return holderType;
    }

    public void setInitBonus(int initBonus) {
        init.setBonus(initBonus);
    }

    public void setName(String name) {
        combatant.getAttribute("player").setValue(name);
    }

    public void setPlayer(String player) {
        combatant.getAttribute("player").setValue(player);
    }

    public Element getElement() {
        return combatant;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public Vector getRowVector(Vector columnOrder) {
        Vector rowVector = new Vector();
        int columns = columnOrder.size();
        for(int j = 0; j < columns; j++) {
            String columnName = (String)columnOrder.get(j);
            if(columnName.equals("Name")) {
                rowVector.add(getName());
            }
            else if(columnName.equals("Player")) {
                rowVector.add(getPlayer());
            }
            else if(columnName.equals("Status")) {
                rowVector.add(getStatus());
            }
            else if(columnName.equals("+")) {
                rowVector.add("" + init.getModifier());
            }
            else if(columnName.equals("Init")) {
                rowVector.add("" + init.getCurrentInitiative());
            }
            else if(columnName.equals("Dur")) {
                rowVector.add("");
            }
            else if(columnName.equals("#")) {
                rowVector.add("" + number);
            }
            else if(columnName.equals("HP")) {
                rowVector.add("" + hitPoints.getCurrent());
            }
            else if(columnName.equals("HP Max")) {
                rowVector.add("" + hitPoints.getMax());
            }
        }
        return rowVector;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public void editRow(Vector columnOrder, int colNumber, Object data) {
        Vector rowVector = new Vector();
        String columnName = (String)columnOrder.elementAt(colNumber);
        String strData = String.valueOf(data);
        if(columnName.equals("Name")) {
            setName(strData);
        }
        else if(columnName.equals("Player")) {
            setPlayer(strData);
        }
        else if(columnName.equals("Status")) {
            setStatus(strData);
        }
        else if(columnName.equals("+")) {
            Integer intData = new Integer(strData);
            setInitBonus(intData.intValue());
        }
        else if(columnName.equals("Init")) {
            Integer intData = new Integer(strData);
            init.setCurrentInitiative(intData.intValue());
        }
        else if(columnName.equals("#")) {
            Integer intData = new Integer(strData);
            setNumber(intData.intValue());
        }
        else if(columnName.equals("HP")) {
            Integer intData = new Integer(strData);
            hitPoints.setCurrent(intData.intValue());
        }
        else if(columnName.equals("HP Max")) {
            Integer intData = new Integer(strData);
            hitPoints.setMax(intData.intValue());
        }
    }

    public void stabilize() {
        setStatus(hitPoints.stabilize());
    }

    public void raise() {
        setStatus(hitPoints.raise());
    }

    public void kill() {
        setStatus(hitPoints.kill());
    }

    public void bleed() {
        setStatus(hitPoints.bleed());
    }

    public void damage(int damage) {
        setStatus(hitPoints.damage(damage));
    }

    public void heal(int heal) {
        setStatus(hitPoints.heal(heal));
    }

    public Element getSaveElement() {
        Element retElement = (Element)combatant.clone();
        retElement.detach();
        int dexMod = init.getAttribute().getModifier();
        int initBonus = init.getModifier();
        int miscMod = init.getBonus();
        retElement.getChild("Attributes").getChild("Dexterity").setAttribute("value", init.getAttribute().getValue() + "");
        retElement.getChild("Attributes").getChild("Constitution").setAttribute("value", hitPoints.getAttribute().getValue() + "");
        retElement.getChild("Combat").getChild("HitPoints").setAttribute("value", hitPoints.getMax() + "");
        retElement.getChild("Combat").getChild("HitPoints").setAttribute("current", hitPoints.getCurrent() + "");
        retElement.getChild("Combat").getChild("Initiative").setAttribute("mod", formatBonus(initBonus));
        retElement.getChild("Combat").getChild("Initiative").setAttribute("Dex", formatBonus(dexMod));
        retElement.getChild("Combat").getChild("Initiative").setAttribute("Misc", formatBonus(miscMod));
        retElement.setAttribute("name", getName());
        retElement.setAttribute("player", getPlayer());
        return retElement;
    }

    private String escapeString(String rawString) {
        System.out.println(rawString);
        StringBuffer newString = new StringBuffer();
        char[] rawChar = rawString.toCharArray();
        for(int i = 0; i < rawChar.length; i++) {
            int charnum = new Character(rawChar[i]).hashCode();
            System.out.println(charnum);
            if(charnum <= 127) {
                newString.append(rawChar[i]);
            }
            else {
                newString.append("&#" + charnum + ";");
            }
        }
        System.out.println(newString.toString());
        return newString.toString();
    }
}
