/*
 * Copyright 2014-2015 See AUTHORS file.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.kotcrab.vis.runtime.scene;

import com.artemis.BaseSystem;
import com.artemis.InvocationStrategy;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.utils.Array;
import com.kotcrab.vis.runtime.RuntimeConfiguration;
import com.kotcrab.vis.runtime.RuntimeContext;
import com.kotcrab.vis.runtime.data.LayerData;
import com.kotcrab.vis.runtime.data.SceneData;
import com.kotcrab.vis.runtime.plugin.EntitySupport;
import com.kotcrab.vis.runtime.scene.SceneConfig.ConfigElement;
import com.kotcrab.vis.runtime.scene.SceneLoader.SceneParameter;
import com.kotcrab.vis.runtime.system.CameraManager;
import com.kotcrab.vis.runtime.util.AfterSceneInit;
import com.kotcrab.vis.runtime.util.BootstrapInvocationStrategy;
import com.kotcrab.vis.runtime.util.EntityEngine;
import com.kotcrab.vis.runtime.util.EntityEngineConfiguration;

/**
 * Base class of VisRuntime scene system. Scene are typically constructed using {@link VisAssetManager} with {@link SceneLoader}
 * @author Kotcrab
 */
public class Scene {
	private CameraManager cameraManager;
	private EntityEngine engine;

	private Array<LayerData> layerData;

	/** Used by framework, not indented for external use */
	public Scene (RuntimeContext context, SceneData data, SceneParameter parameter) {
		layerData = data.layers;

		AssetManager assetsManager = context.assetsManager;
		RuntimeConfiguration runtimeConfig = context.configuration;

		EntityEngineConfiguration engineConfig = new EntityEngineConfiguration();

		if (parameter == null) parameter = new SceneParameter();
		SceneConfig config = parameter.config;
		config.sort();

		for (ConfigElement element : config.getConfigElements()) {
			if (element.disabled) continue;
			engineConfig.setSystem(element.provider.create(engineConfig, context, data));
		}

		cameraManager = engineConfig.getSystem(CameraManager.class);

		if (parameter.respectScenePhysicsSettings) {
			if (data.physicsSettings.physicsEnabled) {
				config.enable(SceneFeatureGroup.PHYSICS);
			} else {
				config.disable(SceneFeatureGroup.PHYSICS);
			}
		}

		for (EntitySupport support : context.supports) {
			support.registerSystems(runtimeConfig, engineConfig, assetsManager);
		}

		engine = new EntityEngine(engineConfig);
	}

	/**
	 * Finishes loading scene and inflate all entities. This must be called manually if scene wasn't loaded
	 * using {@link VisAssetManager} loadSceneNow methods.
	 */
	public void init () {
		engine.setInvocationStrategy(new BootstrapInvocationStrategy());
		engine.process();
		engine.setInvocationStrategy(new InvocationStrategy());

		for (BaseSystem system : engine.getSystems()) {
			if (system instanceof AfterSceneInit) {
				((AfterSceneInit) system).afterSceneInit();
			}
		}
	}

	/** Updates and renders entire scene. Typically called from {@link ApplicationListener#render()} */
	public void render () {
		engine.setDelta(Math.min(Gdx.graphics.getDeltaTime(), 1 / 60f));
		engine.process();
	}

	/** Must by called when screen was resized. Typically called from {@link ApplicationListener#resize(int, int)} */
	public void resize (int width, int height) {
		cameraManager.resize(width, height);
	}

	public Array<LayerData> getLayerData () {
		return layerData;
	}

	public LayerData getLayerDataByName (String name) {
		for (LayerData data : layerData) {
			if (data.name.equals(name)) return data;
		}

		return null;
	}

	public EntityEngine getEntityEngine () {
		return engine;
	}
}

@@ -2282,24 +2282,232 @@
 ig.sort();%0A%0A
+%09%09if (parameter.respectScenePhysicsSettings) %7B%0A%09%09%09if (data.physicsSettings.physicsEnabled) %7B%0A%09%09%09%09config.enable(SceneFeatureGroup.PHYSICS);%0A%09%09%09%7D else %7B%0A%09%09%09%09config.disable(SceneFeatureGroup.PHYSICS);%0A%09%09%09%7D%0A%09%09%7D%0A%0A
 %09%09for (Confi
@@ -2744,216 +2744,8 @@
 );%0A%0A
-%09%09if (parameter.respectScenePhysicsSettings) %7B%0A%09%09%09if (data.physicsSettings.physicsEnabled) %7B%0A%09%09%09%09config.enable(SceneFeatureGroup.PHYSICS);%0A%09%09%09%7D else %7B%0A%09%09%09%09config.disable(SceneFeatureGroup.PHYSICS);%0A%09%09%09%7D%0A%09%09%7D%0A%0A
 %09%09fo

Fix physics enabling