package nmslib

import (
	"errors"
	"fmt"
	"image"
	"io/ioutil"
	"strconv"

	"github.com/fogleman/gg"
)

/*CreateBanner - Output PNG of Portal Glyphs
Requires 3 vars and returns 1 err, Outputs a PNG file
var portalex string: Portal Glyph hex string
var savename string: Output name of PNG file
var opt int
	00 sets horizontal banner in light mode [ 00 || 0 ]
	01 sets horizontal banner in dark mode  [ 01 || 1 ]
	10 sets vertical banner in light mode
	11 sets vertical banner in dark mode

	* note first of the 2 bits sets the layout, the second bit sets the glyph color
*/
func CreateBanner(portalhex string, savename string, opt int) (err error) {
	out, err := GenRawBanner(portalhex, opt)
	if err != nil {
		return
	}
	gg.SavePNG(savename+".png", out)
	//gg.SaveJPG(savename+".jpg", out, 50)
	return
}

/*GenRawBanner - Returns image.Image of genorated image
Requires 2 vars and returns image.Image (raw image data) and an error
var portalex string: Portal Glyph hex string
var opt int
	00 sets horizontal banner in light mode [ 00 || 0 ]
	01 sets horizontal banner in dark mode  [ 01 || 1 ]
	10 sets vertical banner in light mode
	11 sets vertical banner in dark mode

	* note first of the 2 bits sets the layout, the second bit sets the glyph color
*/
func GenRawBanner(portalhex string, layout int) (portalbanner image.Image, err error) {
	var GlyphHex [12]int64
	var glyphImg [12]string
	var mode string
	var imgArray [12]image.Image

	//Set light or dark mode glyphs
	if layout == 00 || layout == 10 {
		mode = "light"
	} else if layout == 01 || layout == 11 {
		mode = "dark"
	} else {
		// if layout is an invalid option (ie. not a 2 bit binary number default to classic mode/layout
		layout = 0
		mode = "light"
	}

	// verify len of portalhex
	if len(portalhex) == 12 {
		// get hex value from each digit in given string and add it to an array of int64
		for i := 0; i < len(portalhex); i++ {
			GlyphHex[i], err = strconv.ParseInt(portalhex[i:int(i+1)], 16, 16)
			if err != nil {
				return nil, errors.New("string provided is not hexadecimal ([0-9][A-F])")
			}
		}

		// assign image location of its glyph-hex value to an array of strings
		for j := 0; j < len(glyphImg); j++ {
			glyphImg[j] = fmt.Sprintf("assets/glyphs/%s/PORTALSYMBOL.%X.png", mode, GlyphHex[j])
		}

		// pull images need from assets.go and saved them to the temp directory
		for k := 0; k < len(glyphImg); k++ {
			data, err := Asset(glyphImg[k])
			if err != nil {
				return nil, errors.New("can not load images from assets: " + glyphImg[k])
			}
			err = ioutil.WriteFile(NmsTemp+"/"+glyphImg[k], []byte(data), 0644)
			if err != nil {
				return nil, errors.New("can not write file to temp directory")
			}
		}

		//Load/open images needed
		for iter := 0; iter < 12; iter++ {
			imgArray[iter], err = gg.LoadPNG(NmsTemp + "/" + glyphImg[iter])
			if err != nil {
				return nil, errors.New("can not read glyph " + glyphImg[iter])
			}
		}

		//begin concatenating images
		// get image size of first glyph, all glyphs have the same X && Y dimension so we only need to measure one.
		imgDim := imgArray[0].Bounds().Size()

		//Set Layout
		//classic horizontal layout
		if layout == 01 || layout == 00 {
			imgWidth := imgDim.X * 12
			imgHeight := imgDim.Y
			concat := gg.NewContext(imgWidth, imgHeight)
			for a := 0; a < 12; a++ {
				concat.DrawImage(imgArray[a], imgDim.X*a, 0)
			}
			return concat.Image(), nil
		}

		//Vertical layout
		if layout == 10 || layout == 11 {
			imgWidth := imgDim.X
			imgHeight := imgDim.Y * 12
			concat := gg.NewContext(imgWidth, imgHeight)
			for a := 0; a < 12; a++ {
				concat.DrawImage(imgArray[a], 0, imgDim.Y*a)
			}
			return concat.Image(), nil
		}
	} else {
		return nil, errors.New("portalcode must be exactly 12 chars")
	}
	return
}
