package main

import (
	"encoding/base64"
	"fmt"
	"net/url"
	"strings"
)

type History struct {
	urlList []string
	ptr     int
}

var ClientHistory = History{make([]string, 0, 10), -1}

func (h *History) Add(u string) {
	if h.ptr > -1 && len(h.urlList) > 0 {
		h.urlList = h.urlList[:h.ptr+1]
	} else {
		h.urlList = make([]string, 0, 10)
	}
	h.urlList = append(h.urlList, u)
	h.ptr++
}

func (h *History) Back() (string, error) {
	if h.ptr > 0 {
		h.ptr--
		return h.urlList[h.ptr], nil
	}
	return "", fmt.Errorf("Unable to go back")
}

func (h *History) Forward() (string, error) {
	if h.ptr < len(h.urlList) - 1 && len(h.urlList) > 0 {
		h.ptr++
		return h.urlList[h.ptr], nil
	}
	return "", fmt.Errorf("Unable to go back")
}


func MakeImage(data, mime string) string {
	var out strings.Builder
	out.WriteString("<img src=\"data:")
	out.WriteString(mime)
	out.WriteString(";base64,")
	out.WriteString(base64.StdEncoding.EncodeToString([]byte(data)))
	out.WriteString("\" alt=\"\">")
	return out.String()
}

func RenderSearchForm(queryText string, u *url.URL) (string, error) {
	out := `
		<form id="search" action="%s">
			<label for="QueryResponse">%s</label>
			<input type="text" name="Query Response" id="QueryResponse" />
			<input type="submit" name="s" value="Submit" />
		</form>
	`
	action := u.String()
	if u.Scheme == "gopher" {
		action = strings.Replace(action, "/7", "/1", 1)
	}
	return fmt.Sprintf(out, action, queryText), nil
}

func NavigateTo(addr string) (string, error) {
	redirectCount = 0
	if strings.Index(addr, " ") > -1 || strings.Index(addr, "://") < 0 {
		addr = fmt.Sprintf(settings.SearchURL, url.PathEscape(addr))
	}

	u, err := url.Parse(addr)
	if err != nil {
		return ConvertErrorToHTML(97, "Error encoding URL"), nil
	}

	if u.Scheme == "" {
		u.Scheme = "gemini"
	}

	u.Scheme = strings.ToLower(u.Scheme)

	switch u.Scheme {
	case "gemini":
		if u.Port() == "" {
			u.Host = u.Host + ":1965"
		}
		return GetGemini(u)
	case "http", "https":
		if u.Port() == "" && u.Scheme == "http" {
			u.Host = u.Host + ":80"
		} else if u.Port() == "" && u.Scheme == "https" {
			u.Host = u.Host + ":443"
		}
		if !settings.OpenWebLinks {
			return WebDisabled, nil
		}
		err := appCtrl.OpenHTTP(u.String())
		if err != nil {
			return "", fmt.Errorf("Unable to open URL in system web browser")
		}
		return "", fmt.Errorf("Opened URL in system web browser")
	case "gopher":
		if u.Port() == "" {
			u.Host = u.Host + ":70"
		}
		if !settings.OpenGopherLinks {
			return GopherDisabled, nil
		}
		return RetrieveGopher(u)
	case "file":
		// handle things
		return  "Stuff and things", nil
	case "goldberry":
		return RouteGoldberry(u)
	}
	return WTFError, nil
}
