use Lattice::events::Events;
use Lattice::view::View;
use ::view::{GameView, Home, Memorial, NewGame, LoadGame, GameHome};
use ::controller::{GameControl};
use ::time;
use ::agent::{Class};
use std::sync::{Mutex};
use std::ops::{DerefMut};

lazy_static! {
    pub static ref GAME_CONTROL: Mutex<GameControl> = Mutex::new( GameControl::new_null() );
}

pub struct GameState {
   view: GameView,
}
impl GameState {
   pub fn new() -> GameState {
      GameState {
         view: GameView::new(),
      }
   }
   pub fn cycle(s: f64, u: u64) -> usize 

   pub fn next_frame(&mut self, events: &mut Events) -> View {
      self.view.new_frame();

      {
         let mut gmc = GAME_CONTROL.lock().unwrap();
         let mut new_game = None;

         {
            let ref mut gm = gmc.deref_mut();
            let ref friend = gm.target_friend;
            let ref mut map = gm.map;

            for msg in events.messages.iter() {
               if msg[0].as_str() == "view" {
                  self.view.message(msg);
               } else if msg[0].as_str() == "control" && msg[1].as_str()=="transition" {
                  if msg[2].as_str()=="home" {
                     self.view = GameView::Home(Home::new());
                  } else if msg[2].as_str()=="new_game" {
                     self.view = GameView::NewGame(NewGame::new());
                  } else if msg[2].as_str()=="load_game" {
                     self.view = GameView::LoadGame(LoadGame::new());
                  } else if msg[2].as_str()=="you_died" {
                     self.view = GameView::Memorial(Memorial::new());
                  } else if msg[2].as_str()=="game_home" && msg[3].as_str()=="new" {
                     let class = Class::from_string(msg[4].as_str());
                     new_game = Some(GameControl::new(class));
                     self.view = GameView::GameHome(GameHome::new());
                  } else {
                     panic!("Unexpected screen transition: {}", msg[2]);
                  }
               } else if msg[0].as_str() == "control" && msg[1].as_str()=="plan" {
                  let dst: Vec<&str> = msg[2].split(",").collect();
                  let dst_x = dst[0].parse::<i64>().expect("i64");
                  let dst_y = dst[1].parse::<i64>().expect("i64");
                  map.plan(friend, dst_x, dst_y);
               }
            }
            events.messages.clear();
         }

         if let Some(ng) = new_game {
            *gmc = ng;
         }

         {
            let ref mut gm = gmc.deref_mut();
            gm.step();
         }
      }

      self.view.render()
   }
}

{
       (((time::precise_time_s().abs()/s) as u64) % u) as usize
   }