function [sys,x0,str,ts]=SimSpeed(t,x,u,flag,sampleTime,simulationSpeed)

% Control the simulation speed

% 2005.09.09 ESR Created
%
% Parameters:
%   sampleTime
%   simulationSpeed
%
% Inputs:
%   (none)
%
% Outputs:
%   - actual simulation speed (*real time)
%   - status flag (0: ok, 1: sim speed not achieved)
%   - correction factor for setting time to sleep
%
% States
%   x(1:6)   - date vector prev step, [year month day hour minute seconds]
%   x(7)     - 1st output, i.e. actual simulation speed (*real time)
%   x(8)     - 2nd output, i.e. status flag
%   x(9)     - 3rd output (and internal value), i.e. time to sleep
%   x(10)    - sim time prev step
%
% Assumptions:
%   - simulation start time is 0.

switch flag,
  case 0         
    [sys,x0,str,ts] = mdlInitializeSizes(sampleTime,simulationSpeed); % Initialization
  case 2
    sys = mdlUpdate(t,x,sampleTime,simulationSpeed);
  case 3
    sys = mdlOutputs(t,x);  % Calculate outputs
  case {1,4}
    sys = []; % do nothing
  case 9
    delete(timerfind('Tag','EOPSimulationSpeedTimer'));
    sys = []; % do nothing
otherwise
    error(['unhandled flag = ',num2str(flag)]);
end

%=============================================================================
% mdlInitializeSizes
% Return the sizes, initial conditions, and sample times for the S-function.
%=============================================================================
%
function [sys,x0,str,ts] = mdlInitializeSizes(sampleTime,simulationSpeed)

sizes = simsizes;
sizes.NumContStates  = 0;
sizes.NumDiscStates  = 10; % time stamp (6 elements) + 3 outputs + 1 internal
sizes.NumOutputs     = 3;  % calc speed, flag (0: ok, 1: sim speed not achieved), time to sleep
sizes.NumInputs      = 0;
sizes.DirFeedthrough = 0;
sizes.NumSampleTimes = 1;
sys = simsizes(sizes);

str = [];

rTimeNow = clock; % -> 6 element date vector, i.e.:
                %    [year month day hour minute seconds] in decimal form.
                %    "year".."minute" are integers. "seconds" is accurate
                %    to several digits beyond the decimal point.
simFlag    = 0;
x0         = [rTimeNow simulationSpeed simFlag 0 0];
ts         = [sampleTime 0];   % sample time: [period, offset]

currSys=strtok(gcs,'/');
delete(timerfind('Tag','EOPSimulationSpeedTimer'));
Tmr=timer('Tag','EOPSimulationSpeedTimer',...
    'StartFcn',  ['set_param(''' currSys ''',''SimulationCommand'',''pause'')'],...
    'StartDelay',1,...
    'TimerFcn',  ';',...
    'StopFcn',   ['set_param(''' currSys ''',''SimulationCommand'',''continue'')']);

%=============================================================================
% mdlUpdate
% 
%=============================================================================
function sys=mdlUpdate(t,x,sampleTime,simulationSpeed)

deadb=0.1; % fraction of sample time

rTimeNow    = clock;
%--disp(['min: ' num2str(rTimeNow(5)) ', sec: ' num2str(rTimeNow(6))]);
actSimSpeed = x(7);
simFlag     = 0;
simTNow     = t;
tToSleep    = 0;
%--disp(['mdlUpdate, t: ' num2str(t)])
if t > 0,
    corrFactorFltr = 0.1;
    rTimeThen    = [x(1)  x(2)  x(3)  x(4)  x(5)  x(6)];
    tToSleep     = x(9);
    simTThen     = x(10);
    deltaSimT    = simTNow - simTThen;
    deltaRTime   = etime(rTimeNow,rTimeThen);
    if deltaRTime > 0,
        calcSimSpeed  = deltaSimT/deltaRTime;
    else
        calcSimSpeed=inf;
    end
    if calcSimSpeed < 2*simulationSpeed,
        actSimSpeed=calcSimSpeed;
    end
    tAdjust      = deltaSimT/simulationSpeed - deltaRTime;
    tToSleep     = tToSleep + tAdjust;
    tToSleep     = floor(1000*tToSleep)/1000; % limit to a resolution of 1 ms

    if tToSleep > 0,
        Tmr = timerfind('Tag','EOPSimulationSpeedTimer');
        set(Tmr,'StartDelay',tToSleep);
        start(Tmr);
        wait(Tmr);
    else
        simFlag  = 1;
        disp([ 't= ' num2str(t) ': could not achieve specified speed! tToSleep: ' num2str(tToSleep)]);
    end
end

sys = [rTimeNow actSimSpeed simFlag tToSleep simTNow];


%=============================================================================
% mdlOutputs
% 
%=============================================================================
function sys = mdlOutputs(t,x)
%disp(['mdlOutputs, t: ' num2str(t)]);
    sys = x(7:9);
   
