package main

import (
	"fmt"
	"html/template"
	"strconv"
)

type ScientificNotationValue float64

func (s *ScientificNotationValue) UnmarshalText(text []byte) error {
	f, err := strconv.ParseFloat(string(text), 64)
	if err != nil {
		return err
	}
	*s = ScientificNotationValue(f)
	return nil
}

// formatMbarHTML formats a millibar value using scientific notation and returns
// a HTML fragment (for superscript support).
func formatMbarHTML(v float32) template.HTML {
	exp := 0
	for v < 1 {
		v *= 10
		exp -= 1
	}
	for v >= 10 {
		v /= 10
		exp += 1
	}
	res := fmt.Sprintf("%.3f", v)
	res += fmt.Sprintf(" x 10<sup>%d</sup>", exp)
	res += " mbar"
	return template.HTML(res)
}

func formatMbar(v float32) string {
	exp := 0
	for v < 1 {
		v *= 10
		exp -= 1
	}
	for v >= 10 {
		v /= 10
		exp += 1
	}
	res := fmt.Sprintf("%.3f", v)
	res += fmt.Sprintf("e%d", exp)
	return res
}

func (s *ScientificNotationValue) MarshalText() ([]byte, error) {
	v := float32(*s)
	res := formatMbar(v)
	return []byte(res), nil
}
