/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package hash;

import java.util.Hashtable;
import java.util.Enumeration;
import mdot.Main;
import structures.Constants;
import structures.HashContext;
import CommonFunctions.debugPrinter;

/*class hashUtil
 * Contains functions for dealing hash codes
 */
public class hashUtil {

    public static double getHash(double result, String hashValue) {
        double hash = 0;

        hash = result + hashValue.hashCode();
        return hash;
    }

    public static double getHash(String hashValue) {

        double hash = 0;

        hash = hashValue.hashCode();
        return hash;
    }


    //Calculates the hash value for each context and compares it to the
    //current hash value stored in that context's hashtable. If the values are
    //the this context has not changes. If none of the contexts have change,
    //returns false, else returns true.
    public static boolean checkHashChanged() {

        double result = 0;
        double coreresult = 0;
        Object value = null;
        double prevHash = 0;
        double prevCoreHash = 0;
        String currKey = null;
        boolean contextChanged = false;
        String val = "";


        Hashtable<String, HashContext> myContext = Main.getContext();
        Enumeration<HashContext> enHashTables = myContext.elements();
        while (enHashTables.hasMoreElements()) {
            HashContext currHashTable = enHashTables.nextElement();

            Enumeration<String> enHashTableKey = currHashTable.keys();


            //Add up the hash value for each key in the context
            while (enHashTableKey.hasMoreElements()) {
                currKey = enHashTableKey.nextElement();

                value = currHashTable.GetObject(currKey);

                val = value.toString();

                //make sure the current key isn't HASH or RESULT
                if ((!currKey.equals(Constants.HASH_HASHTAG)) && (!currKey.equals("result")) && (!currKey.equals(Constants.HASH_COREHASHTAG))) {
                    result = hashUtil.getHash(result, val);
                }

                //make sure the current key isn't HASH or RESULT
                if (Main.coreHash.contains(currKey)) {
                    coreresult = hashUtil.getHash(coreresult, val);
                }

            }

            if (result == Constants.HASH_INITAL_VALUE) {
                result = 0;
            }

            if (coreresult == Constants.HASH_INITAL_VALUE) {
                result = 0;
            }

            //Get the prev hash stored in the hashTabe
            prevHash = currHashTable.GetObjectAsDouble(Constants.HASH_HASHTAG);
            if (prevHash == -1) {
                prevHash = 0;
            }

            //Get the prev hash_core
            prevCoreHash = currHashTable.GetObjectAsDouble(Constants.HASH_COREHASHTAG);
            if (prevCoreHash == -1) {
                prevCoreHash = 0;
            }


            if (prevHash != result) {
                debugPrinter.printLine("CHANGED--> currHash: " + prevHash + " resultHash: " + Double.toString(result));
            } else {
                debugPrinter.printLine("currHash: " + prevHash + " resultHash: " + Double.toString(result));
            }

            if (prevCoreHash != coreresult) {
                debugPrinter.printLine("CHANGED--> currCoreHash: " + prevCoreHash + " resultCoreHash: " + Double.toString(coreresult));
            } else {
                debugPrinter.printLine("currCoreHash: " + prevCoreHash + " resultCoreHash: " + Double.toString(coreresult));
            }

            debugPrinter.printLine("-----------------------------------------------------------");

            //put the new calculated hash value in the table
            currHashTable.removeObject("hash");
            currHashTable.setObjectAsDouble("hash", result);

            currHashTable.removeObject("hash_core");
            currHashTable.setObjectAsDouble("hash_core", coreresult);


            //if the previous and new hash values aren't equal context has changed
            if (prevHash != result) {
                contextChanged = true;
            }

            //Reset
            result = Constants.HASH_INITAL_VALUE;
            coreresult = Constants.HASH_INITAL_VALUE;
            value = null;
            currKey = null;
            currHashTable = null;

        }

        //determine if a hashtable from the context has changed
        if (contextChanged == true) {
            return true;
        } else {
            return false;
        }

    }
}

