context: using System;
  using System.IO;
  using System.Collections.Generic;
  using System.Linq;
  using Microsoft.Xna.Framework;
  using Microsoft.Xna.Framework.Audio;
  using Microsoft.Xna.Framework.Content;
  using Microsoft.Xna.Framework.GamerServices;
  using Microsoft.Xna.Framework.Graphics;
  using Microsoft.Xna.Framework.Input;
  using Microsoft.Xna.Framework.Media;
  using Microsoft.Xna.Framework.Net;
  using Microsoft.Xna.Framework.Storage;
  using WiiApi.Tracking3d;
  using WiiApi;
  
  namespace Caliibrator
  {
      /// <summary>
      /// Glavna klasa kalibratora.
      /// </summary>
      public class CalibrationMain : Microsoft.Xna.Framework.Game
      {
          //Osnovne klase, za iscrtavanje
          GraphicsDeviceManager graphics;
          SpriteBatch spriteBatch;
          SpriteFont font;
          SpriteFont helpFont;
  
          public Camera camera { get; protected set; }
          ModelManager modelManager;
          Grid grid;
  
          private String message = ""; //sta se iscrtava na ekranu
          private String helpMessage = @"
                              HELP               
                  * W => povezi wii kontroler
                  * K => raskini vezu sa kontrolerom
                  * + => povecaj prag filtriranja za 1
                  * - => smani prag filtriranja za 1
                  * F => ukljuci filter
                  * U => iskljuci filter
                  * C => ukljuci postavljenu kalibraciju
                  * R => resetuj kalibraciju
                  * Levo, desno, gore, dole => postavi levu, 
                  * desnu, donju odn. gornju granicu na 
                  * trenutni polozaj markera
                  * Page up, page down => postavlja najudaljeniju 
                  * odn. najblizu granicu na trenutni polozaj ";//pomoc
  
          public Kontroler wLeft;
          public Kontroler wRight;
          public Tracker3d tracker;
  
          public bool connected {get; set;}
          public bool wiimode { get; set; }
  
          public Vector3 wiipos1 { get; set; }
          public Vector3 wiipos2 { get; set; }
  
          float minX = 0;
          float maxX = 1;
          float minY = 0;
          float maxY = 1;
          float minZ = 1.5f;
          float maxZ = 10;
  
          private bool calibrateMinX = false;
          private bool calibrateMaxX = false;
          private bool calibrateMinY = false;
          private bool calibrateMaxY = false;
          private bool calibrateMinZ = false;
          private bool calibrateMaxZ = false;
  
          private bool calibrated = false;
  
          private bool help = false;
  
          private delegate void Obrada(ParametriDogadjaja p);
  
          private bool dofilter = false;
  
          
  
          public CalibrationMain()
          {
              graphics = new GraphicsDeviceManager(this);
              Content.RootDirectory = "Content";
              connected = false;
              //tw = new StreamWriter("save.txt");
          }
  
          public Vector3 getCalibrationMinimum()
          {
              return new Vector3(minX, minY, minZ);
          }
  
          public Vector3 getCalibrationMaximum()
          {
              return new Vector3(maxX, maxY, maxZ);
          }
  
          /// <summary>
          /// Allows the game to perform any initialization it needs to before starting to run.
          /// This is where it can query for any required services and load any non-graphic
          /// related content.  Calling base.Initialize will enumerate through any components
          /// and initialize them as well.
          /// </summary>
          protected override void Initialize()
          {
              // TODO: Add your initialization logic here
              camera = new Camera(this, new Vector3(0, 0, 250),Vector3.Zero, Vector3.Up);
              Components.Add(camera);
  
              modelManager = new ModelManager(this);
              Components.Add(modelManager);
  
              grid = new Grid(this, camera);
              grid.Visible = true;
              grid.GridX = 256;
              grid.GridY = 256;
              grid.Spacing = 32.0f;
              grid.Position = new Vector3(0, -100, -25);
              grid.Rotation = Vector3.Zero;
              Components.Add(grid);
  
              wiipos1 = new Vector3();
              wiipos2 = new Vector3();
  
              base.Initialize();
          }
  
          /// <summary>
          /// LoadContent will be called once per game and is the place to load
          /// all of your content.
          /// </summary>
          protected override void LoadContent()
          {
              // Create a new SpriteBatch, which can be used to draw textures.
              spriteBatch = new SpriteBatch(GraphicsDevice);
  
              font = Content.Load<SpriteFont>(@"fonts\arial");
              helpFont = Content.Load<SpriteFont>(@"fonts\helpfont");
  
              // TODO: use this.Content to load your game content here
          }
  
          /// <summary>
          /// UnloadContent will be called once per game and is the place to unload
          /// all content.
          /// </summary>
          protected override void UnloadContent()
          {
              // TODO: Unload any non ContentManager content here
          }
  
          /// <summary>
          /// Allows the game to run logic such as updating the world,
          /// checking for collisions, gathering input, and playing audio.
          /// </summary>
          /// <param name="gameTime">Provides a snapshot of timing values.</param>
          protected override void Update(GameTime gameTime)
          {
              // Allows the game to exit
              if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                  this.Exit();
  
              /*
                  * W => povezi wii kontroler
                  * K => raskini vezu sa kontrolerom
                  * + => povecaj prag filtriranja za 1
                  * - => smani prag filtriranja za 1
                  * F => ukljuci filter
                  * U => iskljuci filter
                  * C => ukljuci postavljenu kalibraciju
                  * R => resetuj kalibraciju
                  * Levo, desno, gore, dole => postavi levu, desnu, donju 
                  * odn. gornju granicu na trenutni polozaj markera
                  * Page up, page down => postavlja najudaljeniju 
                  * odn. najblizu granicu na trenutni polozaj 
               */
  
              if (Keyboard.GetState().IsKeyDown(Keys.W))
              {
                  connect();
              }
  
              if (Keyboard.GetState().IsKeyDown(Keys.K))
              {
                  wiimode = false;
              }
  
              if (Keyboard.GetState().IsKeyDown(Keys.Add))
              {
                  tracker.FILTERING_THRESHOLD += 1.0f;
  
              }
  
              if (Keyboard.GetState().IsKeyDown(Keys.Subtract))
              {
                  tracker.FILTERING_THRESHOLD -= 1.0f;
                  if (tracker.FILTERING_THRESHOLD < 0)
                  {
                      tracker.FILTERING_THRESHOLD = 0;
                  }
              }
  
              if (Keyboard.GetState().IsKeyDown(Keys.F))
              {
                  dofilter = true;
                  tracker.clearHistory();
              }
  
              if (Keyboard.GetState().IsKeyDown(Keys.U))
              {
                  dofilter = false;
              }
  
              if (Keyboard.GetState().IsKeyDown(Keys.S))
              {
                  //SAVE CALIBRATION DATA
                  FileStream f = File.Open("save.txt", FileMode.Create);
                  TextWriter tw = new StreamWriter(f);
                  tw.WriteLine(minX);
                  tw.WriteLine(maxX);
                  tw.WriteLine(minY);
                  tw.WriteLine(maxY);
                  tw.WriteLine(minZ);
                  tw.WriteLine(maxZ);
                  tw.Close();
              }
  
              if (Keyboard.GetState().IsKeyDown(Keys.L))
              {
                  TextReader tr = new StreamReader("save.txt");
                  String s = tr.ReadLine();
                  minX = float.Parse(s);
                  s = tr.ReadLine();
                  maxX = float.Parse(s);
                  s = tr.ReadLine();
                  minY = float.Parse(s);
                  s = tr.ReadLine();
                  maxY = float.Parse(s);
                  s = tr.ReadLine();
  
gt:                 minZ = float.Parse(s);