package indicatorv2

import (
	"github.com/c9s/bbgo/pkg/types"
)

const MaxNumOfRMA = 1000

type RMAStream struct {
	// embedded structs
	*types.Float64Series

	// config fields
	Adjust bool

	window        int
	counter       int
	sum, previous float64
}

func RMA2(source types.Float64Source, window int, adjust bool) *RMAStream {
	checkWindow(window)

	s := &RMAStream{
		Float64Series: types.NewFloat64Series(),
		window:        window,
		Adjust:        adjust,
	}

	s.Bind(source, s)
	return s
}

func (s *RMAStream) Calculate(x float64) float64 {
	lambda := 1 / float64(s.window)
	if s.counter == 0 {
		s.sum = 1
		s.previous = x
	} else {
		if s.Adjust {
			s.sum = s.sum*(1-lambda) + 1
			s.previous = s.previous + (x-s.previous)/s.sum
		} else {
			s.previous = s.previous*(1-lambda) + x*lambda
		}
	}
	s.counter++

	return s.previous
}

func (s *RMAStream) Truncate() {
	s.Slice = types.ShrinkSlice(s.Slice, MaxSliceSize, TruncateSize)
}

func checkWindow(window int) {
	if window == 0 {
		panic("window can not be zero")
	}
}
