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

namespace StarEngine.Ruby
{
    public partial class RubyInterpreter
    {
        private void InitializeAudioModule()
        {
            VALUE mAudio = SERubyConsts.ForName("Audio");

            RUBY.rb_define_singleton_method(mAudio, "__cs_play_bgm__",
                delegate(VALUE self, VALUE rbPath, VALUE rbTime, VALUE rbVolume, VALUE rbLoop)
                {
                    string csPath = RUBY.StringValuePtr(rbPath);
                    csPath = PathExtensions.GetFullPathAndExtension(csPath);
                    int csVolumeInt = (rbVolume == RUBY.Qnil) ? 255 : RUBY.NUM2INT(rbVolume);
                    int csTime = (rbTime == RUBY.Qnil) ? 0 : RUBY.NUM2INT(rbTime);
                    byte csVolume = (byte)Math.Max(0, Math.Min(255, csVolumeInt));
                    bool csLoop = (rbLoop == RUBY.Qnil) ? true : RUBY.ToBool(rbLoop);

                    try
                    {
                        this.GameEnvironment.Audio.PlayBgm(csPath, csTime, csVolume, csLoop);
                    }
                    catch (FileNotFoundException e)
                    {
                        RUBY.rb_raise(SERubyConsts.ForName("::Errno::ENOENT"), e.FileName);
                    }
                    catch (StarEngineException e)
                    {
                        RUBY.rb_raise(SERubyConsts.ForName("StarEngineError"), e.Message);
                    }
                    return RUBY.Qnil;
                });

            RUBY.rb_define_singleton_method(mAudio, "__cs_stop_bgm__",
                delegate(VALUE self, VALUE rbTime)
                {
                    int csTime = (rbTime == RUBY.Qnil) ? 0 : RUBY.NUM2INT(rbTime);
                    this.GameEnvironment.Audio.StopBgm(csTime);
                    return RUBY.Qnil;
                });

            RUBY.rb_define_singleton_method(mAudio, "playing_bgm?",
                delegate(VALUE self)
                {
                    return this.GameEnvironment.Audio.IsPlayingBgm ? RUBY.Qtrue : RUBY.Qfalse;
                });

            RUBY.rb_define_singleton_method(mAudio, "bgm_volume",
                delegate(VALUE self)
                {
                    return RUBY.INT2NUM(this.GameEnvironment.Audio.BgmVolume);
                });

            RUBY.rb_define_singleton_method(mAudio, "bgm_volume=",
                delegate(VALUE self, VALUE rbBgmVolume)
                {
                    IAudio audio = this.GameEnvironment.Audio;
                    audio.BgmVolume = (byte)Math.Min(Math.Max(RUBY.NUM2INT(rbBgmVolume), 0), 255);
                    return rbBgmVolume;
                });

            RUBY.rb_define_singleton_method(mAudio, "__cs_play_se__",
                delegate(VALUE self, VALUE rbPath, VALUE rbTime, VALUE rbVolume, VALUE rbPanning)
                {
                    string csPath = RUBY.StringValuePtr(rbPath);
                    csPath = PathExtensions.GetFullPathAndExtension(csPath);
                    int csVolumeInt = (rbVolume == RUBY.Qnil) ? 255 : RUBY.NUM2INT(rbVolume);
                    byte csVolume = (byte)Math.Max(0, Math.Min(255, csVolumeInt));
                    int csTime = (rbTime == RUBY.Qnil) ? 0 : RUBY.NUM2INT(rbTime);
                    int csPanningInt = (rbVolume == RUBY.Qnil) ? 128 : RUBY.NUM2INT(rbPanning);
                    byte csPanning = (byte)Math.Max(0, Math.Min(255, csPanningInt));

                    try
                    {
                        this.GameEnvironment.Audio.PlaySE(csPath, csTime, csVolume, csPanning);
                    }
                    catch (FileNotFoundException e)
                    {
                        RUBY.rb_raise(SERubyConsts.ForName("::Errno::ENOENT"), e.FileName);
                    }
                    catch (StarEngineException e)
                    {
                        RUBY.rb_raise(SERubyConsts.ForName("StarEngineError"), e.Message);
                    }
                    return RUBY.Qnil;
                });

            RUBY.rb_define_singleton_method(mAudio, "__cs_stop_all_ses__",
                delegate(VALUE self, VALUE rbTime)
                {
                    int csTime = (rbTime == RUBY.Qnil) ? 0 : RUBY.NUM2INT(rbTime);
                    this.GameEnvironment.Audio.StopAllSEs(csTime);
                    return RUBY.Qnil;
                });
        }
    }
}
