import net.sf.jirr.*;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.*;

public class EngineManager 
{
  static protected int READ_BUFFER_SIZE = 1000;
  static protected EngineManager instance = null;
  protected IrrlichtDevice device = null;
  protected boolean running = true;
  protected String filename;
  
  static public EngineManager getInstance()
  {
    if (instance == null)
      instance = new EngineManager();
    return instance;
  }
  
  public IrrlichtDevice getDevice()
  {
    return device;
  }
  
  public ISceneManager getSceneManager()
  {
    return device.getSceneManager();
  }
  
  public IVideoDriver getVideoDriver()
  {
    return device.getVideoDriver();
  }
  
  public IGUIEnvironment getGuiEnvironment()
  {
    return device.getGUIEnvironment();
  }
  
  protected EngineManager()
  {
    
  }
  
  public void startupEngineManager(String caption)
  {
    // create the Irrlicht device
    device = Jirr.createDevice(E_DRIVER_TYPE.EDT_DIRECT3D9, new dimension2di(600400)16 );
    // set the window title
    device.setWindowCaption(caption);
    // add a camer to the scene
    device.getSceneManager().addCameraSceneNode(null, new vector3df(0,0,-50)new vector3df(0,0,0));
    // load a font and set it as the default
    IGUISkin skin = getGuiEnvironment().getSkin();
        IGUIFont font = getGuiEnvironment().getFont("fonthaettenschweiler.bmp");
        if (font != null
          skin.setFont(font);
        
        loadResources();
  }
  
  protected void loadResources()
  {
    try
    {
      // The EngineManager assumes that there is a file called media.zip, either in the
      // JAR file downloaded via Webstart, or just in the current working directory.
      // Webstart doesn't allow you to know the name of the local JAR filename in the cache,
      // but we can get access to the media.zip file easily enough with a call to 
      // getResourceAsStream. Once we get access to that file stream we can copy
      // the media.zip file out into a known temporary location and give Irrlicht 
      // access to it there.
      
      // get the file stream (should be null for a local app, and not null for a webstart app)
      InputStream in = this.getClass().getResourceAsStream("media.zip");
          if (in != null)
          {
            // find a unique temporary file name 
            int i = 0;
            String tempDir = System.getProperty("java.io.tmpdir");
            File file = null;
            do 
            {
              ++i;
              file = new File(tempDir + "media" + i + ".zip");
            while (file.exists());
            
            // write the output file
            filename = file.getPath();
            OutputStream out = new FileOutputStream(filename);
            int c;
            byte[] buffer = new byte[READ_BUFFER_SIZE];
              while ((c = in.read(buffer)) != -1)
              {
                  out.write(buffer, 0, c);
              }
              in.close();
              out.close();
            
            System.out.println("addZipFileArchive: " + file);
            device.getFileSystem().addZipFileArchive(file.getPath());
          }
          else
          {
          // otherwise assume there is a file called media.zip
            System.out.println("addZipFileArchive: media.zip");
            device.getFileSystem().addZipFileArchive("media.zip");
          }
    }
    catch (Exception ex)
    {
      
    }
  }
  
  public void shutdown()
  {
    // clean up the Irrlicht engine
    device.drop();
    device = null;
    
    // clean up the temporary file
    if (filename != null)
    {
      File file = new File(filename);
      file.delete();
    }
  }
  
  public void stopGameLoop()
  {
    running = false;
  }
  
  public void enterGameLoop()
  {
    while (device.run() && running)
    {
      // begin the scene
      device.getVideoDriver().beginScene(true, true, new SColor(255,100,101,140));
      // draw the scene
      device.getSceneManager().drawAll();
      // draw the GUI
      device.getGUIEnvironment().drawAll();
      // end the scene
      device.getVideoDriver().endScene();
    }
  }
}