#------------------------------------------
# display-unit.nas - Canvas EFIS framework
# author:       jsb
# created:      12/2017
#------------------------------------------


# Class DisplayUnit (DU) - handles a named display 3D object in the cockpit
#  * creates a canvas that is placed on the 3D object once
#  * creates an image element on canvas to show source input
#  * handles power on/off by (un-)hiding canvas root group

var DisplayUnit =
{
    #-- static members
    _instances: [],
    bgcolor: [0.01, 0.01, 0.01, 1],
    
    # call del() on all instances
    unload: func() {
        foreach (var instance; DisplayUnit._instances) {
            instance.del();
        }
        DisplayUnit._instances = [];
    },
    
    del: func() {
        if (me.window != nil) {
            me.window.del();
            me.window = nil;
        }
        if (me.placement != nil) { 
            me.placement.remove();
            me.placement = nil;
        }
        if (me.du_canvas != nil) {
            me.du_canvas.del();
            me.du_canvas = nil;
        }
    },

    # name: string, used in canvas window title and on DU test canvas
    # canvas_settings: hash
    # screen_obj: string, name of 3D object for canvas placement
    # parent_obj: string, optional parent 3D object for placement
    new: func(name, canvas_settings, screen_obj, parent_obj = nil) {
        var obj = {
            parents: [me],
            _id: size(DisplayUnit._instances),
            canvas_settings: canvas_settings,
            placement_node: screen_obj,
            placement_parent: parent_obj,
            placement: nil,
            du_canvas: nil,
            root: nil,
            window: nil,
            name: name,
            img: nil,     # canvas image element, shall use other canvas as source
            powerN: nil,
        };
        append(DisplayUnit._instances, obj);
        return obj._init();
    },

    _init: func() {
        me.canvas_settings["name"] = "DisplayUnit " ~ size(DisplayUnit._instances);
        me.du_canvas = canvas.new(me.canvas_settings).setColorBackground(DisplayUnit.bgcolor);
        me.root = me.du_canvas.createGroup();
        #-- optional for development: create test image
        me._test_img();
        
        me.img = me.root.createChild("image", "DisplayUnit "~me.name);
        var place = { parent: me.placement_parent, node: me.placement_node };
        me.placement = me.du_canvas.addPlacement(place);
        #var status = me.placement.getNode("status-msg",1);
        return me;
    },

    _test_img: func() {
        var x = num(me.canvas_settings.view[0])/2 or 20;
        var y = num(me.canvas_settings.view[1])/2 or 20;
        me.root.createChild("text").setText("'"~me.name~"'\n no source ")
            .setColor(1,1,1,1)
            .setAlignment("center-center")
            .setTranslation(x, y);

        var L = int(y/16);
        var black = [0, 0, 0, 1];
        var blue = [0, 0.2, 0.9, 1];
        var yellow = [1, 1, 0, 1];
        var grey = [0.7, 0.7, 0.7, 1];
        var tl = me.root.createChild("group", "top-left");
        var r = tl.createChild("path").rect(L, L, 8*L, 8*L)
            .setColorFill(grey);
        for (var i=1; i <= 3; i += 1) {
            for (var j=1; j <= 8; j += 1) {
                var r = tl.createChild("path").rect(i*L, j*L, L, L);
                # .setStrokeLineWidth(0);
                math.mod(i+j, 2) ?  r.setColorFill(black) : r.setColorFill(yellow);
            }
        }
        var F = tl.createChild("path")
            .setColorFill(blue)
            .setColor(blue)
            .setStrokeLineJoin("round")
            .setStrokeLineWidth(3);
        F.moveTo(5*L, 2*L)
            .line(3.5*L, 0).line(0, L).line(-2.5*L, 0)
            .line(0, L)
            .line(2*L, 0).line(0, L).line(-2*L, 0)
            .line(0, 3*L)
            .line(-L, 0)
            .close();
        x = me.canvas_settings.view[0]-L;
        y = me.canvas_settings.view[1]-L;
        me.root.createChild("path", "square-top-left").rect(0, 0, L, L)
            .setColorFill(1,1,1,1);
        me.root.createChild("path", "square-top-right").rect(x, 0, L, L)
            .setColorFill(1,1,1,1);
        me.root.createChild("path", "square-btm-left").rect(0, y, L, L)
            .setColorFill(1,1,1,1);
        me.root.createChild("path", "square-btm-right").rect(x, y, L, L)
            .setColorFill(1,1,1,1);
    },
    
    # set a new source path for canvas image element
    setSource: func(path) {
        #print("DisplayUnit.setSource for "~me.du_canvas.getPath()~" ("~me.name~") to "~path);
        if (path == "")
            me.img.hide();
        else {
            me.img.set("src", path);
            me.img.show();
        }
        return me;
    },

    setPowerSource: func(prop, min) {
        me.powerN = props.getNode(prop,1);
        setlistener(me.powerN, func(n) {
            if ((n.getValue() or 0) >= min) me.root.show();
            else me.root.hide();
        }, 1, 0);
    },
    
    asWindow: func(window_size) {
        me.window = canvas.Window.new(window_size, "dialog");
        me.window.set('title', "EFIS " ~ me.name)
            .set("resize", 1)
            .setCanvas(me.du_canvas);
        me.window.move(me._id*200, me._id*40);
        if (typeof(me.window.lockAspectRatio) == "func")
            me.window.lockAspectRatio(1);
        me.window.del = func() { call(canvas.Window.del, [], me); }
        return me.window
    },    
};