using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;

using UnityEngine;
using System;
public class JoyconManager: MonoBehaviour
{
    public enum JoyconType { left, right };

    // Settings accessible via Unity
    public bool EnableIMU = true;
    public bool EnableLocalize = true;

	// Different operating systems either do or don't like the trailing zero
	private const ushort vendor_id = 0;
	private const ushort vendor_id_ = 0x057e;
	private const ushort product_l = 0x2006;
	private const ushort product_r = 0x2007;

    public List<Joycon> j; // Array of all connected Joy-Cons
    static JoyconManager instance;
    Joycon leftJoycon, rightJoycon;

    public static JoyconManager Instance
    {
        get { return instance; }
    }

    public Joycon GetJoycon(JoyconType type){
        if (type == JoyconType.right && rightJoycon != null)
            return rightJoycon;
        
        if (type == JoyconType.left && leftJoycon != null)
            return leftJoycon;

        return null;  
    }

    void Awake()
    {
        if (instance != null) Destroy(gameObject);
        instance = this;
		int i = 0;

		j = new List<Joycon>();
		bool isLeft = false;
		HIDapi.hid_init();
		Debug.Log("Vendor_id:"+vendor_id);
		IntPtr ptr = HIDapi.hid_enumerate(vendor_id, 0x0);
		Debug.Log("Pointer:"+ptr.ToString());
		IntPtr top_ptr = ptr;

		if (ptr == IntPtr.Zero)
		{
			ptr = HIDapi.hid_enumerate(vendor_id_, 0x0);
			if (ptr == IntPtr.Zero)
			{ 
				HIDapi.hid_free_enumeration(ptr);
				Debug.Log ("No Joy-Cons found!");
			}
		}
		hid_device_info enumerate;
		while (ptr != IntPtr.Zero) {
			enumerate = (hid_device_info)Marshal.PtrToStructure (ptr, typeof(hid_device_info));
			Debug.Log (enumerate.path);
				if (enumerate.product_id == product_l || enumerate.product_id == product_r) {
					if (enumerate.product_id == product_l) {
						isLeft = true;
						Debug.Log ("Left Joy-Con connected.");
					} else if (enumerate.product_id == product_r) {
						isLeft = false;
						Debug.Log ("Right Joy-Con connected.");
					} else {
						Debug.Log ("Non Joy-Con input device skipped.");
					}
					IntPtr handle = HIDapi.hid_open_path (enumerate.path);
					HIDapi.hid_set_nonblocking (handle, 1);
                Joycon joycon = new Joycon(handle, EnableIMU, EnableLocalize & EnableIMU, 0.05f, isLeft);
                j.Add (joycon);

                if (isLeft)
                    leftJoycon = joycon;
                else
                    rightJoycon = joycon;
                
					++i;
				}
				ptr = enumerate.next;
			}
		HIDapi.hid_free_enumeration (top_ptr);
    }

    void Start()
    {
		Debug.Log("Start JM");
		for (int i = 0; i < j.Count; ++i)
		{
			Debug.Log ("LED:"+i);
			Joycon jc = j [i];
			byte LEDs = 0x0;
			LEDs |= (byte)(0x3 << i);
			jc.Attach (leds_: LEDs);
			jc.Begin ();
		}
    }

    void Update()
    {
		for (int i = 0; i < j.Count; ++i)
		{
			j[i].Update();
		}
    }

    void OnApplicationQuit()
    {
		for (int i = 0; i < j.Count; ++i)
		{
			j[i].Detach ();
		}
    }
}
