//
//  lightModifier.js
//
//  Created by James Pollack @imgntn on 12/15/2015
//  Copyright 2015 High Fidelity, Inc.
//
//  Given a selected light, instantiate some entities that represent various values you can dynamically adjust by grabbing and moving.
//
//  Distributed under the Apache License, Version 2.0.
//  See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//  

//some experimental options
var ONLY_I_CAN_EDIT = false;
var SLIDERS_SHOULD_STAY_WITH_AVATAR = false;
var VERTICAL_SLIDERS = false;
var SHOW_OVERLAYS = true;
var SHOW_LIGHT_VOLUME = true;
var USE_PARENTED_PANEL = true;
var VISIBLE_PANEL = true;
var USE_LABELS = true;
var LEFT_LABELS = false;
var RIGHT_LABELS = true;
var ROTATE_CLOSE_BUTTON = false;

//variables for managing overlays
var selectionDisplay;
var selectionManager;
var lightOverlayManager;

//for when we make a 3d model of a light a parent for the light
var PARENT_SCRIPT_URL = Script.resolvePath('lightParent.js?' + Math.random(0 - 100));

if (SHOW_OVERLAYS === true) {

    Script.include('../../scripts/system/libraries/gridTool.js');
    Script.include('../../scripts/system/create/entitySelectionTool/entitySelectionTool.js?' + Math.random(0 - 100));
    Script.include('../libraries/lightOverlayManager.js');

    var grid = Grid();
    gridTool = GridTool({
        horizontalGrid: grid
    });
    gridTool.setVisible(false);

    selectionDisplay = SelectionDisplay;
    selectionManager = SelectionManager;
    lightOverlayManager = new LightOverlayManager();
    selectionManager.addEventListener(function() {
        selectionDisplay.updateHandles();
        lightOverlayManager.updatePositions();
    });
    lightOverlayManager.setVisible(true);
}

var DEFAULT_PARENT_ID = '{00000000-0000-0000-0000-000000000000}'

var AXIS_SCALE = 1;
var COLOR_MAX = 255;
var INTENSITY_MAX = 0.05;
var CUTOFF_MAX = 360;
var EXPONENT_MAX = 1;

var SLIDER_SCRIPT_URL = Script.resolvePath('slider.js?' + Math.random(0, 100));
var LIGHT_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/james/light_modifier/source4_very_good.fbx';
var CLOSE_BUTTON_MODEL_URL = 'http://hifi-content.s3.amazonaws.com/james/light_modifier/red_x.fbx';
var CLOSE_BUTTON_SCRIPT_URL = Script.resolvePath('closeButton.js?' + Math.random(0, 100));
var TRANSPARENT_PANEL_URL = 'http://hifi-content.s3.amazonaws.com/james/light_modifier/transparent_box_alpha_15.fbx';
var VISIBLE_PANEL_SCRIPT_URL = Script.resolvePath('visiblePanel.js?' + Math.random(0, 100));

var RED = {
    red: 255,
    green: 0,
    blue: 0
};

var GREEN = {
    red: 0,
    green: 255,
    blue: 0
};

var BLUE = {
    red: 0,
    green: 0,
    blue: 255
};

var PURPLE = {
    red: 255,
    green: 0,
    blue: 255
};

var WHITE = {
    red: 255,
    green: 255,
    blue: 255
};

var ORANGE = {
    red: 255,
    green: 165,
    blue: 0
}

var SLIDER_DIMENSIONS = {
    x: 0.075,
    y: 0.075,
    z: 0.075
};

var CLOSE_BUTTON_DIMENSIONS = {
    x: 0.1,
    y: 0.025,
    z: 0.1
}

var LIGHT_MODEL_DIMENSIONS = {
    x: 0.58,
    y: 1.21,
    z: 0.57
}

var PER_ROW_OFFSET = {
    x: 0,
    y: -0.2,
    z: 0
};
var sliders = [];
var slidersRef = {
    'color_red': null,
    'color_green': null,
    'color_blue': null,
    intensity: null,
    cutoff: null,
    exponent: null
};
var light = null;

var basePosition;
var avatarRotation;

function entitySlider(light, color, sliderType, displayText, row) {
    this.light = light;
    this.lightID = light.id.replace(/[{}]/g, "");
    this.initialProperties = light.initialProperties;
    this.color = color;
    this.sliderType = sliderType;
    this.displayText = displayText;
    this.verticalOffset = Vec3.multiply(row, PER_ROW_OFFSET);
    this.avatarRot = Quat.fromPitchYawRollDegrees(0, MyAvatar.bodyYaw, 0.0);
    this.basePosition = Vec3.sum(MyAvatar.position, Vec3.multiply(1.5, Quat.getFront(this.avatarRot)));
    this.basePosition.y += 1;
    basePosition = this.basePosition;
    avatarRot = this.avatarRot;

    var message = {
        lightID: this.lightID,
        sliderType: this.sliderType,
        sliderValue: null
    };

    if (this.sliderType === 'color_red') {
        message.sliderValue = this.initialProperties.color.red
        this.setValueFromMessage(message);
    }
    if (this.sliderType === 'color_green') {
        message.sliderValue = this.initialProperties.color.green
        this.setValueFromMessage(message);
    }
    if (this.sliderType === 'color_blue') {
        message.sliderValue = this.initialProperties.color.blue
        this.setValueFromMessage(message);
    }

    if (this.sliderType === 'intensity') {
        message.sliderValue = this.initialProperties.intensity
        this.setValueFromMessage(message);
    }

    if (this.sliderType === 'exponent') {
        message.sliderValue = this.initialProperties.exponent
        this.setValueFromMessage(message);
    }

    if (this.sliderType === 'cutoff') {
        message.sliderValue = this.initialProperties.cutoff
        this.setValueFromMessage(message);
    }

    this.setInitialSliderPositions();
    this.createAxis();
    this.createSliderIndicator();
    if (USE_LABELS === true) {
        this.createLabel()
    }
    return this;
}

//what's the ux for adjusting values?  start with simple entities, try image overlays etc
entitySlider.prototype = {
    createAxis: function() {
        //start of line
        var position;
        var extension;

        if (VERTICAL_SLIDERS == true) {
            position = Vec3.sum(this.basePosition, Vec3.multiply(row, (Vec3.multiply(0.2, Quat.getRight(this.avatarRot)))));
            //line starts on bottom and goes up
            var upVector = Quat.getUp(this.avatarRot);
            extension = Vec3.multiply(AXIS_SCALE, upVector);
        } else {
            position = Vec3.sum(this.basePosition, this.verticalOffset);
            //line starts on left and goes to right
            //set the end of the line to the right
            var rightVector = Quat.getRight(this.avatarRot);
            extension = Vec3.multiply(AXIS_SCALE, rightVector);
        }


        this.axisStart = position;
        this.endOfAxis = Vec3.sum(position, extension);
        this.createEndOfAxisEntity();

        var properties = {
            type: 'Line',
            name: 'Hifi-Slider-Axis::' + this.sliderType,
            color: this.color,
            dynamic: false,
            collisionless: true,
            dimensions: {
                x: 3,
                y: 3,
                z: 3
            },
            position: position,
            linePoints: [{
                x: 0,
                y: 0,
                z: 0
            }, extension],
            lineWidth: 5,
        };

        this.axis = Entities.addEntity(properties);
    },
    createEndOfAxisEntity: function() {
        //we use this to track the end of the axis while parented to a panel
        var properties = {
            name: 'Hifi-End-Of-Axis',
            type: 'Box',
            dynamic: false,
            collisionless: true,
            dimensions: {
                x: 0.01,
                y: 0.01,
                z: 0.01
            },
            color: {
                red: 255,
                green: 255,
                blue: 255
            },
            position: this.endOfAxis,
            parentID: this.axis,
            visible: false
        }

        this.endOfAxisEntity = Entities.addEntity(this.endOfAxis);
    },
    createLabel: function() {

        var LABEL_WIDTH = 0.25
        var PER_LETTER_SPACING = 0.1;
        var textWidth = this.displayText.length * PER_LETTER_SPACING;

        var position;
        if (LEFT_LABELS === true) {
            var leftVector = Vec3.multiply(-1, Quat.getRight(this.avatarRot));

            var extension = Vec3.multiply(textWidth, leftVector);

            position = Vec3.sum(this.axisStart, extension);
        }

        if (RIGHT_LABELS === true) {
            var rightVector = Quat.getRight(this.avatarRot);

            var extension = Vec3.multiply(textWidth / 1.75, rightVector);

            position = Vec3.sum(this.endOfAxis, extension);
        }


        var labelProperties = {
            name: 'Hifi-Slider-Label-' + this.sliderType,
            type: 'Text',
            dimensions: {
                x: textWidth,
                y: 0.2,
                z: 0.1
            },
            textColor: {
                red: 255,
                green: 255,
                blue: 255
            },
            text: this.displayText,
            lineHeight: 0.14,
            backgroundColor: {
                red: 0,
                green: 0,
                blue: 0
            },
            position: position,
            rotation: this.avatarRot,
        }
        print('BEFORE CREATE LABEL' + JSON.stringify(labelProperties))
        this.label = Entities.addEntity(labelProperties);
        print('AFTER CREATE LABEL')
    },
    createSliderIndicator: function() {
        var extensionVector;
        var position;
        if (VERTICAL_SLIDERS == true) {
            position = Vec3.sum(this.basePosition, Vec3.multiply(row, (Vec3.multiply(0.2, Quat.getRight(this.avatarRot)))));
            extensionVector = Quat.getUp(this.avatarRot);

        } else {
            position = Vec3.sum(this.basePosition, this.verticalOffset);
            extensionVector = Quat.getRight(this.avatarRot);

        }

        var initialDistance;
        if (this.sliderType === 'color_red') {
            initialDistance = this.distanceRed;
        }
        if (this.sliderType === 'color_green') {
            initialDistance = this.distanceGreen;
        }
        if (this.sliderType === 'color_blue') {
            initialDistance = this.distanceBlue;
        }
        if (this.sliderType === 'intensity') {
            initialDistance = this.distanceIntensity;
        }
        if (this.sliderType === 'cutoff') {
            initialDistance = this.distanceCutoff;
        }
        if (this.sliderType === 'exponent') {
            initialDistance = this.distanceExponent;
        }

        var extension = Vec3.multiply(initialDistance, extensionVector);
        var sliderPosition = Vec3.sum(position, extension);

        var properties = {
            type: 'Sphere',
            name: 'Hifi-Slider-' + this.sliderType,
            dimensions: SLIDER_DIMENSIONS,
            dynamic: true,
            color: this.color,
            position: sliderPosition,
            script: SLIDER_SCRIPT_URL,
            collisionless: true,
            userData: JSON.stringify({
                lightModifierKey: {
                    lightID: this.lightID,
                    sliderType: this.sliderType,
                    axisStart: position,
                    axisEnd: this.endOfAxis,
                },
                handControllerKey: {
                    disableReleaseVelocity: true,
                    disableMoveWithHead: true,
                    disableNearGrab:true
                }
            }),
        };

        this.sliderIndicator = Entities.addEntity(properties);
    },
    setValueFromMessage: function(message) {

        //message is not for our light
        if (message.lightID !== this.lightID) {
            //    print('not our light')
            return;
        }

        //message is not our type
        if (message.sliderType !== this.sliderType) {
            //    print('not our slider type')
            return
        }

        var lightProperties = Entities.getEntityProperties(this.lightID);

        if (this.sliderType === 'color_red') {
            Entities.editEntity(this.lightID, {
                color: {
                    red: message.sliderValue,
                    green: lightProperties.color.green,
                    blue: lightProperties.color.blue
                }
            });
        }

        if (this.sliderType === 'color_green') {
            Entities.editEntity(this.lightID, {
                color: {
                    red: lightProperties.color.red,
                    green: message.sliderValue,
                    blue: lightProperties.color.blue
                }
            });
        }

        if (this.sliderType === 'color_blue') {
            Entities.editEntity(this.lightID, {
                color: {
                    red: lightProperties.color.red,
                    green: lightProperties.color.green,
                    blue: message.sliderValue,
                }
            });
        }

        if (this.sliderType === 'intensity') {
            Entities.editEntity(this.lightID, {
                intensity: message.sliderValue
            });
        }

        if (this.sliderType === 'cutoff') {
            Entities.editEntity(this.lightID, {
                cutoff: message.sliderValue
            });
        }

        if (this.sliderType === 'exponent') {
            Entities.editEntity(this.lightID, {
                exponent: message.sliderValue
            });
        }
    },
    setInitialSliderPositions: function() {
        this.distanceRed = (this.initialProperties.color.red / COLOR_MAX) * AXIS_SCALE;
        this.distanceGreen = (this.initialProperties.color.green / COLOR_MAX) * AXIS_SCALE;
        this.distanceBlue = (this.initialProperties.color.blue / COLOR_MAX) * AXIS_SCALE;
        this.distanceIntensity = (this.initialProperties.intensity / INTENSITY_MAX) * AXIS_SCALE;
        this.distanceCutoff = (this.initialProperties.cutoff / CUTOFF_MAX) * AXIS_SCALE;
        this.distanceExponent = (this.initialProperties.exponent / EXPONENT_MAX) * AXIS_SCALE;
    }

};


var panel;
var visiblePanel;

function makeSliders(light) {

    if (USE_PARENTED_PANEL === true) {
        panel = createPanelEntity(MyAvatar.position);
    }

    if (light.type === 'spotlight') {
        var USE_COLOR_SLIDER = true;
        var USE_INTENSITY_SLIDER = true;
        var USE_CUTOFF_SLIDER = true;
        var USE_EXPONENT_SLIDER = true;
    }
    if (light.type === 'pointlight') {
        var USE_COLOR_SLIDER = true;
        var USE_INTENSITY_SLIDER = true;
        var USE_CUTOFF_SLIDER = false;
        var USE_EXPONENT_SLIDER = false;
    }
    if (USE_COLOR_SLIDER === true) {
        slidersRef.color_red = new entitySlider(light, RED, 'color_red', 'Red', 1);
        slidersRef.color_green = new entitySlider(light, GREEN, 'color_green', 'Green', 2);
        slidersRef.color_blue = new entitySlider(light, BLUE, 'color_blue', 'Blue', 3);

        sliders.push(slidersRef.color_red);
        sliders.push(slidersRef.color_green);
        sliders.push(slidersRef.color_blue);

    }
    if (USE_INTENSITY_SLIDER === true) {
        slidersRef.intensity = new entitySlider(light, WHITE, 'intensity', 'Intensity', 4);
        sliders.push(slidersRef.intensity);
    }
    if (USE_CUTOFF_SLIDER === true) {
        slidersRef.cutoff = new entitySlider(light, PURPLE, 'cutoff', 'Cutoff', 5);
        sliders.push(slidersRef.cutoff);
    }
    if (USE_EXPONENT_SLIDER === true) {
        slidersRef.exponent = new entitySlider(light, ORANGE, 'exponent', 'Exponent', 6);
        sliders.push(slidersRef.exponent);
    }

    createCloseButton(slidersRef.color_red.axisStart);

    subscribeToSliderMessages();

    if (USE_PARENTED_PANEL === true) {
        parentEntitiesToPanel(panel);
    }

    if (SLIDERS_SHOULD_STAY_WITH_AVATAR === true) {
        parentPanelToAvatar(panel);
    }

    if (VISIBLE_PANEL === true) {
        visiblePanel = createVisiblePanel();
    }
};

function parentPanelToAvatar(panel) {
    //this is going to need some more work re: the sliders actually being grabbable.  probably something to do with updating axis movement
    Entities.editEntity(panel, {
        parentID: MyAvatar.sessionUUID,
        //actually figure out which one to parent it to -- probably a spine or something.
        parentJointIndex: 1,
    })
}


function parentEntitiesToPanel(panel) {

    sliders.forEach(function(slider) {
        Entities.editEntity(slider.axis, {
            parentID: panel
        })
        Entities.editEntity(slider.sliderIndicator, {
            parentID: panel
        })
    })

    closeButtons.forEach(function(button) {
        Entities.editEntity(button, {
            parentID: panel
        })
    })
}

function createPanelEntity(position) {
    print('CREATING PANEL at ' + JSON.stringify(position));
    var panelProperties = {
        name: 'Hifi-Slider-Panel',
        type: 'Box',
        dimensions: {
            x: 0.1,
            y: 0.1,
            z: 0.1
        },
        visible: false,
        dynamic: false,
        collisionless: true
    }

    var panel = Entities.addEntity(panelProperties);
    return panel
}

function createVisiblePanel() {
    var totalOffset = -PER_ROW_OFFSET.y * sliders.length;

    var moveRight = Vec3.sum(basePosition, Vec3.multiply(AXIS_SCALE / 2, Quat.getRight(avatarRot)));

    var moveDown = Vec3.sum(moveRight, Vec3.multiply((sliders.length + 1) / 2, PER_ROW_OFFSET))
    var panelProperties = {
        name: 'Hifi-Visible-Transparent-Panel',
        type: 'Model',
        modelURL: TRANSPARENT_PANEL_URL,
        dimensions: {
            x: AXIS_SCALE + 0.1,
            y: totalOffset,
            z: SLIDER_DIMENSIONS.z / 4
        },
        visible: true,
        dynamic: false,
        collisionless: true,
        position: moveDown,
        rotation: avatarRot,
        script: VISIBLE_PANEL_SCRIPT_URL
    }

    var panel = Entities.addEntity(panelProperties);

    return panel
}


function createLightModel(position, rotation) {
    var blockProperties = {
        name: 'Hifi-Spotlight-Model',
        type: 'Model',
        shapeType: 'box',
        modelURL: LIGHT_MODEL_URL,
        dimensions: LIGHT_MODEL_DIMENSIONS,
        dynamic: true,
        position: position,
        rotation: rotation,
        script: PARENT_SCRIPT_URL,
        userData: JSON.stringify({
            handControllerKey: {
                disableReleaseVelocity: true
            }
        })
    };

    var block = Entities.addEntity(blockProperties);

    return block
}

var closeButtons = [];

function createCloseButton(axisStart) {
    var MARGIN = 0.10;
    var VERTICAL_OFFFSET = {
        x: 0,
        y: 0.15,
        z: 0
    };
    var leftVector = Vec3.multiply(-1, Quat.getRight(avatarRot));
    var extension = Vec3.multiply(MARGIN, leftVector);
    var position = Vec3.sum(axisStart, extension);

    var buttonProperties = {
        name: 'Hifi-Close-Button',
        type: 'Model',
        modelURL: CLOSE_BUTTON_MODEL_URL,
        dimensions: CLOSE_BUTTON_DIMENSIONS,
        position: Vec3.sum(position, VERTICAL_OFFFSET),
        rotation: Quat.multiply(avatarRot, Quat.fromPitchYawRollDegrees(90, 0, 45)),
        //rotation: Quat.fromPitchYawRollDegrees(0, 0, 90),
        dynamic: false,
        collisionless: true,
        script: CLOSE_BUTTON_SCRIPT_URL,
        userData: JSON.stringify({
            grabbableKey: {
                wantsTrigger: true
            }
        })
    }

    var button = Entities.addEntity(buttonProperties);

    closeButtons.push(button);

    if (ROTATE_CLOSE_BUTTON === true) {
        Script.update.connect(rotateCloseButtons);
    }
}

function rotateCloseButtons() {
    closeButtons.forEach(function(button) {
        Entities.editEntity(button, {
            angularVelocity: {
                x: 0,
                y: 0.5,
                z: 0
            }
        })

    })
}

function subScribeToNewLights() {
    Messages.subscribe('Hifi-Light-Mod-Receiver');
    Messages.messageReceived.connect(handleLightModMessages);
}

function subscribeToSliderMessages() {
    Messages.subscribe('Hifi-Slider-Value-Reciever');
    Messages.messageReceived.connect(handleValueMessages);
}

function subscribeToLightOverlayRayCheckMessages() {
    Messages.subscribe('Hifi-Light-Overlay-Ray-Check');
    Messages.messageReceived.connect(handleLightOverlayRayCheckMessages);
}

function subscribeToCleanupMessages() {
    Messages.subscribe('Hifi-Light-Modifier-Cleanup');
    Messages.messageReceived.connect(handleCleanupMessages);
}


function handleLightModMessages(channel, message, sender) {
    if (channel !== 'Hifi-Light-Mod-Receiver') {
        return;
    }
    if (sender !== MyAvatar.sessionUUID) {
        return;
    }
    var parsedMessage = JSON.parse(message);

    makeSliders(parsedMessage.light);
    light = parsedMessage.light.id
    if (SHOW_LIGHT_VOLUME === true) {
        selectionManager.setSelections([parsedMessage.light.id]);
    }
}

function handleValueMessages(channel, message, sender) {

    if (channel !== 'Hifi-Slider-Value-Reciever') {
        return;
    }
    if (ONLY_I_CAN_EDIT === true && sender !== MyAvatar.sessionUUID) {
        return;
    }
    var parsedMessage = JSON.parse(message);

    slidersRef[parsedMessage.sliderType].setValueFromMessage(parsedMessage);
}

var currentLight;
var block;
var oldParent = null;
var hasParent = false;

function handleLightOverlayRayCheckMessages(channel, message, sender) {
    if (channel !== 'Hifi-Light-Overlay-Ray-Check') {
        return;
    }
    if (ONLY_I_CAN_EDIT === true && sender !== MyAvatar.sessionUUID) {
        return;
    }

    var pickRay = JSON.parse(message);

    var doesIntersect = lightOverlayManager.findRayIntersection(pickRay);
    //  print('DOES INTERSECT A LIGHT WE HAVE???' + doesIntersect.intersects);
    if (doesIntersect.intersects === true) {
        // print('FULL MESSAGE:::' + JSON.stringify(doesIntersect))

        var lightID = doesIntersect.entityID;
        if (currentLight === lightID) {
            //  print('ALREADY HAVE A BLOCK, EXIT')
            return;
        }

        currentLight = lightID;
        var lightProperties = Entities.getEntityProperties(lightID);
        if (lightProperties.parentID !== DEFAULT_PARENT_ID) {
            //this light has a parent already.  so lets call our block the parent and then make sure not to delete it at the end;
            oldParent = lightProperties.parentID;
            hasParent = true;
            block = lightProperties.parentID;
            if (lightProperties.parentJointIndex !== -1) {
                //should make sure to retain the parent too.  but i don't actually know what the
            }
        } else {
            block = createLightModel(lightProperties.position, lightProperties.rotation);
        }

        var light = {
            id: lightID,
            type: 'spotlight',
            initialProperties: lightProperties
        }

        makeSliders(light);

        if (SHOW_LIGHT_VOLUME === true) {
            selectionManager.setSelections([lightID]);
        }

        Entities.editEntity(lightID, {
            parentID: block,
            parentJointIndex: -1
        });

    }
}

function handleCleanupMessages(channel, message, sender) {

    if (channel !== 'Hifi-Light-Modifier-Cleanup') {
        return;
    }
    if (ONLY_I_CAN_EDIT === true && sender !== MyAvatar.sessionUUID) {
        return;
    }
    if (message === 'callCleanup') {
        cleanup(true);
    }
}

function updateSliderAxis() {
    sliders.forEach(function(slider) {

    })
}

function cleanup(fromMessage) {
    var i;
    for (i = 0; i < sliders.length; i++) {
        Entities.deleteEntity(sliders[i].axis);
        Entities.deleteEntity(sliders[i].sliderIndicator);
        Entities.deleteEntity(sliders[i].label);
    }

    while (closeButtons.length > 0) {
        Entities.deleteEntity(closeButtons.pop());
    }

    //if the light was already parented to something we will want to restore that.  or come up with groups or something clever.
    if (oldParent !== null) {
        Entities.editEntity(currentLight, {
            parentID: oldParent,
        });
    } else {
        Entities.editEntity(currentLight, {
            parentID: null,
        });
    }


    if (fromMessage !== true) {
        Messages.messageReceived.disconnect(handleLightModMessages);
        Messages.messageReceived.disconnect(handleValueMessages);
        Messages.messageReceived.disconnect(handleLightOverlayRayCheckMessages);
        lightOverlayManager.setVisible(false);
    }


    Entities.deleteEntity(panel);
    Entities.deleteEntity(visiblePanel);

    selectionManager.clearSelections();

    if (ROTATE_CLOSE_BUTTON === true) {
        Script.update.disconnect(rotateCloseButtons);
    }

    if (hasParent === false) {
        Entities.deleteEntity(block);
    }

    oldParent = null;
    hasParent = false;
    currentLight = null;
    sliders = [];

}

Script.scriptEnding.connect(cleanup);

Script.scriptEnding.connect(function() {
    lightOverlayManager.setVisible(false);
})


subscribeToLightOverlayRayCheckMessages();
subScribeToNewLights();
subscribeToCleanupMessages();



//other light properties
// diffuseColor: { red: 255, green: 255, blue: 255 },
// ambientColor: { red: 255, green: 255, blue: 255 },
// specularColor: { red: 255, green: 255, blue: 255 },
// constantAttenuation: 1,
// linearAttenuation: 0,
// quadraticAttenuation: 0,
// exponent: 0,
// cutoff: 180, // in degrees