package main

import (
	"fmt"
	"math"
	"os"
	"strings"

	svg "github.com/ajstarks/svgo"
)

func main() {
	if err := doMain(); err != nil {
		panic(err)
	}
}

func doMain() error {
	f, err := os.OpenFile("release.svg", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
	if err != nil {
		return err
	}
	defer f.Close()
	canvas := svg.New(f)
	canvas.Start(600, 400)
	canvas.Translate(300, 200)
	for i, month := range strings.Split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec", " ") {
		angle := func(midx int) float64 {
			return (float64(midx) - 3) * 2 * math.Pi / 12
		}
		begin, end := angle(i), angle(i+1)

		// Draw a single black wedge of the calendar.
		path := fmt.Sprintf("M 0,0 L %v,%v A 100,100 0 0 0 %v,%v L 0 0",
			100*math.Sin(begin), 100*math.Cos(begin), 100*math.Sin(end), 100*math.Cos(end))
		canvas.Path(path, "stroke: black; fill:none")

		// Draw the text. Spin it around for readability in the second half.
		canvas.RotateTranslate(50, 0, angle(i)*360/(2*math.Pi)+20)
		if i < 6 {
			canvas.Text(0, 0, month)
		} else {
			canvas.Group(`transform="rotate(180)"`, `transform-origin="13 -3"`)
			canvas.Text(0, 0, month)
			canvas.Gend()
		}
		canvas.Gend()
	}

	type milestone struct {
		month, week int
		name        string
	}
	milestones := []milestone{
		{1, 1, "Planning"},
		{1, 3, "General development"},
		{5, 4, "Freeze"},
		{6, 2, "First RC"},
		{8, 2, "Release"},
	}
	for relIdx, relName := range []string{"Summer", "Winter"} {
		angle := func(m milestone) float64 {
			return (float64(m.month-1) - 3 + (float64(m.week)-0.5)/4) * 2 * math.Pi / 12
		}

		// Shift the milestones 6 months for the winter release.
		milestones := milestones
		for i := range milestones {
			milestones[i].month = (milestones[i].month + 6*relIdx) % 12
		}

		frozen := false
		for i, m := range milestones {
			x, y := math.Cos(angle(m)), math.Sin(angle(m))
			// Align the text away from the center of the circle.
			textAnchor := "start"
			if x < 0 {
				textAnchor = "end"
			}
			// Color the arc depending on the freeze state.
			if m.name == "Freeze" {
				frozen = true
			}
			color := "green"
			if frozen {
				color = "blue"
			}

			// Center radius of the release arc.
			arcRadius := float64(120 + 20*relIdx)
			// Length of the line to the label. Vary a bit to avoid text overlap.
			lineLength := float64(30 + 5*((i+1)%2))
			// Distance from the end of the line to the text.
			textoff := float64(10)

			// Draw the arc to the next milestone.
			if i+1 < len(milestones) {
				nx, ny := math.Cos(angle(milestones[i+1])), math.Sin(angle(milestones[i+1]))
				canvas.Arc(int(x*arcRadius), int(y*arcRadius), int(arcRadius), int(arcRadius), 0, false, true, int(nx*arcRadius), int(ny*arcRadius), "stroke-width:10; fill:none; stroke: "+color)
			}
			// Draw the line from the inner edge of the arc.
			canvas.Line(int(x*(arcRadius-5)), int(y*(arcRadius-5)), int(x*(arcRadius+lineLength)), int(y*(arcRadius+lineLength)), "stroke:black")
			canvas.Text(int(x*(arcRadius+lineLength+textoff)), int(y*(arcRadius+lineLength+textoff)), relName+": "+m.name, "text-anchor: "+textAnchor)
		}
	}
	canvas.Gend()
	canvas.End()
	return f.Close()
}
