package dotweb

import (
	"github.com/devfeel/dotweb/framework/file"
	"html/template"
	"io"
	"path"
)

// Renderer is the interface that wraps the render method.
type Renderer interface {
	SetTemplatePath(path string)
	Render(io.Writer, interface{}, Context, ...string) error
}

type innerRenderer struct {
	templatePath string
}

// Render render view use http/template
func (r *innerRenderer) Render(w io.Writer, data interface{}, ctx Context, tpl ...string) error {
	t, err := r.parseFiles(tpl...)
	if err != nil {
		return err
	}
	return t.Execute(w, data)
}

// SetTemplatePath set default template path
func (r *innerRenderer) SetTemplatePath(path string) {
	r.templatePath = path
}

// 定义函数unescaped
func unescaped(x string) interface{} { return template.HTML(x) }

// return http/template by gived file name
func (r *innerRenderer) parseFiles(fileNames ...string) (*template.Template, error) {
	var realFileNames []string
	for _, v := range fileNames {
		if !file.Exist(v) {
			v = path.Join(r.templatePath, v)
		}
		realFileNames = append(realFileNames, v)
	}
	t, err := template.ParseFiles(realFileNames...)
	if err != nil {
		return nil, err
	}
	t = registeTemplateFunc(t)
	return t, nil
}

// registeTemplateFunc registe default support funcs
func registeTemplateFunc(t *template.Template) *template.Template {
	return t.Funcs(template.FuncMap{"unescaped": unescaped})
	//TODO:add more func
}

// NewInnerRenderer create a inner renderer instance
func NewInnerRenderer() *innerRenderer {
	r := new(innerRenderer)
	return r
}
