umplot.um


type (
    Point* = struct {
        x, y: real
    }

    Kind* = enum {
        line = 1
        scatter
    }

    Style* = struct {
        kind: Kind
        color: uint32
        width: real     
    }

    Series* = struct {
        points: []Point
        name: str
        style: Style
    }

    Grid* = struct {
        xNumLines, yNumLines: int 
        color: uint32
        fontSize: int
        visible, labelled: bool
    }

    Titles* = struct {
        x, y, graph: str
        color: uint32
        fontSize: int
        visible: bool
    }

    Legend* = struct {
        visible: bool
    }    

    Plot* = struct {
        series: []Series
        grid: Grid
        titles: Titles
        legend: Legend
    }
)

fn (s: ^Series) clear*() {
    s.points = []Point{}
}

fn (s: ^Series) add*(x, y: real) {
    s.points = append(s.points, Point{x, y})
}

fn init*(numSeries: int = 1, kind: Kind = .line): Plot {
    plt := Plot{series: make([]Series, numSeries)}

    const getDefaultColors = fn (numColors: int): []uint32 {
        basicColors := []uint32{0xFF0000DD, 0xFFDD0000, 0xFF00DD00}
        colors := make([]uint32, numColors)

        for i := 0; i < numColors; i++ {
            if i < len(basicColors) {
                colors[i] = basicColors[i]
            } else {
                j := i - len(basicColors)
                colors[i] = (colors[j] + colors[j + 1]) / 2
            }
        }

        return colors       
    }

    defaultColors := getDefaultColors(numSeries)

    for i := 0; i < numSeries; i++ {
        plt.series[i].name = ""
        plt.series[i].style = {kind: kind, color: defaultColors[i], width: 3.0}
    }

    plt.grid = {xNumLines: 5, yNumLines: 5, color: 0xFF505050, fontSize: 12, visible: true, labelled: true}
    plt.titles = {x: "", y: "", graph: "", color: plt.grid.color, fontSize: plt.grid.fontSize, visible: true}
    plt.legend = {visible: true}

    return plt
}

fn umplot_plot(p: ^Plot): int

fn (p: ^Plot) plot*() {
    umplot_plot(p)
}