//
// displayLastEditedBy.js
//
// Created by Si Fi Faye Li on 2 December, 2016
//
// Draws a line from each entity to the user in the current session who last changed a property, if any, as recorded
// by the lastEditedBy property.

(function () {
    var SHOW_LAST_EDITED_BY_ME = true;
    var SEARCH_RADIUS = 40;
    // in meter, if the entities is too far away(out of search radius), we won't display its last edited by

    var LINE_COLOR = { red: 0, green: 255, blue: 255};
    var LINE_EXPRIRATION_TIME = 3000; // in ms
    var UPDATE_INTERVAL = 1 / 60; // 60fps 
    var myHashMap = {};  // stores {entityID of target entity : overlayID of the line}

    var timer = 0;
    var lastUpdateTime = 0;
    function update(deltaTime) {
        timer += deltaTime;
        if (timer - lastUpdateTime > UPDATE_INTERVAL) {
            var targetEntityIDs = Entities.findEntities(MyAvatar.position,SEARCH_RADIUS);

            targetEntityIDs.forEach(function(targetEntityID){
                var targetEntityProps = Entities.getEntityProperties(targetEntityID);


                // don't draw lines for entities that were last edited long time ago
                if (targetEntityProps.hasOwnProperty("lastEdited")) {
                    var currentTime = new Date().getTime();
                    // lastEdited is in usec while JS date object returns msec
                    var timeDiff = currentTime - targetEntityProps.lastEdited/1000;
                    if (timeDiff > LINE_EXPRIRATION_TIME) {
                        if (myHashMap.hasOwnProperty(targetEntityID)) {
                            var overlayID = myHashMap[targetEntityID];
                            Overlays.deleteOverlay(overlayID);
                        }
                        return;
                    }
                }

                var targetAvatarUUID = targetEntityProps.lastEditedBy;

                // don't draw lines for entities last edited by myself
                // you may set SHOW_LAST_EDITED_BY_ME to true if you want to see these lines
                if (targetAvatarUUID === MyAvatar.sessionUUID && !SHOW_LAST_EDITED_BY_ME) {
                    if (myHashMap.hasOwnProperty(targetEntityID)) {
                        var overlayID = myHashMap[targetEntityID];
                        Overlays.deleteOverlay(overlayID);
                    }
                    return;
                }
                // don't draw lines for entities with no last edited by
                if (targetAvatarUUID === "{00000000-0000-0000-0000-000000000000}") {
                    if (myHashMap.hasOwnProperty(targetEntityID)) {
                        var overlayID = myHashMap[targetEntityID];
                        Overlays.deleteOverlay(overlayID);
                    }
                    return;
                } 

                var targetAvatar = AvatarList.getAvatar(targetAvatarUUID);
                
                // skip adding overlay if the avatar can't be found
                if (targetAvatar === null) {
                    // delete overlay if the avatar was found before but no long here
                    if (myHashMap.hasOwnProperty(targetEntityID)) {
                        var overlayID = myHashMap[targetEntityID];
                        Overlays.deleteOverlay(overlayID);
                    }
                    return;
                }

                var props = {
                    start: targetEntityProps.position,
                    end: targetAvatar.position,
                    color: LINE_COLOR,
                    alpha: 1,
                    ignoreRayIntersection: true,
                    visible: true,
                    solid: true,
                    drawInFront: true
                };

                if (myHashMap.hasOwnProperty(targetEntityID)) {
                    var overlayID = myHashMap[targetEntityID];
                    Overlays.editOverlay(overlayID, props);
                } else {
                    var newOverlayID = Overlays.addOverlay("line3d", props);
                    myHashMap[targetEntityID] = newOverlayID;
                }
                
            });

            // remove lines for entities no longer within search radius
            for (var key in myHashMap) {
                if (myHashMap.hasOwnProperty(key)) {
                    if (targetEntityIDs.indexOf(key) === -1) {
                        var overlayID = myHashMap[key];
                        Overlays.deleteOverlay(overlayID);
                        delete myHashMap[key];
                    }
                } 
            }

            lastUpdateTime = timer;
        }     
    }
    Script.update.connect(update);

    function cleanup() {
        for (var key in myHashMap) {
            if (myHashMap.hasOwnProperty(key)) {
                var overlayID = myHashMap[key];
                Overlays.deleteOverlay(overlayID);
            } 
        }
    }
    Script.scriptEnding.connect(cleanup);
})();