using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Ruby;
using VALUE = System.Int32;
using StarEngine.Core;

namespace StarEngine.Ruby
{
    public partial class RubyInterpreter
    {
        private void InitializeInputModule()
        {
            VALUE mInput = SERubyConsts.ForName("Input");

            RUBY.rb_define_singleton_method(mInput, "__cs_pressed_keys__",
                delegate(VALUE self, VALUE rbDevice, VALUE rbOptions)
                {
                    IInput input = this.GameEnvironment.Input;

                    VALUE rbKeys = RUBY.rb_ary_new();

                    string csDevice = RUBY.StringValuePtr(RUBY.Send(rbDevice, "to_s"));
                    int csDeviceNumber = RUBY.NUM2INT(RUBY.HashAref(rbOptions, "device_number"));
                    int csDuration = RUBY.NUM2INT(RUBY.HashAref(rbOptions, "duration"));
                    int csDelay = RUBY.NUM2INT(RUBY.HashAref(rbOptions, "delay"));
                    int csInterval = RUBY.NUM2INT(RUBY.HashAref(rbOptions, "interval"));

                    if (csDevice == "keyboard")
                    {
                        Keys[] keys = input.GetPressedKeyboardKeys(csDuration, csDelay, csInterval);
                        foreach (Keys key in keys)
                            RUBY.rb_ary_push(rbKeys, RUBY.Intern(key.ToString().ToLower()));
                    }
                    else if (csDevice == "game_pad")
                    {
                        GamePadDirections directions = input.GetPressedGamePadDirections(csDeviceNumber, csDuration, csDelay, csInterval);
                        if ((directions & GamePadDirections.Down) != 0)
                            RUBY.rb_ary_push(rbKeys, RUBY.Intern("down"));
                        if ((directions & GamePadDirections.Left) != 0)
                            RUBY.rb_ary_push(rbKeys, RUBY.Intern("left"));
                        if ((directions & GamePadDirections.Right) != 0)
                            RUBY.rb_ary_push(rbKeys, RUBY.Intern("right"));
                        if ((directions & GamePadDirections.Up) != 0)
                            RUBY.rb_ary_push(rbKeys, RUBY.Intern("up"));

                        int[] buttons = input.GetPressedGamePadButtons(csDeviceNumber, csDuration, csDelay, csInterval);
                        foreach (int button in buttons)
                            RUBY.rb_ary_push(rbKeys, RUBY.INT2NUM(button));
                    }
                    else if (csDevice == "mouse")
                    {
                        MouseButtons buttons = input.GetPressedMouseButtons(csDuration, csDelay, csInterval);
                        if ((buttons & MouseButtons.Left) != 0)
                            RUBY.rb_ary_push(rbKeys, RUBY.Intern("left"));
                        if ((buttons & MouseButtons.Middle) != 0)
                            RUBY.rb_ary_push(rbKeys, RUBY.Intern("middle"));
                        if ((buttons & MouseButtons.Right) != 0)
                            RUBY.rb_ary_push(rbKeys, RUBY.Intern("right"));
                    }
                    else
                    {
                        RUBY.rb_raise(SERubyConsts.ForName("::ArgumentError"), "invalid device: " + csDevice);
                    }

                    RUBY.Send(rbKeys, "freeze");
                    return rbKeys;
                });

            RUBY.rb_define_singleton_method(mInput, "mouse_location",
                delegate(VALUE self)
                {
                    Point csMouseLocation = this.GameEnvironment.Input.MouseLocation;
                    VALUE rbMouseLocation = RUBY.rb_ary_new();
                    RUBY.rb_ary_push(rbMouseLocation, RUBY.INT2NUM(csMouseLocation.X));
                    RUBY.rb_ary_push(rbMouseLocation, RUBY.INT2NUM(csMouseLocation.Y));
                    return rbMouseLocation;
                });
        }
    }
}
