using System;
using System.Collections.Generic;
using System.Text;
using IrrlichtNetSwig;

namespace LoadIrrFile
{
    class Program
    {
        static void Main(string[] args)
        {

            E_DRIVER_TYPE driverType;

            Console.WriteLine(
                @"Please select the driver you want for this example:
(a) Direct3D 9.0c
(b) Direct3D 8.1
(c) OpenGL 1.5
(d) Software Renderer
(e) Burning's Software Renderer
(f) NullDevice
(otherKey) exit");

            var keyInfo = Console.ReadKey(true);

            switch (keyInfo.KeyChar)
            {
                case 'a':
                    driverType = E_DRIVER_TYPE.EDT_DIRECT3D9;
                    break;
                case 'b':
                    driverType = E_DRIVER_TYPE.EDT_DIRECT3D8;
                    break;
                case 'c':
                    driverType = E_DRIVER_TYPE.EDT_OPENGL;
                    break;
                case 'd':
                    driverType = E_DRIVER_TYPE.EDT_SOFTWARE;
                    break;
                case 'e':
                    driverType = E_DRIVER_TYPE.EDT_BURNINGSVIDEO;
                    break;
                case 'f':
                    driverType = E_DRIVER_TYPE.EDT_NULL;
                    break;
                default:
                    return;
            }

            // create device and exit if creation failed

            IrrlichtDevice device =
                IrrlichtNet.createDevice(driverType, new dimension2di(640, 480));

            if (device == null)
                return; // could not create selected driver.

            device.setWindowCaption("Load .irr file example");

            IVideoDriver driver = device.getVideoDriver();
            ISceneManager smgr = device.getSceneManager();

            /*
            Now load our .irr file.
            .irr files can store the whole scene graph including animators,
            materials and particle systems. And there is also the possibility to
            store arbitrary user data for every scene node in that file. To keep
            this example simple, we are simply loading the scene here. See the
            documentation at ISceneManager::loadScene and ISceneManager::saveScene
            for more information. So to load and display a complicated huge scene,
            we only need a single call to loadScene().
            */

            // load the scene
            smgr.loadScene("../../media/example.irr");

            /*
            Now we'll create a camera, and give it a collision response animator
            that's built from the mesh nodes in the scene we just loaded.
            */
            ICameraSceneNode camera = smgr.addCameraSceneNodeFPS(null, 50.0f, 0.1f);

            // Create a meta triangle selector to hold several triangle selectors.
            IMetaTriangleSelector meta = smgr.createMetaTriangleSelector();

            /*
            Now we will find all the nodes in the scene and create triangle
            selectors for all suitable nodes.  Typically, you would want to make a
            more informed decision about which nodes to performs collision checks
            on; you could capture that information in the node name or Id.
            */
            arraySceneNode nodes = new arraySceneNode();
            smgr.getSceneNodesFromType((int) ESCENE_NODE_TYPE.ESNT_ANY, nodes); // Find all nodes

            for (uint i = 0; i < nodes.size(); ++i)
            {
                ISceneNode node = nodes.getItem(i);
                ITriangleSelector selector = null;

                switch (node.getType())
                {
                    case (int)ESCENE_NODE_TYPE.ESNT_CUBE:
                    case (int)ESCENE_NODE_TYPE.ESNT_ANIMATED_MESH:
                        // Because the selector won't animate with the mesh,
                        // and is only being used for camera collision, we'll just use an approximate
                        // bounding box instead of ((IAnimatedMeshSceneNode)node).getMesh(0)
                        selector = smgr.createTriangleSelectorFromBoundingBox(node);
                        break;

                    case (int)ESCENE_NODE_TYPE.ESNT_MESH:
                    case (int)ESCENE_NODE_TYPE.ESNT_SPHERE: // Derived from IMeshSceneNode

                        selector = smgr.createTriangleSelector(IMeshSceneNode.cast(node).getMesh(), node);
                        break;

                    case (int)ESCENE_NODE_TYPE.ESNT_TERRAIN:
                        selector = smgr.createTerrainTriangleSelector(ITerrainSceneNode.cast(node));
                        break;

                    case (int)ESCENE_NODE_TYPE.ESNT_OCT_TREE:
                        selector = smgr.createOctTreeTriangleSelector(IMeshSceneNode.cast(node).getMesh(), node);
                        break;

                    default:
                        // Don't create a selector for this node type
                        break;
                }

                if (selector != null)
                {
                    // Add it to the meta selector, which will take a reference to it
                    meta.addTriangleSelector(selector);
                    // And drop my reference to it, so that the meta selector owns it.
                    selector.drop();
                }
            }

            /*
            Now that the mesh scene nodes have had triangle selectors created and added
            to the meta selector, create a collision response animator from that meta selector.
            */
            ISceneNodeAnimator anim = smgr.createCollisionResponseAnimator(
                meta, camera, new vector3df(5, 5, 5),
                new vector3df(0, 0, 0));
            meta.drop(); // I'm done with the meta selector now

            camera.addAnimator(anim);
            anim.drop(); // I'm done with the animator now

            // And set the camera position so that it doesn't start off stuck in the geometry
            camera.setPosition(new vector3df(0.0f, 20.0f, 0.0f));

            // Point the camera at the cube node, by finding the first node of type ESNT_CUBE
            ISceneNode cube = smgr.getSceneNodeFromType((int) ESCENE_NODE_TYPE.ESNT_CUBE);
            if (cube != null)
                camera.setTarget(cube.getAbsolutePosition());

            /*
            That's it. Draw everything and finish as usual.
            */

            int lastFPS = -1;

            while (device.run())
                if (device.isWindowActive())
                {
                    driver.beginScene(true, true, new SColor(0, 200, 200, 200));
                    smgr.drawAll();
                    driver.endScene();

                    int fps = driver.getFPS();

                    if (lastFPS != fps)
                    {
                        string str = "Load Irrlicht File example - Irrlicht Engine [";
                        str += driver.getName();
                        str += "] FPS:";
                        str += fps;

                        device.setWindowCaption(str);
                        lastFPS = fps;
                    }

                }

            device.drop();

            return;
        }
    }
}
