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

namespace StarEngine.Ruby
{
    internal static class ColorClass
    {
        public static Color ToCSharpColor(VALUE rbColor)
        {
            byte csRed = (byte)RUBY.NUM2INT(RUBY.Send(rbColor, "red"));
            byte csGreen = (byte)RUBY.NUM2INT(RUBY.Send(rbColor, "green"));
            byte csBlue = (byte)RUBY.NUM2INT(RUBY.Send(rbColor, "blue"));
            byte csAlpha = (byte)RUBY.NUM2INT(RUBY.Send(rbColor, "alpha"));
            return Color.FromArgb(csAlpha, csRed, csGreen, csBlue);
        }

        public static VALUE ToRubyColor(Color csColor)
        {
            VALUE rbRed = RUBY.INT2NUM(csColor.R);
            VALUE rbGreen = RUBY.INT2NUM(csColor.G);
            VALUE rbBlue = RUBY.INT2NUM(csColor.B);
            VALUE rbAlpha = RUBY.INT2NUM(csColor.A);
            return RUBY.Send(SERubyConsts.ForName("Color"), "new", rbRed, rbGreen, rbBlue, rbAlpha);
        }
    }

    internal static class ToneClass
    {
        public static Tone ToCSharpTone(VALUE rbTone)
        {
            int csRed = RUBY.NUM2INT(RUBY.Send(rbTone, "red"));
            int csGreen = RUBY.NUM2INT(RUBY.Send(rbTone, "green"));
            int csBlue = RUBY.NUM2INT(RUBY.Send(rbTone, "blue"));
            byte csSaturation = (byte)RUBY.NUM2INT(RUBY.Send(rbTone, "saturation"));
            return new Tone(csRed, csGreen, csBlue, csSaturation);
        }

        public static VALUE ToRubyTone(Tone csTone)
        {
            VALUE rbRed = RUBY.INT2NUM(csTone.Red);
            VALUE rbGreen = RUBY.INT2NUM(csTone.Green);
            VALUE rbBlue = RUBY.INT2NUM(csTone.Blue);
            VALUE rbSaturation = RUBY.INT2NUM(csTone.Saturation);
            return RUBY.Send(SERubyConsts.ForName("Tone"), "new", rbRed, rbGreen, rbBlue, rbSaturation);
        }
    }

    internal static class BlendTypeEnum
    {
        public static BlendType ToCSharpBlendType(VALUE rbBlendType)
        {
            if (rbBlendType == RUBY.Intern("alpha"))
                return BlendType.Alpha;
            else if (rbBlendType == RUBY.Intern("add"))
                return BlendType.Addition;
            else if (rbBlendType == RUBY.Intern("sub"))
                return BlendType.Subtraction;
            else
                RUBY.rb_raise(SERubyConsts.ForName("::ArgumentError"), "invalid blend type");
            return BlendType.Alpha;
        }

        public static VALUE ToRubyBlendType(BlendType csBlendType)
        {
            switch(csBlendType)
            {
            case BlendType.Alpha:
                return RUBY.Intern("alpha");
            case BlendType.Addition:
                return RUBY.Intern("add");
            case BlendType.Subtraction:
                return RUBY.Intern("sub");
            default:
                RUBY.rb_raise(SERubyConsts.ForName("::ArgumentError"), "invalid blend type");
                return RUBY.Qnil;
            }
        }
    }
}
