/*
 *  RPGeneration - A role playing utility generate interesting things
 *  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
 *
 * VariableHashMap.java
 *
 * Created on November 1, 2002, 1:15 PM
 */

package org.evilsoft.gaming.RPGeneration;

import java.util.Random;
import org.jdom.*;
/**
 *
 * @author  devon
 */
public class VariableHashMap extends java.util.HashMap {
    private Random rand = new Random();
    private java.util.ArrayList initialize = new java.util.ArrayList();
    private java.util.HashMap tables;

    private boolean DEBUG = false;

    /** Creates a new instance of VariableHashMap */
    public VariableHashMap() {
        this.tables = new java.util.HashMap();
    }

    public VariableHashMap(java.util.HashMap tables) {
        this.tables = tables;
    }

    public void newVar(Element varElement) throws variableException {
        String key;
        try {
            key = varElement.getAttribute("Name").getValue();

            if(get(key) != null) {
                throw new variableException("Variable " + key + " exists, cannot create again");
            }
            put(key, "");
            if(DEBUG) {System.out.println("Key: '" + key + "'");}
        }
        catch(Exception e) {
            System.out.println("XML ERROR");
            e.printStackTrace();
        }
    }
    
    public void setVar(String key, String value) throws variableException {
        if(get(key) == null) {
            throw new variableException("Variable " + key + " does not exist, cannot set value");
        }
        put(key, value);
    }

    public String getVal(String key) throws variableException {
        if(get(key) == null) {
            throw new variableException("Variable " + key + " does not exist, cannot get value");
        }
        return (String)get(key);
    }

    public String addVar(String key, int add) throws variableException {
        if(get(key) == null) {
            throw new variableException("Variable " + key + " does not exist, cannot add to value");
        }
        if(get(key) == "") {
            put(key, "0");
        }
        int val = new Integer((String)get(key)).intValue();
        val = val + add;
        put(key, val + "");
        return val + "";
    }

    public String subtractVar(String key, int subtract) throws variableException {
        if(get(key) == null) {
            throw new variableException("Variable " + key + " does not exist, cannot subtract from value");
        }
        if(get(key) == "") {
            put(key, "0");
        }
        int val = new Integer((String)get(key)).intValue();
        val = val - subtract;
        put(key, val + "");
        return val + "";
    }

    public String multiplyVar(String key, int multiply) throws variableException {
        if(get(key) == null) {
            throw new variableException("Variable " + key + " does not exist, cannot multiply by value");
        }
        if(get(key) == "") {
            put(key, "0");
        }
        int val = new Integer((String)get(key)).intValue();
        val = val * multiply;
        put(key, val + "");
        return val + "";
    }

    public String divideVar(String key, int divide) throws variableException {
        if(get(key) == null) {
            throw new variableException("Variable " + key + " does not exist, cannot divide by value");
        }
        if(get(key) == "") {
            put(key, "0");
        }
        int val = new Integer((String)get(key)).intValue();
        val = val / divide;
        put(key, val + "");
        return val + "";
    }

    public void addTable(Element tableElement) {
        Trait table = new Trait(tableElement, this);
        if(DEBUG) { System.out.println("Put: TABLE " + table.getType()); }
        String key = table.getType();
        tables.put(key, table);
    }

    public Detail getTableDetail(String key) {
        if(DEBUG) { System.out.println("Get: TABLE " + key); }
        Trait table = (Trait)tables.get(key);
        return table.getDetail();
    }

    public void addInitialOperations(Operation op) {
        initialize.add(op);
    }

    public void initialize() throws variableException {
        doOperation(initialize);
    }

    public void doOperation(java.util.ArrayList ops) throws variableException {
        for(int i = 0; i < ops.size(); i++) {
            doOperation((Operation)ops.get(i));
        }
    }

    public void doOperation(Operation op) throws variableException {
        String type = op.getType();
        String key = op.getKey();
        String value = op.getValue();
        if(DEBUG) {System.out.println("Operation Type: " + type + " Key: " + key + " Value: " + value);}

        if(type.equals("Set")) {
            value = parse(value);
            setVar(key, value);
        }
        else if(type.equals("Add")) {
            int val = new Integer(parse(value)).intValue();
            addVar(key, val);
        }
        else if(type.equals("Subtract")) {
            int val = new Integer(parse(value)).intValue();
            subtractVar(key, val);
        }
        else if(type.equals("Multiply")) {
            int val = new Integer(parse(value)).intValue();
            multiplyVar(key, val);
        }
        else if(type.equals("Divide")) {
            int val = new Integer(parse(value)).intValue();
            divideVar(key, val);
        }
    }

    public String parse(String val) {
        String retString = val;
        if(val.matches("\\$\\{.*?\\}.*")) {
            String var = val.substring(val.indexOf("${") + 2, val.indexOf("}"));
            String value = (String)get(var);
            if(value == null) {
                value = "";
            }
            retString = val.replaceFirst("\\$\\{.*?\\}", value) ;
        }
        if(DEBUG) {System.out.println("Parse: " + val + " To: " + retString);}
        return retString;
    }

    public Random getRandom() {
        return rand;
    }
}
