1package intfns
2
3import (
4	"fmt"
5	"math"
6
7	"github.com/ChrisTrenkamp/goxpath/tree"
8)
9
10func number(c tree.Ctx, args ...tree.Result) (tree.Result, error) {
11	if b, ok := args[0].(tree.IsNum); ok {
12		return b.Num(), nil
13	}
14
15	return nil, fmt.Errorf("Cannot convert object to a number")
16}
17
18func sum(c tree.Ctx, args ...tree.Result) (tree.Result, error) {
19	n, ok := args[0].(tree.NodeSet)
20	if !ok {
21		return nil, fmt.Errorf("Cannot convert object to a node-set")
22	}
23
24	ret := 0.0
25	for _, i := range n {
26		ret += float64(tree.GetNodeNum(i))
27	}
28
29	return tree.Num(ret), nil
30}
31
32func floor(c tree.Ctx, args ...tree.Result) (tree.Result, error) {
33	n, ok := args[0].(tree.IsNum)
34	if !ok {
35		return nil, fmt.Errorf("Cannot convert object to a number")
36	}
37
38	return tree.Num(math.Floor(float64(n.Num()))), nil
39}
40
41func ceiling(c tree.Ctx, args ...tree.Result) (tree.Result, error) {
42	n, ok := args[0].(tree.IsNum)
43	if !ok {
44		return nil, fmt.Errorf("Cannot convert object to a number")
45	}
46
47	return tree.Num(math.Ceil(float64(n.Num()))), nil
48}
49
50func round(c tree.Ctx, args ...tree.Result) (tree.Result, error) {
51	isn, ok := args[0].(tree.IsNum)
52	if !ok {
53		return nil, fmt.Errorf("Cannot convert object to a number")
54	}
55
56	n := isn.Num()
57
58	if math.IsNaN(float64(n)) || math.IsInf(float64(n), 0) {
59		return n, nil
60	}
61
62	if n < -0.5 {
63		n = tree.Num(int(n - 0.5))
64	} else if n > 0.5 {
65		n = tree.Num(int(n + 0.5))
66	} else {
67		n = 0
68	}
69
70	return n, nil
71}
72