------------------------------------------------
-- ScenarioScript.lua
-- 01/20/2013
--
-- Serg Zjuzin
--
-- Scenario universal script

-- for Train Simulator 2013 
------------------------------------------------

-- true/false defn
FALSE = 0
TRUE = 1

-- condition return values
CONDITION_NOT_YET_MET = 0
CONDITION_SUCCEEDED = 1
CONDITION_FAILED = 2

-- Message types
MT_INFO = 0			-- large centre screen pop up
MT_ALERT = 1		        -- top right alert message

MSG_TOP = 1
MSG_VCENTRE = 2
MSG_BOTTOM = 4
MSG_LEFT = 8
MSG_CENTRE = 16
MSG_RIGHT = 32

MSG_SMALL = 0
MSG_REG = 1
MSG_LRG = 2

DEBUG = nil  -- Debug and trace flag = nil to disable this mode

------------------------------------------------
-- Fn OnEvent
-- 		event - name of the event
--	    return - TRUE/FALSE if event handled
function OnEvent ( event )
---------------------------

  -- Chain of events
  ---------------------------

  local j, k, current_event, chain_event, time_next_event;
  
  j = string.find (event, "+", 1, TRUE) or 0;
  if j > 0 then
    -- Event includes chain
    if j > 1 then
      -- First event exist
      current_event = string.sub (event, 1, j - 1);
    else
      -- First event is empty
      current_event = "";
    end
    chain_event = string.sub (event, j + 1);
                           
    k = string.find (chain_event, "+", 1, TRUE) or 0;
    if k > 0 then      
      -- If next element of chain - time until next event
      time_next_event = tonumber (string.sub (chain_event, 1, k - 1));
      if time_next_event == nil then
        -- Time  by default until next event
        time_next_event = 0.1;
      else
        -- Time specified until next event
        chain_event = string.sub (chain_event, k + 1);
      end
    else
      -- Time  by default until next event
      time_next_event = 0.1;
    end
                 
    -- Shedule for next event
    SysCall("ScenarioManager:TriggerDeferredEvent", chain_event, time_next_event);
  else
    -- Last event in chain
    current_event = event;
  end                  
                            
  if (current_event == "") then
    -- Empty event
    return TRUE;
  end
	
  -- Predefined commands
  ---------------------------
               
  if current_event == "lock" then
    -- Lock control
    SysCall("ScenarioManager:LockControls");
    return TRUE;
  end
               
  if current_event == "unlock" then
    -- Unlock control
    SysCall("ScenarioManager:UnlockControls");
    return TRUE;
  end
                 
  if current_event == "stop" then
    -- Apply emergency brake
    SysCall("PlayerEngine:SetControlValue", "EmergencyBrake", 0, 1);
    return TRUE;
  end
                  
  if current_event == "halt" then
    -- Apply engine shutdown
    SysCall("PlayerEngine:SetControlValue", "Startup", 0, -1);
    return TRUE;
  end
                      
  if current_event == "cab" then
    -- Activate cab camera		
    SysCall("CameraManager:ActivateCamera", "CabCamera", 0);
    return TRUE;
  end
                           
  if current_event == "break" then
    -- Job failed - abort scenario
    SysCall("ScenarioManager:TriggerScenarioFailure", nil);
    return TRUE;
  end

  if current_event == "debug" then
    -- Debugging mode is now enabled
    DEBUG = 1;
    return TRUE;
  end

  if current_event == "nodebug" then
    -- Debugging mode is now disabled
    DEBUG = nil;
    return TRUE;
  end
                    
  -- Parse commands
  ---------------------------
  local command, command_id, command_name, control_value;
  command_id = string.sub(current_event, 1, 3);
  j = string.find (current_event, "=", 1, TRUE) or 0;
  if j > 5 then
    -- Control value defined
    control_value, command_name, command = tonumber (string.sub (current_event, j + 1)) or 0, string.sub (current_event, 4, j - 1), string.sub (current_event, 1, j - 1);
  else
    -- Control value not defined
    control_value, command_name, command = 0, string.sub (current_event, 4), current_event;    
  end

  if DEBUG then
    SysCall("ScenarioManager:ShowMessage", "Debbug message:", string.format("command=%q\nid=%q name=%q\ncontrol=%d\neng=%s msg=%s cam=%s wet=%s", command, command_id, command_name, control_value, tostring(command_id == "eng"), tostring(string.sub(command_id, 1, 1) == "m"), tostring(command_id == "cam"), tostring(command_id == "wet")), MT_INFO);
  end;  
                                             
  -- PlayerEngine commands
  ---------------------------
  if command_id == "eng" then
    -- SetControlValue command		
    if DEBUG then
      SysCall("ScenarioManager:ShowMessage", "Debbug message:", string.format("SysCall(\"PlayerEngine:SetControlValue\", %q, 0, %d)", command_name, control_value), MT_INFO);
    end;
    SysCall("PlayerEngine:SetControlValue", command_name, 0, control_value);
    return TRUE;
  end 
                    
  -- Pop up message commands
  ---------------------------
  local htmlfile, frame_dim, pause_mode_flag;
  if string.sub(command_id, 1, 1) == "m" then
    -- Pop up message command
    if string.sub(command_id, 2, 2) == "l" then
      -- Large dimension frame
      frame_dim = MSG_LRG;
    elseif string.sub(command_id, 2, 2) == "r" then
      -- Middle dimension frame
      frame_dim = MSG_REG;
    else
      -- Small dimension frame
      frame_dim = MSG_SMALL;
    end
    if string.sub(command_id, 3, 3) == "p" then
      -- Pause mode
      pause_mode_flag = TRUE;
    else
      -- No pause mode
      pause_mode_flag = FALSE;
    end
                 
    if control_value < 15 then
      -- Minimal time of show message 15s
      control_value = 15;
    end
                    
    -- Html file name = command_(id + name) + '.html'
    htmlfile = command .. ".html";
    -- Frame on screen position - always top right corner
    if DEBUG then
      SysCall("ScenarioManager:ShowMessage", "Debbug message:", string.format("SysCall(\"ScenarioManager:ShowInfoMessageExt\", nil, %q, %d, MSG_RIGHT + MSG_TOP, %d, %d)", htmlfile, control_value, frame_dim, pause_mode_flag), MT_INFO);
    else  
      SysCall("ScenarioManager:ShowInfoMessageExt", nil, htmlfile, control_value, MSG_RIGHT + MSG_TOP, frame_dim, pause_mode_flag);
    end;
    return TRUE;
  end
                   
  -- Camera control commands
  ---------------------------
  if command_id == "cam" then
    -- Activate specified camera		
    if DEBUG then
      SysCall("ScenarioManager:ShowMessage", "Debbug message:", string.format("SysCall(\"CameraManager:ActivateCamera\", %q, %d)", command_name, control_value), MT_INFO);
    end;
    SysCall("CameraManager:ActivateCamera", command_name, control_value);
    return TRUE;
  end 
                           
  -- Weather control commands
  ---------------------------
  if command_id == "wet" then
    -- Run specified weather phenomenon		
    if DEBUG then
      SysCall("ScenarioManager:ShowMessage", "Debbug message:", string.format("SysCall(\"WeatherController:SetCurrentWeatherEventChain\", %q)", command_name), MT_INFO);
    end;
    SysCall("WeatherController:SetCurrentWeatherEventChain", command_name);
    return TRUE;
  end

  if DEBUG then SysCall("ScenarioManager:ShowMessage", "Debbug message:", string.format("Event=%q not handled.", current_event), MT_INFO); end
                      
  -- Unknown event - not handled
  return FALSE;
end
