# vim: set tabstop=8 shiftwidth=8 expandtab:

types = dict (
        double = dict(
                name = 'double',
                zero = '0.0',
                one = '1.0',
                sqrt = 'sqrt',
                typeSuffix = 'd',
        ),
        float = dict(
                name = 'float',
                zero = '0.0f',
                one = '1.0f',
                sqrt = 'sqrtf',
                typeSuffix = '',
        ),
        int32 = dict(
                name = 'int32_t',
                zero = '0',
                one = '1',
                typeSuffix = 'i',
        ),
)

variants = [ 
dict( 
        dataType = 'Vec2',
        elemType = types['float'],
        funcPrefix = 'v2',
        components = ['x', 'y'],
), dict( 
        dataType = 'Vec3',
        elemType = types['float'],
        funcPrefix = 'v3',
        components = ['x', 'y', 'z'],
), dict( 
        dataType = 'Vec4',
        elemType = types['float'],
        funcPrefix = 'v4',
        components = ['x', 'y', 'z', 'w'],
), dict( 
        dataType = 'Vec2',
        elemType = types['double'],
        funcPrefix = 'v2',
        components = ['x', 'y'],
), dict( 
        dataType = 'Vec3',
        elemType = types['double'],
        funcPrefix = 'v3',
        components = ['x', 'y', 'z'],
), dict( 
        dataType = 'Vec4',
        elemType = types['double'],
        funcPrefix = 'v4',
        components = ['x', 'y', 'z', 'w'],
), dict( 
        dataType = 'Vec2',
        elemType = types['int32'],
        funcPrefix = 'v2',
        components = ['x', 'y'],
), dict( 
        dataType = 'Vec3',
        elemType = types['int32'],
        funcPrefix = 'v3',
        components = ['x', 'y', 'z'],
), dict( 
        dataType = 'Vec4',
        elemType = types['int32'],
        funcPrefix = 'v4',
        components = ['x', 'y', 'z', 'w'],
), 
]

functions = [ 
###

dict( 
        match = '.*',
        func = [ 

('New',
'$T $P$N(%%", ".join([("$E " + e) for e in variant["components"]])%%)',
""" {
        const $T r = { %%", ".join([e for e in variant["components"]])%% };
        return r;
}
"""),

('NewZeroLength',
'$T $P$N(void)',
""" {
        const $T r = { $(zero) };
        return r;
}
"""),

('Sum',
'$T $P$N($T a, $T b)',
""" {
        const $T r = { %%join('a', 'b', ' + ', ', ')%% };
        return r;
}
"""),

('Diff',
'$T $P$N($T a, $T b)',
""" {
        const $T r = { %%join('a', 'b', ' - ', ', ')%% };
        return r;
}
"""),

('Product',
'$T $P$N($T a, $E scale)',
""" {
        const $T r = { %%join('a', '#scale', ' * ', ', ')%% };
        return r;
}
"""),

('DotProduct',
'$E $P$N($T a, $T b)',
""" {
        return %%join('a', 'b', ' * ', ' + ')%%;
}
"""),
        
('Norm',
'$E $P$N($T a)',
""" {
        return %%join('a', 'a', ' * ', ' + ')%%;
}
"""),
        ]), 
        
### Functions that have no meaning for integers

dict( 
        match = 'Vec.[^i]?$',
        func = [ 
('Length',
'$E $P$N($T a)',
""" {
        return $(sqrt)(%%join('a', 'a', ' * ', ' + ')%%);
}
"""),

('UnitVector',
'$T $P$N($T a)',
""" {
        $E length = $PLength(a);
        if (length > $(zero)) {
                const $T r = { %%join('a', '#length', '/', ' , ')%% };
                return r;
        } else {
                const $T r = { $(zero) };
                return r;
        }
}
"""),

        ]),

###

dict( 
        match = 'Vec2',
        func = [ 
('Area',
'$E $P$N($T a)',
""" {
        return a.$0 * a.$1;
}
"""),
        ]),

###

dict( 
        match = 'Vec4',
        func = [ 
('NewFromVec3',
'$T $P$N$(typeSuffix)(Vec3$(typeSuffix) xyz, $E w)',
""" {
        const $T r = { xyz.$0, xyz.$1, xyz.$2, w };
        return r;
}
"""),

('ToVec3',
'Vec3$(typeSuffix) $P$N$(typeSuffix)($T a)',
""" {
        const Vec3$(typeSuffix) r = { a.$0, a.$1, a.$2 };
        return r;
}
"""),

        ]),

###

]

headerIntro = """
#pragma once
/* AUTO-GENERATED DO NOT EDIT */
#include <stdint.h>

"""

sourceIntro = """
/* AUTO-GENERATED DO NOT EDIT */
#include "$(headerFilename)"
#include <math.h>
#include <float.h>

"""

