//>>> _using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpDX;
using SharpDX.Direct3D11;
using SharpDX.Windows;
//<<< _using

using Framefield.Core;
using System.IO;
using Un4seen.Bass;


namespace Framefield.Core.IDc5e20b30_2386_400a_b049_c09d2889fb09
{
    public class Class_PlaySound : OperatorPart.Function, Framefield.Core.OperatorPartTraits.ITimeAccessor
    {
        //>>> _inputids
        private enum InputId
        {
            FilePath = 0,
            PlayTrigger = 1,
            Volume = 2,
            Loop = 3,
            StopTrigger = 4
        }
        //<<< _inputids 

        public override void Dispose()
        {
            StopPlaying();
        }

        public override OperatorPartContext Eval(OperatorPartContext context, List<OperatorPart> inputs, int outputIdx)
        {
            //>>> _params
            var FilePath = inputs[(int)InputId.FilePath].Eval(context).Text;
            var PlayTrigger = inputs[(int)InputId.PlayTrigger].Eval(context).Value;
            var Volume = inputs[(int)InputId.Volume].Eval(context).Value;
            var Loop = inputs[(int)InputId.Loop].Eval(context).Value;
            var StopTrigger = inputs[(int)InputId.StopTrigger].Eval(context).Value;
            //<<< _params

            if (!IsSoundInitialized())
                return context;

            if ((File.Exists(FilePath) && _fileName != FilePath) ||
                (File.Exists(_fileName) && _lastLoop != Loop))
            {
                StopPlaying();

                _fileName = FilePath;
                _stream = Bass.BASS_StreamCreateFile(_fileName, 0, 0, BASSFlag.BASS_STREAM_PRESCAN | (Loop > 0.5 ? BASSFlag.BASS_MUSIC_LOOP : 0));
                _lastLoop = Loop;
                Logger.Debug(this, "opened sound: {0}", _fileName);
            }

            if (_stream == 0)
            {
                context.Value = -1.0f;
                return context;
            }

            bool playTriggerFlankUp = _lastPlayTrigger < 0.5 && PlayTrigger > 0.5;
            _lastPlayTrigger = PlayTrigger;
            if (playTriggerFlankUp && !IsPlaying())
            {
                Bass.BASS_ChannelPlay(_stream, false);
                _lastVolume = -9999999.0f;
            }

            bool stopTriggerFlankUp = _lastStopTrigger < 0.5 && StopTrigger > 0.5;
            _lastStopTrigger = StopTrigger;
            if (stopTriggerFlankUp)
            {
                StopPlaying();
            }

            if (_lastVolume != Volume)
            {
                Bass.BASS_ChannelSetAttribute(_stream, BASSAttribute.BASS_ATTRIB_VOL, Volume);
                _lastVolume = Volume;
            }

            context.Value = (float)Bass.BASS_ChannelBytes2Seconds(_stream, Bass.BASS_ChannelGetPosition(_stream, BASSMode.BASS_POS_BYTES));
            return context;
        }
        
        private void StopPlaying()
        {
            if (_stream != 0)
            {
                Bass.BASS_ChannelPause(_stream);
                Bass.BASS_ChannelStop(_stream);
                Bass.BASS_StreamFree(_stream);
                _stream = 0;
                Logger.Debug(this,"closed sound: {0}", _fileName);
            }
            _lastPlayTrigger = -9999999.0f;
            _lastStopTrigger = -9999999.0f;
            _lastVolume = -9999999.0f;
        }

        private bool IsSoundInitialized()
        {
            return Bass.BASS_GetInfo() != null;
        }
        
        private bool IsPlaying()
        {
            return Bass.BASS_ChannelIsActive(_stream) == Un4seen.Bass.BASSActive.BASS_ACTIVE_PLAYING;
        }

        string _fileName;
        int _stream;
        float _lastPlayTrigger;
        float _lastStopTrigger;
        float _lastVolume;
        float _lastLoop;
    }
}

