// vim: shiftwidth=4 tabstop=4 noexpandtab

package main

import (
	"io/ioutil"
	"log"
	"encoding/binary"
	"math"
)

type BinaryStl struct {
	header []byte
	numberOfTriangles uint32
	surface Surface
}

func ReadBinaryStlFile(filePath string) (BinaryStl, error) {

	fileContent, err := ioutil.ReadFile(filePath)
	if err != nil {
		return BinaryStl{}, err
	}

	model := BinaryStl{}
	model.surface = Surface{}

	model.header = fileContent[0:80]
	log.Printf("STL header: '%s'\n", string(model.header))

	model.numberOfTriangles = binary.LittleEndian.Uint32(fileContent[80:84])
	log.Printf("STL model has %d triangles\n", model.numberOfTriangles)

	var i uint32
	for i = 0; i < model.numberOfTriangles; i++ {  // for each expected triangle
		start := 84 + i*50  // 50 bytes is length of one triangle
		end := 84 + (i+1)*50
		model.surface.triangles = append(model.surface.triangles,
			ParseBinaryStlTriangle(fileContent[start:end]))
	}

	return model,nil
}

func ParseBinaryStlTriangle(data []byte) *Triangle {  // FIXME: This function should only accept 50 byte slices/arrays

	triangle := new(Triangle)
	triangle.a = new(Point)
	triangle.b = new(Point)
	triangle.c = new(Point)

	triangle.a.x = math.Float32frombits(binary.LittleEndian.Uint32(data[12:16]))
	triangle.a.y = math.Float32frombits(binary.LittleEndian.Uint32(data[16:20]))
	triangle.a.z = math.Float32frombits(binary.LittleEndian.Uint32(data[20:24]))

	triangle.b.x = math.Float32frombits(binary.LittleEndian.Uint32(data[24:28]))
	triangle.b.y = math.Float32frombits(binary.LittleEndian.Uint32(data[28:32]))
	triangle.b.z = math.Float32frombits(binary.LittleEndian.Uint32(data[32:36]))

	triangle.c.x = math.Float32frombits(binary.LittleEndian.Uint32(data[36:40]))
	triangle.c.y = math.Float32frombits(binary.LittleEndian.Uint32(data[40:44]))
	triangle.c.z = math.Float32frombits(binary.LittleEndian.Uint32(data[44:48]))

	return triangle
}