/*
 * Copyright (c) 2014 Paul Scherrer Institute. All rights reserved.
 */

import ch.psi.pshell.device.*;
import com.sun.jna.Function;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.StdCallLibrary;
import com.sun.jna.win32.W32APIFunctionMapper;
import com.sun.jna.win32.W32APITypeMapper;
import java.util.HashMap;
import java.util.Map;

/**
 */
public class Beeper extends DeviceBase {

    public Beeper(String name) {
        super(name);
    }

    // JNA Mapping
    static Map UNICODE_OPTIONS = new HashMap() {

        {
            put("type-mapper", W32APITypeMapper.UNICODE);
            put("function-mapper", W32APIFunctionMapper.UNICODE);
        }
    };

    interface Kernel32 extends StdCallLibrary {

        public static final String LIBRARY_NAME = "kernel32";
        Kernel32 INSTANCE = (Kernel32) Native.loadLibrary(LIBRARY_NAME, Kernel32.class, UNICODE_OPTIONS);
        Kernel32 SYNC_INSTANCE = (Kernel32) Native.synchronizedLibrary(INSTANCE);

        boolean Beep(int FREQUENCY, int DURATION);

        void Sleep(int DURATION);

        int CreateEventW(Pointer securityAttributes, boolean manualReset, boolean initialState, String name);

        int CreateThread(/*Pointer*/int lpThreadAttributes, IntByReference dwStackSize, Function lpStartAddress, Structure lpParameter, int dwCreationFlags, IntByReference lpThreadId);
        public static final int STILL_ACTIVE = 259;

        int GetExitCodeThread(int hThread, IntByReference lpExitCode);

        int GetLastError();

        boolean CloseHandle(int handle);

    }
    private final int mEventHandle = Kernel32.INSTANCE.CreateEventW(Pointer.NULL, true, false, null);

    
    //Public interface
    public int getLastError(){
        return Kernel32.SYNC_INSTANCE.GetLastError();
    }
    
    public void sleep(int duration){
        Kernel32.SYNC_INSTANCE.Sleep(duration);
    }
    
    public void beep(int frequency, int duration){
        Kernel32.SYNC_INSTANCE.Beep(frequency, duration);
    }
    
}
