/*

CLASS {NATIVE_Configuration|_Java}, NATIVE:

*/

import java.util.ArrayList;
import java.util.prefs.*;

public class NATIVE_Configuration {
    
    public static ArrayList<NATIVE_Configuration> All_configs = 
        new ArrayList<NATIVE_Configuration>();

    public static int Create_new_configure(int Area, String Path, String Name,
        Boolean Write, Boolean Create) {
        //DEBUG:
        //AL4_system.WriteLine("Create_new_configure: " + Area + ", " + Path + 
        //", " + Name + ", " + Write + ", " + Create);
        //-----------------------------
        if (All_configs.size() == 0)
        All_configs.add(null);
        int h = All_configs.lastIndexOf(null);
        if (h <= 0) {
           h = All_configs.size();
           All_configs.add(null);
        }
        All_configs.set(h, 
            new NATIVE_Configuration(Area, Path, Name, Write, Create));
        return h;
    }

    String Name;
    String Key_name;
    Boolean Read_only;
    Boolean Can_create;
    
    Preferences javaPrefs;
    
    public NATIVE_Configuration(int Area, String Path, String Name, 
        Boolean Write, Boolean Create) {
            
        if (Area == 0) 
            javaPrefs = Preferences.userNodeForPackage(
                        NATIVE_Configuration.class);
        else
            javaPrefs = Preferences.systemNodeForPackage(
                        NATIVE_Configuration.class);
        
        Key_name = Path;
        if (Area == 1 && !starting(Key_name, "HKEY_LOCAL_MACHINE\\")) {
            Key_name = "HKEY_LOCAL_MACHINE\\" + Key_name;
        }
        else if (Area == 0 && !starting(Key_name, "HKEY_")) {
            Key_name = "HKEY_CURRENT_USER\\Software\\" + Name +
            "\\" + Key_name;
        }
        for (int i = Key_name.length()-1; i >= 0; i--)
            if (Key_name.charAt(i) == '\\')
                Key_name = Key_name.substring(0, i) + '/' +
                           Key_name.substring(i+1);
        Read_only = !Write;
        Can_create = Create;
        //DEBUG:
        //AL4_system.WriteLine("Created: " + Name + ", " + Key_name + ", " +
        //Read_only + ", " + Can_create);
        //-----------------------------
    }
    
    public static String Value_String(int Handle, 
        String Name_value, String New_value, Boolean Set_new)
    {
        //DEBUG:
        //AL4_system.WriteLine("Value_String: " + Name_value + " = " + New_value +
        //", Set_new = " + Set_new);
        //-----------------------------
        NATIVE_Configuration config = All_configs.get(Handle);
        //DEBUG:
        //AL4_system.WriteLine("config= " + config);
        //-----------------------------
        Preferences k = config.create_key();
        //DEBUG:
        //AL4_system.WriteLine("k= " + k);
        //-----------------------------
        String RESULT = k.get(Name_value, "");
        //DEBUG:
        //AL4_system.WriteLine("RESULT= " + RESULT);
        //-----------------------------
        if (RESULT == null)
        {
            RESULT = "";
            if (!config.Can_create) {
                //DEBUG:
                //AL4_system.WriteLine("config.Can_create: " + config.Can_create);
                //-----------------------------
                return RESULT;
            }
        }
        //DEBUG:
        //AL4_system.WriteLine("Set_new: " + Set_new + ", read_only: " + config.Read_only);
        //-----------------------------
        if (Set_new && !config.Read_only) {
            //DEBUG:
            //AL4_system.WriteLine("put: " + Name_value + " = " + New_value);
            //-----------------------------
            k.put(Name_value, New_value);
        }
        return RESULT;
    }
    
    public static int Value_integer(int Handle, 
        String Name_value, int New_value, Boolean Set_new)
    {
        NATIVE_Configuration config = All_configs.get(Handle);
        Preferences k = config.create_key();
        int RESULT = k.getInt(Name_value, 0);
        if (Set_new && !config.Read_only)
            k.putInt(Name_value, New_value);
        return RESULT;
    }
    
    public static Boolean Value_boolean(int Handle, 
        String Name_value, Boolean New_value, Boolean Set_new)
    {
        NATIVE_Configuration config = All_configs.get(Handle);
        Preferences k = config.create_key();
        Boolean RESULT = k.getBoolean(Name_value, false);
        if (Set_new && !config.Read_only)
            k.putBoolean(Name_value, New_value);
        return RESULT;
    }
    
    public static String Binary_get(int Handle, String Name_value)
    {
        NATIVE_Configuration config = All_configs.get(Handle);
        Preferences k = config.create_key();
        byte[] data = k.getByteArray(Name_value, null);
        String RESULT = "";
        if (data != null) {
            for (int i = 0; i < data.length; i++) {
                RESULT += (char)data[i];
            } 
        }
        return RESULT;
    }
    
    public static Boolean Value_present(int Handle, String Name_value)
            throws Exception
    {
        NATIVE_Configuration config = All_configs.get(Handle);
        Preferences k = config.create_key();
        String[] list = k.keys();
        for (int i = 0; i < list.length; i++)
            if (list[i].equals(Name_value)) return true;
        return false;
    }
    
    public static void Value_delete(int Handle, String Name_value)
    {
        NATIVE_Configuration config = All_configs.get(Handle);
        Preferences k = config.create_key();
        k.remove(Name_value);
    }
    
    public static void Subkey_delete(int Handle, String Name_subkey)
            throws Exception 
    {
        NATIVE_Configuration config = All_configs.get(Handle);
        Preferences k = config.create_key();
        k.node(Name_subkey).removeNode();
    }
    
    public static void Values_list(int Handle, DynAStr List)
            throws Exception
    {
        List.Clear();
        NATIVE_Configuration config = All_configs.get(Handle);
        Preferences k = config.create_key();
        String[] list = k.keys();
        for (int i = 0; i < list.length; i++)
            List.Add(list[i]);
    }
    
    public static void Subkeys_list(int Handle, DynAStr List)
            throws Exception
    {
        List.Clear();
        NATIVE_Configuration config = All_configs.get(Handle);
        Preferences k = config.create_key();
        String[] list = k.childrenNames();
        for (int i = 0; i < list.length; i++)
            List.Add(list[i]);
    }
    
    private Boolean starting(String X, String Y)
    {
        if (X.length() < Y.length()) {
            return false;
        }
        if (!X.substring(0, Y.length()).equals(Y)) {
            return false;
        }
        return true;
    }
    
    public Preferences create_key()
    {
        //for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
        //    System.out.println(ste);
        //}
        //DEBUG:
        //AL4_system.WriteLine("create_key" + Key_name);
        //--------------------------------------------
        String path = Key_name;
        
        Preferences base_key = null;
        if (starting(path, "HKEY_LOCAL_MACHINE\\") || 
            starting(path, "HKEY_LOCAL_MACHINE/")
           )
            base_key = Preferences.systemRoot();
        else base_key = Preferences.userRoot();
        
        if (starting(path, "HKEY_"))
        {
            //DEBUG:
            //AL4_system.WriteLine("Cutting HKEY_: " + path);
            //--------------------------------------------
            for (int i = 0; i < path.length(); i++)
                if (path.charAt(i) == '\\' || path.charAt(i) == '/')
                {
                    path = path.substring(i+1);
                    break;
                }
        }
        if (path.length() > 0 && path.charAt(path.length()-1) == '/')
            path = path.substring(0, path.length()-1);
        //DEBUG:
        //AL4_system.WriteLine("before base_key.node(" + path + "), base_key=" + base_key);
        //--------------------------------------------
        Preferences RESULT = base_key;
        try {
            RESULT = base_key.node(path);
        }
        catch (Exception Ex) {
            AL4_system.WriteLine("Exception: " + Ex.getMessage());
            Ex.printStackTrace();
        }
        //DEBUG:
        //AL4_system.WriteLine("Preferences=" + path + ", RESULT=" + RESULT);
        //--------------------------------------------
        return RESULT;
    }
    
/*
    
CONST STR:
    NATIVE_configure_import = ""

    NATIVE_new_configure_object = @
    "   RESULT = NATIVE_Configuration.Create_new_configure("
    "       X_Area, X_Path, X_Name, !X_Read, X_Can_create);"
    
    NATIVE_release_configure_object = @
    "   if (NATIVE_Configuration.All_configs.size() > X_Handle &&"
    "       X_Handle >= 0)"
    "       NATIVE_Configuration.All_configs.set(X_Handle, null);"
    
    NATIVE_value_string = @
    "   RESULT = NATIVE_Configuration.Value_String("
    "       X_Handle, X_Name, X_New, X_Set);"
    
    NATIVE_value_integer = @
    "   RESULT = NATIVE_Configuration.Value_integer("
    "       X_Handle, X_Name, X_New, X_Set);"
    
    NATIVE_value_boolean = @
    "   RESULT = NATIVE_Configuration.Value_boolean("
    "       X_Handle, X_Name, X_New, X_Set);"
    
    NATIVE_binary_get = @
    "   RESULT = NATIVE_Configuration.Binary_get(X_Handle, X_Name);"
        
    NATIVE_present_value = @
    "   RESULT = NATIVE_Configuration.Value_present("
    "       X_Handle, X_Name);"
    
    NATIVE_list_values = @
    "   NATIVE_Configuration.Values_list(X_Handle, X_List);"
    
    NATIVE_list_subkeys = @
    "   NATIVE_Configuration.Subkeys_list(X_Handle, X_List);"
    
    NATIVE_delete_value = @
    "   NATIVE_Configuration.Value_delete(X_Handle, X_Name);"
    
    NATIVE_delete_subkey = @
    "   NATIVE_Configuration.Subkey_delete(X_Handle, X_Name);"

    .
        
   */

}

/*
END
*/

