package main

import (
	"fmt"
	"github.com/golang/freetype/truetype"
	"golang.org/x/image/font"
	"image/color"
	_ "image/jpeg"
	"io/ioutil"
	"log"
	"strings"
	"time"
	"github.com/hajimehoshi/ebiten"
	"github.com/hajimehoshi/ebiten/audio"
	"github.com/hajimehoshi/ebiten/audio/mp3"
	"github.com/hajimehoshi/ebiten/ebitenutil"
	"github.com/hajimehoshi/ebiten/text"
)

const (
	screenWidth  = 640
	screenHeight = 480
	sampleRate   = 44100
)

type dialogue struct {
	Speaker character
	Text    string
}

type character struct {
	Name  string
	Color color.RGBA
}

func check(err error) {
    if err != nil {
        log.Fatal(err)
    }
}

var (
	m        = character{`Me`, color.RGBA{200, 200, 255, 255}}
	s        = character{`Sylvie`, color.RGBA{200, 255, 200, 255}}
	d        = character{``, color.RGBA{0, 255, 0, 0}}
	messages = []dialogue{
		{d, `playSong ../../resources/Hisoku.mp3`},
		{s, `Hi there! How was class?`},
		{m, `Good...`},
		{d, "I can't bring myself to admit that it all\n went in one ear and out the other."},
		{s, `Are you going home now? Wanna walk back with me?`},
		{d, `playSong ../../resources/Departures.mp3`},
		{m, `Sure!`},
	}
	mplusNormalFont font.Face
	line            = 0
	bg              *ebiten.Image
	audioContext    *audio.Context
	audioPlayer     *audio.Player
	songSize		int64
	playingMusic    = false
	songDuration 	time.Duration
)

func playSong(path string) {
	var err error
	if playingMusic {
		audioPlayer.Close()
	}
	f, err := ebitenutil.OpenFile(path)
	check(err)
	d, err := mp3.Decode(audioContext, f)
	check(err)
	audioPlayer, err = audio.NewPlayer(audioContext, d)
	check(err)
	songSize = d.Size()
	audioPlayer.Play()
	playingMusic = true
	songDuration = time.Second * time.Duration(songSize) / 4 / sampleRate
}

func init() {

	f, err := ebitenutil.OpenFile("../../resources/mplus-1p-regular.ttf")
	check(err)
	defer f.Close()

	b, err := ioutil.ReadAll(f)
	check(err)

	tt, err := truetype.Parse(b)
	check(err)
	const dpi = 72
	mplusNormalFont = truetype.NewFace(tt, &truetype.Options{
		Size:    24,
		DPI:     dpi,
		Hinting: font.HintingFull,
	})
	audioContext, err = audio.NewContext(sampleRate)
	check(err)
}

func update(screen *ebiten.Image) error {

	if ebiten.IsRunningSlowly() {
		return nil
	}
	action := strings.Split(messages[line].Text, " ")
	for _, v := range ebiten.InputChars() {
		if v == 32 {
			if line+1 != len(messages) {
				line++
			}
		}
	}
	action = strings.Split(messages[line].Text, " ")
	if action[0] == "playSong" {
		if line+1 != len(messages) {
			playSong(action[1])
			line++
		}
	}

	if playingMusic {
		if int(audioPlayer.Current().Seconds()) == int(songDuration.Seconds()) {
			audioPlayer.Seek(0)
		}
	}


	msg := fmt.Sprintf("FPS: %0.2f", ebiten.CurrentFPS())
	const x = 20

	op := &ebiten.DrawImageOptions{}

	screen.DrawImage(bg, op)

	ebitenutil.DrawRect(screen, 30, 350, screenWidth-60, 100, color.RGBA{128, 128, 128, 200})

	text.Draw(screen, msg, mplusNormalFont, x, 40, color.White)
	text.Draw(screen, messages[line].Speaker.Name, mplusNormalFont, 50, 370, messages[line].Speaker.Color)
	text.Draw(screen, messages[line].Text, mplusNormalFont, 50, 400, color.White)
	return nil
}

func main() {
	var err error
	bg, _, err = ebitenutil.NewImageFromFile("../../resources/bg.jpg", ebiten.FilterNearest)
	check(err)
	if err := ebiten.Run(update, screenWidth, screenHeight, 1, "Visual novel (Testing ebiten)"); err != nil {
		log.Fatal(err)
	}
}
