using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using LibUsbDotNet;
using LibUsbDotNet.Main;
using LibUsbDotNet.DeviceNotify;

namespace Salamax
{
  public class BridgeService
  {
    private WiiRemote _wiiRemote = new WiiRemote();
    private SilverlinkCable _silverlink = new SilverlinkCable();
    private Xbox360Controller _controller = new Xbox360Controller();
    public UsbDevice _controllerDevice = null;

    public BridgeService()
    {
      _silverlink.ReceivedStaticDataRequest += _silverlink_ReceivedStaticDataRequest;
      _silverlink.ReceivedChallenge1 += _silverlink_ReceivedChallenge1;
      _silverlink.ReceivedChallenge2 += _silverlink_ReceivedChallenge2;
      ButtonStateChanges.ButtonStateChanged += ButtonStateChanges_ButtonStateChanged;

      ButtonStateChanges.AddNotifier(_wiiRemote);
    }

    public WiiRemote Wiimote
    {
      get
      {
        return _wiiRemote;
      }
    }

    public bool IsSilverlinkConnected
    {
      get
      {
        return _silverlink.IsConnected;
      }
    }

    public bool IsControllerConnected
    {
      get
      {
        return _controller.IsConnected;
      }
    }

    public void Start()
    {
      try { _wiiRemote.Connect(); }
      catch { /* Eat it, because the Wiimote library is a little dumb... */ };

      //Detect all the necessary devices
      _FindAllDevices();

      Logger.WriteLine("Bridge service started.", Logger.Type.Information);
    }

    public void ForwardButtonStateChanges()
    {
      ButtonStateChanges.RefreshState();
    }

    public void Stop()
    {
      //Disconnect all devices
      _wiiRemote.Disconnect();
      _controller.Disconnect();
      _silverlink.Disconnect();

      Logger.WriteLine("Bridge service stopped.", Logger.Type.Information);
    }

    private void _FindAllDevices()
    {
      _controller.Find();
      _silverlink.Find();
    }

    private void _silverlink_ReceivedChallenge1(object sender, ChallengeEventArgs e)
    {
      var buffer = _controller.DoChallenge1(e.Data);
      _silverlink.ForwardData(0x83, buffer, buffer.Length);
    }

    private void _silverlink_ReceivedChallenge2(object sender, ChallengeEventArgs e)
    {
      var buffer = _controller.DoChallenge2(e.Data);
      _silverlink.ForwardData(0x83, buffer, buffer.Length);
    }

    private void _silverlink_ReceivedStaticDataRequest(object sender, EventArgs e)
    {
      //Get the data from the controller
      var buffer = _controller.RequestStaticData();

      //Send the response back
      _silverlink.ForwardData(0x81, buffer, buffer.Length);
    }

    private void ButtonStateChanges_ButtonStateChanged(object sender, EventArgs e)
    {
      _silverlink.ForwardData(0x00, ButtonStateChanges.KeyStateInfo, ButtonStateChanges.KeyStateInfo.Length);
    }
  }
}
