package gstreamer

import (
	"fmt"
	"github.com/rs/zerolog"
	"github.com/tinyzimmer/go-gst/gst"
	"strconv"
	"strings"
	"time"
)

func (o *TextOverlay) create(log zerolog.Logger) (*gst.Element, error) {

	e, err := gst.NewElementWithName("textoverlay", o.Name)
	if err != nil {
		log.Error().Msgf("could not create element %s: %v\n", o.Name, err)
		return nil, fmt.Errorf("could not create element %s", o.Name)
	}
	setPropertyWrapper(e, "draw-outline", false)
	setPropertyWrapper(e, "draw-shadow", false)
	setPropertyWrapper(e, "halignment", "0") //left
	setPropertyWrapper(e, "valignment", "2") //top
	setPropertyWrapper(e, "deltax", o.X)
	setPropertyWrapper(e, "deltay", o.Y)
	setPropertyWrapper(e, "color", o.Color)
	setPropertyWrapper(e, "font-desc", fmt.Sprintf("%s, %s %v", o.Font, o.FontWeight, o.FontSize))

	setPropertyWrapper(e, "text", o.Value)

	if o.Display {
		o.show()
	} else {
		o.hide()
	}
	o.element = e

	return e, nil
}

func (o *TextOverlay) update(log zerolog.Logger) {
	text, _ := o.element.GetProperty("text")
	if text != o.Value {
		setPropertyWrapper(o.element, "text", o.Value)
		setPropertyWrapper(o.element, "font-desc", fmt.Sprintf("Fira Sans, %s %v", o.FontWeight, o.FontSize))
	}
	setPropertyWrapper(o.element, "deltax", o.X)
	setPropertyWrapper(o.element, "deltay", o.Y)
	if o.Display {
		o.show()
	} else {
		o.hide()
	}
	o.resizeTextOverlay(log)
}

func (o *TextOverlay) show() gst.ClockCallback {
	return func(clock *gst.Clock, clockTime time.Duration) bool {
		setPropertyWrapper(o.element, "silent", 0)
		return true
	}
}

func (o *TextOverlay) hide() gst.ClockCallback {
	return func(clock *gst.Clock, clockTime time.Duration) bool {
		setPropertyWrapper(o.element, "silent", 1)
		return true
	}
}

func (o *TextOverlay) getName() string {
	return o.Name
}

func (o *TextOverlay) resizeTextOverlay(log zerolog.Logger) {
	if o.MaxWidth == 0 {
		return
	}
	width, _ := o.element.GetProperty("text-width")

	for width.(uint) >= o.MaxWidth {
		log.Debug().Str("name", o.Name).Uint("width", width.(uint)).Uint("max-width", o.MaxWidth).Msg("Shrinking Textoverlay")
		fontdesc, _ := o.element.GetProperty("font-desc")
		fd := strings.Fields(fontdesc.(string))
		fontsize, _ := strconv.Atoi(fd[len(fd)-1])
		setPropertyWrapper(o.element, "font-desc", fmt.Sprintf("%s, %s %v", o.Font, o.FontWeight, fontsize-1))
		time.Sleep(time.Millisecond * 60)
		width, _ = o.element.GetProperty("text-width")
	}
}

func (o TextOverlay) getBlendInTime() time.Duration {
	return o.BlendIn
}

func (o TextOverlay) getBlendOutTime() time.Duration {
	return o.BlendOut
}

func (o *TextOverlay) getElement() *gst.Element {
	return o.element
}

func (o *TextOverlay) setElement(element *gst.Element) {
	o.element = element
}

func (o *TextOverlay) getType() string {
	return "textoverlay"
}