#line 742 "/home/travis/build/felix-lang/felix/src/packages/gui.fdoc"
  class FlxGuiWindowManager
  {
  // Window Manager is responsible for a set of windows,
  // and dispatching events specific to a particular
  // window to that window.
  
  // ------------------------------------------------------------------
  object window_manager () =
  {
    var windows = darray[window_controller_interface]();
  
    method fun get_n_windows () => windows.len.int;
  
    // add a new window to the controlled set
    // return its current index
    method gen add_window (w:window_controller_interface) : int =
    {
      windows += w;
      return windows.len.int - 1;
    }
  
    fun find_window(wid: uint32) : opt[window_controller_interface] =
    {
      for wobj in windows do
        if wid == #(wobj.get_window_id) return Some wobj;
      done
      return None[window_controller_interface];
    }
  
    fun find_window_index (wid: uint32) : opt[int] =
    {
      for var i in 0 upto windows.len.int - 1 do
        if wid == #(windows.i.get_window_id) return Some i;
      done
      return None[int];
    }
  
    method fun get_window_controller_from_index (i:int) => windows.i;
  
    method proc delete_window (wid: uint32)
    {
      match find_window_index wid with
      | #None => ;
      | Some i =>
        println$ "delete window found index " + i.str;
        windows.i.destroy_window ();
        println$ "SDL destroyed";
        erase (windows, i);
        println$ "Window erased";
      endmatch;
    }
  
    // this is a global source for all events
    gen create_event_source () : ischannel[event_t]  =
    {
      var imsgs,omsgs = #mk_ioschannel_pair[SDL_Event];
      proc driver ()
      {
        var e : SDL_Event;
        // dummy first event
        e.type = SDL_FIRSTEVENT.uint32;
        write$ omsgs,e;
        SDL_PumpEvents;
        C_hack::ignore$ SDL_WaitEvent$ &e;
        while e.type.SDL_EventType != SDL_QUIT do
          write$ omsgs, e;
          SDL_PumpEvents;
          C_hack::ignore$ SDL_WaitEvent$ &e;
        done
        println$ "SDL_QUIT seen!";
        write$ omsgs, e;
        return;
      }
      spawn_fthread driver;
      return imsgs;
    }
  
    var imsgs = create_event_source ();
    method fun get_event_source () => imsgs;
    method proc dispatch_window_event (e:event_t)
    {
      match SDL_GetWindowID e with
      | Some wid =>
        match find_window wid with
        | Some wobj =>
          var omsgs = #(wobj.get_oschannel);
          write (omsgs, e);
          if e.type.SDL_EventType == SDL_WINDOWEVENT and
            e.window.event.SDL_WindowEventID == SDL_WINDOWEVENT_CLOSE
          do
            #(wobj.get_window_id).delete_window;
            println$ "dispatch: window deleted!";
          else
            wobj.display();
          done
          | #None => println$ "Can't find window ID = " + str wid;
          endmatch;
        | #None => println$ "No window for message: Event type " + e.type.SDL_EventType.str;
        endmatch;
    }
  
    method proc delete_all()
    {
      println$ "Delete all";
      var e : SDL_Event;
      e.type = SDL_WINDOWEVENT.uint32;
      e.window.event = SDL_WINDOWEVENT_CLOSE.uint8;
      for wobj in windows do
        var omsgs = #(wobj.get_oschannel);
        e.window.windowID = #(wobj.get_window_id);
        //write (omsgs, e);
      done
      // note: not bothering to delete the darray :)
    }
  }
  
  }