package opentype

import (
	
	
)

// Table is one opentype binary table and its tag.
type Table struct {
	Content []byte
	Tag     Tag
}

// WriteTTF creates a single Truetype font file (.ttf) from the given [tables] slice,
// which must be sorted by Tag
func ( []Table) []byte {
	 := uint32(otfHeaderSize + len()*otfEntrySize)
	 := make([]byte, )

	writeTTFHeader(len(), )

	 :=  // the actual content will start after the header + table directory
	for ,  := range  {
		 := checksum(.Content)
		 := uint32(len(.Content))

		 := [otfHeaderSize+*otfEntrySize:]
		binary.BigEndian.PutUint32(, uint32(.Tag))
		binary.BigEndian.PutUint32([4:], )
		binary.BigEndian.PutUint32([8:], )
		binary.BigEndian.PutUint32([12:], )

		// update the offset
		 =  + 
	}

	// append the actual table content :
	// allocate only once
	 = append(, make([]byte, -)...)
	 = 
	for ,  := range  {
		copy([:], .Content)
		 =  + uint32(len(.Content))
	}

	return 
}

// out is assumed to have a length >= ttfHeaderSize
func writeTTFHeader( int,  []byte) {
	 := math.Floor(math.Log2(float64()))
	// Maximum power of 2 less than or equal to numTables, times 16 ((2**floor(log2(numTables))) * 16, where “**” is an exponentiation operator).
	 := math.Pow(2, ) * 16
	// Log2 of the maximum power of 2 less than or equal to numTables (log2(searchRange/16), which is equal to floor(log2(numTables))).
	 := 
	// numTables times 16, minus searchRange ((numTables * 16) - searchRange).
	 := *16 - int()

	binary.BigEndian.PutUint32([:], uint32(TrueType))
	binary.BigEndian.PutUint16([4:], uint16())
	binary.BigEndian.PutUint16([6:], uint16())
	binary.BigEndian.PutUint16([8:], uint16())
	binary.BigEndian.PutUint16([10:], uint16())
}

func checksum( []byte) uint32 {
	// "To accommodate data with a length that is not a multiple of four,
	// the above algorithm must be modified to treat the data as though
	// it contains zero padding to a length that is a multiple of four."
	if  := len() % 4;  != 0 {
		 = append(, make([]byte, )...)
	}

	var  uint32
	for  := 0;  < len()/4; ++ {
		 += binary.BigEndian.Uint32([*4:])
	}

	return 
}