var globalActions = [];
var items = [];
var currentActions = [];
var currentHtmlID = null;
var globalChainID = 0;
var disableMovement = false;
var allowMapSwitch = false;

var loadStoryConfig = function (url, callback) {
    $.ajax({
        dataType:"json",
        url: url,
        success:callback,
    });
};

var setupStartHandler = function(data){
    if(data.startButton) {
        $("#" + data.startButton).click(startStory);
    }
    if(data.disableMovement) {
        framework.subscribe("MAP_ACTIVATED", function(map) {
            setMapMovement(false);
        });
    }
};
var tourActive = true;
var startStory = function() {
    $("#story-frame").removeClass("startscreen", 1000);
    $("#balloon-startscreen").hide();
    $("#story-frame").addClass("tour");
    $("#tour-frame").show();
    $("#story-box").scroll(function(){
        var contentOffset =  $("#story-box").offset().top;
        var contentHeight = $("#story-box").height();
        $(".story-content").removeClass("active").each(function() {
            var offset = $(this).offset().top;
            var height  = $(this).height();
            var localoffset = offset - contentOffset;
            var localbottom = localoffset + height;
            var localHeight = localbottom - localoffset;
            if(localoffset > 0 || (localbottom > 100 )) {
                var id = $(this).attr('id');
                $(this).addClass("active");
                if(id !== currentHtmlID) {
                    currentHtmlID = id;
                    var item = getItemForHtmlID(id);
                    if (item && item.doScroll) {
                        item.doScroll();
                    }
                }
                return false;
            }
        });
    });
    $("#story-box").children().first().scroll();
    if(allowMapSwitch) {
        $("#tour-button").click(function () {
            if (tourActive) {
                tourActive = false;
                showMap();
            } else {
                tourActive = true;
                showTour();
            }
        });
    } else {
        $("#tour-button").hide();
    }
    // showMap();
};

var setupItems = function(data) {
    items = data.items;
    for (var i = 0; i < items.length; i++) {
        var item = items[i];
        var htmlID = item.htmlID;
        if(!htmlID) {
            console.log('could not load ITEM ', item);
            continue;
        }
        if($(htmlID).length <= 0) {
            console.log('could not find HTML Element ', htmlID);
            continue;
        }


        if(item.clickInteraction && Array.isArray(item.clickInteraction) && item.clickInteraction.length > 0) {
            $(htmlID).click(function(item) {
                var actions = [];
                globalChainID++;
                var chainID = globalChainID;
                for(var j = 0; j < item.clickInteraction.length; j++) {
                    var action = item.clickInteraction[j];
                    actions.push(doAction.bind(this, action, true));
                }
                function chain(fn) {
                    if(fn && chainID === globalChainID) {
                        fn(function() {chain(actions.shift()) });
                    }
                }
                chain(actions.shift());

            }.bind(null, item));
        }
        if(item.scrollInteraction && Array.isArray(item.scrollInteraction) && item.scrollInteraction.length > 0) {
            item.doScroll = function(item) {
                var actions = [];
                globalChainID++;
                var chainID = globalChainID;
                clearActions();
                for(var j = 0; j < item.scrollInteraction.length; j++) {
                    var action = item.scrollInteraction[j];
                    currentActions.push(action);
                    actions.push(doAction.bind(this, action, true));
                }
                function chain(fn) {
                    if(fn && chainID === globalChainID) {
                        fn(function() {chain(actions.shift()) });
                    }
                }
                chain(actions.shift());
            }.bind(null, item);
        }
    }
};



vcs.vcm.Framework.getInstance().subscribe("MAP_LOADED", function() {

});

var framework = vcs.vcm.Framework.getInstance();
vcs.vcm.Framework.loadConfig("config.json");
loadStoryConfig("templates/items.json", function(data) {
    console.log(data);
    globalActions = data.actions;
    disableMovement = data.disableMovement;
    allowMapSwitch = data.allowMapSwitch;
    setupStartHandler(data);
    setupItems(data);
});
var clearActions = function() {
    for(var i = 0; i < currentActions.length; i++) {
        clearAction(currentActions[i]);
    }
    currentActions = [];
};
var getItemForHtmlID = function(id) {
    var jqueryID = "#" + id;
    for(var i =0; i < items.length; i++ ) {
        if(items[i].htmlID && items[i].htmlID === jqueryID) {
            return items[i];
        }
    }
}

var getAction = function(action) {
    if(typeof action === 'string') {
        for(var i = 0; i < globalActions.length; i++) {
            if( globalActions[i].id === action) {
                return globalActions[i];
            }
        }
    }
    return action;
};

var clearAction = function(action) {
    var actionObject = getAction(action);
    if(typeof actionObject  === 'object') {
        var type = actionObject.type;

        switch(type) {
            case 'viewpoint':
                // do nothing
                break;
            case 'highlight':
                clearHighlight(actionObject);
                break;
            case 'hide':
                clearHide(actionObject);
                break;
            case 'layer':
                deactivateLayer(actionObject);
                break;
            case 'geojson':
                deactivateGeojson(actionObject);
                break;
            case 'model':
                deactivateModel(actionObject);
                break;
            case 'rotate':
                stopRotation(actionObject);
                break;
            default:
                console.log(type + ' is not a defined action');
        }
    } else {
        console.log(action + ' is not a valid action');
    }
};

var doAction = function(action, clearOnActive, callback) {
    var actionObject = getAction(action);
    if(typeof actionObject  === 'object') {
        var type = actionObject.type;

        switch(type) {
            case 'viewpoint':
                gotoViewPoint(actionObject, callback);
                break;
            case 'highlight':
                if(clearOnActive && actionObject.active) {
                    clearHighlight(actionObject);
                } else {
                    highlight(actionObject);
                }
                callback();
                break;
            case 'hide':
                if(clearOnActive && actionObject.active) {
                    clearHide(actionObject);
                } else {
                    hide(actionObject);
                }
                callback();
                break;
            case 'layer':
                if(clearOnActive && actionObject.active) {
                    deactivateLayer(actionObject);
                } else {
                    activateLayer(actionObject);
                }
                callback();
                break;
            case 'geojson':
                if(clearOnActive && actionObject.active) {
                    deactivateGeojson(actionObject);
                } else {
                    activateGeojson(actionObject);
                }
                callback();
                break;
            case 'model':
                if(clearOnActive && actionObject.active) {
                    deactivateModel(actionObject);
                } else {
                    activateModel(actionObject);
                }
                callback();
                break;
            case 'rotate':
                if(clearOnActive && actionObject.active) {
                    stopRotation(actionObject);
                } else {
                    rotate(actionObject);
                }
                callback();
                break;
            default:
                console.log(type + ' is not a defined action');
        }
    } else {
        console.log(action + ' is not a valid action');
    }
};

var gotoViewPoint = function(viewpointObject, callback) {
    if(!viewpointObject.viewpoint) {
        console.log('Could not goto Viewpoint ', viewpointObject);
        return;
    }
    var viewpoint = new vcs.vcm.util.ViewPoint(viewpointObject.viewpoint);
    framework.getActiveMap().gotoViewPoint(viewpoint, null, null, callback);
};

var highlight = function(action) {
    if (action.ids) {
        var layerNames = action.layerNames;
        var layers = framework.getLayers();
        var highlightIDs = action.ids;
        for (var key in highlightIDs) {
            if(highlightIDs.hasOwnProperty(key)) {
                var color = highlightIDs[key];
                if(!(color instanceof Cesium.Color)) {
                    var cesiumColor = Cesium.Color.fromCssColorString(color);
                    highlightIDs[key] = cesiumColor;
                }
            }
        }
        for (var i = 0; i< layers.length; i++) {
            var layer = layers[i];
            if(layer instanceof vcs.vcm.layer.cesium.Buildings) {
                if(!layerNames || layerNames.indexOf(layer.getName()) >= 0) {
                    layer.highlight(highlightIDs);
                }
            }
        }
        action.active = true;
    }
};
var clearHighlight = function(action) {
    if (action.ids) {
        var layerNames = action.layerNames;
        var layers = framework.getLayers();
        var highlightIDs = action.ids;
        var toUnhighlight = [];
        for (var key in highlightIDs) {
            toUnhighlight.push(key);
        }
        for (var i = 0; i< layers.length; i++) {
            var layer = layers[i];
            if(layer instanceof vcs.vcm.layer.cesium.Buildings) {
                if(!layerNames || layerNames.indexOf(layer.getName()) >= 0) {
                    layer.unHighlight(toUnhighlight);
                }
            }
        }
        action.active = false;
    }
};
var hide = function(action) {
    if (action.ids) {
        var layerNames = action.layerNames;
        var layers = framework.getLayers();
        var idsToHide = action.ids;
        for (var i = 0; i< layers.length; i++) {
            var layer = layers[i];
            if(layer instanceof vcs.vcm.layer.cesium.Buildings) {
                if(!layerNames || layerNames.indexOf(layer.getName()) >= 0) {
                    layer.hideObjects(idsToHide);
                }
            }
        }
        action.active = true;
    }
};
var clearHide = function(action) {
    if (action.ids) {
        var layerNames = action.layerNames;
        var layers = framework.getLayers();
        var idsToHide = action.ids;
        for (var i = 0; i< layers.length; i++) {
            var layer = layers[i];
            if(layer instanceof vcs.vcm.layer.cesium.Buildings) {
                if(!layerNames || layerNames.indexOf(layer.getName()) >= 0) {
                    layer.showObjects(idsToHide);
                }
            }
        }
        action.active = false;
    }
};
var activateLayer = function(action) {
    if (action.layerNames || action.layerNamesInactive) {
        var layerNamesToActivate = action.layerNames || [];
        var layerNamesToDeactivate = action.layerNamesInactive || [];
        var layers = framework.getLayers();
        for (var i = 0; i< layers.length; i++) {
            var layer = layers[i];
            if(layerNamesToActivate.indexOf(layer.getName()) >= 0) {
                layer.activate(true);
            } else if(layerNamesToDeactivate.indexOf(layer.getName()) >= 0) {
                layer.activate(false);
            }
        }
        if(!action.subscription) {
            action.subscription = true;
            framework.subscribe("LAYER_CHANGED", function(layer){
                var layerNames = this.layerNames;
                if(layerNames.indexOf(layer.getName()) >= 0) {
                    if(layer.isActive() !== this.active) {
                        this.active = layer.isActive();
                    }
                }
            }.bind(action));
        }
        framework.subscribe
        action.active = true;
    }
};
var deactivateLayer = function(action) {
    if (action.layerNames || action.layerNamesInactive) {
        var layerNamesToActivate = action.layerNamesInactive || [];
        var layerNamesToDeactivate = action.layerNames || [];
        var layers = framework.getLayers();
        for (var i = 0; i< layers.length; i++) {
            var layer = layers[i];
            if(layerNamesToActivate.indexOf(layer.getName()) >= 0) {
                layer.activate(true);
            } else if(layerNamesToDeactivate.indexOf(layer.getName()) >= 0) {
                layer.activate(false);
            }
        }
        action.active = false;
    }
};
var activateGeojson = function(action) {
    if(action.featureUrl) {
        if(!action.layer) {
            action.layer = new vcs.vcm.layer.GeoJSON( {
                url: action.featureUrl,
                projection: {
                    epsg: 4326
                },
            });
            framework.addLayer(action.layer);
        }
        action.layer.activate(true);
        action.active = true;
    }
};
var deactivateGeojson = function(action) {
    if(action.layer) {
        action.layer.activate(false);
        action.active = false;
    }
};

var activateModel = function(action) {
    if(action.models) {
        if(!action.layer) {
            action.layer = new vcs.vcm.layer.cesium.Gltf({
                projection: {epsg: 4326},
                allowPicking: false,
                models: action.models
            });
            framework.addLayer(action.layer);
        }
        action.layer.activate(true);
        action.active = true
    }
};

var deactivateModel = function(action) {
    if(action.layer) {
        action.layer.activate(false);
        action.active = false;
    }
};

var rotate = function(action) {
    if(action) {
        var map = framework.getActiveMap();
        var widget = framework.getWidgetByType("vcs.vcm.widgets.NavigationControls");
        if(widget) {
            widget.rotateAroundCenterPosition(map, true);
        }
        action.active = true
    }
};

var stopRotation = function(action) {
    if(action) {
        var map = framework.getActiveMap();
        var widget = framework.getWidgetByType("vcs.vcm.widgets.NavigationControls");
        if(widget) {
            widget.rotateAroundCenterPosition(map, false);
        }
        action.active = false;
    }
};


var showMap = function() {
    $("#vcs_map_container").addClass("tour-inactive");
    $("#story-frame").addClass("tour-inactive");
    $("#widget-box").removeClass("hidden");
    $(".mapControls").removeClass("hidden");
    // $(".tool-box").addClass("hidden");  //Commenting tool-box and tool-header to hide the vcm header to avoid menu from getting overrided behind header
    //$(".tour-header").addClass("hidden");
    $(".dropdown").removeClass("hidden");
    setMapMovement(true);
};

var showTour = function() {
    $("#vcs_map_container").removeClass("tour-inactive");
    $("#story-frame").removeClass("tour-inactive");
    $("#widget-box").addClass("hidden");
    $(".mapControls").addClass("hidden");
    $("#tour-button").show();
    //$(".tool-box").addClass("hidden");
    //$(".tour-header").removeClass("hidden");
    if(disableMovement) {
        setMapMovement(false);
    }
};

var setMapMovement = function(value) {
    var map = vcs.vcm.Framework.getInstance().getActiveMap();
    if(map instanceof vcs.vcm.maps.Cesium) {
        var scene = map.getScene();
        scene.screenSpaceCameraController.enableRotate = value;
        scene.screenSpaceCameraController.enableTranslate = value;
        scene.screenSpaceCameraController.enableZoom = value;
        scene.screenSpaceCameraController.enableTilt = value;
        scene.screenSpaceCameraController.enableLook = value;
    }
}