package goPress

import (
	"github.com/hoisie/web"
	"io"
	"io/ioutil"
	"log"
	"math/big"
	"os"
	"path/filepath"
)

//
// Function:          ImagesLoad
//
// Description:       This function is called to upload an image for the
//                    images directory.
//
// Inputs:
//                    val        Name of the image with relative path
//
func ImagesLoad(ctx *web.Context, val string) {
	LoadImage(ctx, SiteData.Sitebase+"images/"+val)
}

//
// Function:		 LoadThemeImage
//
// Description:		 This function loads images from the theme's directory.
//
// Inputs
//					 image        Name of the image file to load
//
func LoadThemeImage(ctx *web.Context, image string) {
	LoadImage(ctx, SiteData.stylingBase+SiteData.CurrentStyling+"/images/"+image)
}

//
// Function:          LoadImage
//
// Description:       This function does the work of loading an image file and passing it on.
//                    TODO: Needs finished.
//
// Inputs:
//
func LoadImage(ctx *web.Context, val string) {
	//
	// Get the file extension.
	//
	fileExt := filepath.Ext(val)

	//
	// Set the http header based on the file type.
	//
	SetStandardHeader(ctx)
	ctx.ContentType(fileExt)
	if fileExt == ".svg" {
		//
		// This is a text based file. Read it and send to the browser.
		//
		wfile, err := os.Open(val)
		if err == nil {
			bcontents, _ := ioutil.ReadAll(wfile)
			wfile.Close()
			ctx.WriteString(string(bcontents))
		}
	} else {
		//
		// This is a binary based file. Read it and sent the contents to the browser.
		//
		fi, err := os.Open(val)

		//
		// Set the size of the binary coming down the pipe. Chrome has to have this value
		// one larger than real.
		//
		finfo, _ := os.Stat(val)
		i := big.NewInt(finfo.Size())
		ctx.SetHeader("Accept-Ranges", "bytes", true)
		ctx.SetHeader("Content-Length", i.String(), true)

		if err != nil {
			log.Println(err)
			return
		}
		defer fi.Close()

		//
		// Create a buffer to contain the image data. Binary images usually get
		// very big.
		//
		buf := make([]byte, 1024)

		//
		// Go through the binary file 1K at a time and send to the browser.
		//
		for {
			//
			// Read a buffer full.
			//
			n, err := fi.Read(buf)
			if err != nil && err != io.EOF {
				log.Println(err)
				break
			}

			//
			// If nothing was read, then exit.
			//
			if n == 0 {
				break
			}

			//
			// Write the binary buffer to the browser.
			//
			n2, err := ctx.Write(buf[:n])
			if err != nil {
				log.Println(err)
				break
			} else if n2 != n {
				log.Println("Error in sending " + val + " to the browser. Amount read does not equal the amount sent.")
				break
			}
		}
	}
}
