function varargout = createData(key)
% CREATE DATA create data

% EVALUATE THE KEY
if ischar(key)
  key = eval(key);
end

% FIGURE OUT WHAT THE NEEDED FUNCTIONS ARE
stepfun = eval(['@',key.prefix,'_step_gen']);
measfun = eval(['@',key.prefix,'_meas_gen']);
icfun = eval(['@',key.prefix,'_ics']);

% CREATE THE INPUT
for i = 1:numel(key.inputcreate)
  [inp(:,i),time] = key.inputcreate{i}(...
                  key.inputparams(i),key.time.oneDT,key.time.TMAX);
end

% CREATE THE NOISE
randn('state',key.seed);
process_noise = randn(numel(time),numel(key.noise.process));
measurement_noise = randn(numel(time),numel(key.noise.measurement));

% INITIALIZE THE STATE
state = zeros(numel(time),numel(fieldnames(key.state)));
[temp,state(1,:)] = icfun();

% INITIALIZE THE MEASUREMENTS
meas1 = measfun(state(1,:),inp(1,:),measurement_noise(1,:));
meas = zeros(numel(time),numel(meas1));
meas(1,:) = meas1;

% SIMULATE THE MODEL
if isempty(key.debug)
  for k = 2:numel(time)
    state(k,:) = stepfun(state(k-1,:),inp(k-1,:),process_noise(k-1,:));
    meas(k,:) = measfun(state(k,:),inp(k,:),measurement_noise(k,:));
  end
else
  for k = 2:numel(time)
    [state(k,:),dbg(k,:)] = ...
                stepfun(state(k-1,:),inp(k-1,:),process_noise(k-1,:));
    meas(k,:) = measfun(state(k,:),inp(k,:),measurement_noise(k,:));
  end
end

% PLOT THE DATA IF NO OUTPUT ARGS
if nargout == 0
  subplot(2,1,1)
  hold off
  plot(time,meas)
  ylabel('Measurements');
  title(key.prefix);
  subplot(2,1,2)
  hold off
  plot(time,inp) 
  ylabel('Inputs');
  xlabel('Time');
end

% CREATE OUT STRUCTURE
statenames = fieldnames(key.state);
for i = 1:numel(statenames)
  out.(statenames{i}) = state(:,i);
end
for i = 1:numel(key.input)
  out.(key.input{i}) = inp(:,i);
end
for i = 1:numel(key.noise.process)
  out.(key.noise.process{i}) = process_noise(:,i);
end
for i = 1:numel(key.noise.measurement)
  out.(key.noise.measurement{i}) = measurement_noise(:,i);
end
for i = 1:numel(key.meas)
  out.(key.meas{i}) = meas(:,i);
end
out.time = time;
for i = 1:numel(key.debug)
  out.(key.debug{i}) = dbg(:,i);
end

% SAVE
save(key.prefix,'meas','inp','out','key');

% OUTPUT IF SPECIFIED
if nargout == 1
  varargout{1} = out;
end
