% TIME Time object class constructor.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: Time object class constructor.  Time objects are lightweight
%              ltpda user objects that can be used to operate with times.
%              Their use in the graphical user interface is limited to
%              their creation.
%
% SUPERCLASSES: ltpda_nuo < ltpda_obj
%
% CONSTRUCTORS:
%
%       t1 = time()
%       t1 = time('14:00:05.000')
%       t1 = time('2007-06-06 14:00:05')
%       t1 = time('14:00:05 2007-06-06')
%       t1 = time(1234.5)
%       t1 = time([0 2000 6000])
%       t1 = time(plist)
%
% PLIST CONSTRUCTORS:
%
% From Milliseconds
% -----------------
%
%   Construct a time object from its representation in milliseconds since the
%   unix epoch, 1970-01-01 00:00:00.000 UTC:
%
%     'milliseconds' - time in milliseconds. default: 0
%
% From Time
% ---------
%
%   Construct a time object from its representation as a string or its
%   representation as number of seconds since the unix epoch, 1970-01-01
%   00:00:00.000 UTC:
%
%     'time' - time string or double. default: '1970-01-01 00:00:00.000 UTC'
%
%   If the time is specified as a string it is possible to specify the format
%   and the timezone that must be used to interpret the string:
%
%     'timezone'    - timezone. default: ''
%     'timeformat'  - time format string. default: ''
%
%
% SEE ALSO: timespan
%
% VERSION: $Id: time.m,v 1.90 2011/03/28 17:02:29 ingo Exp $
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

classdef time < ltpda_nuo

  % private read-only properties
  properties (SetAccess = private)
    utc_epoch_milli = 0;  % unix epoch time in milliseconds
  end

  % protected properties
  properties (SetAccess = protected)
  end

  % constant properties
  properties (Constant = true)
    timeformat;
    timezone;
  end

  % constant properties access methods
  methods
    function value = get.timezone(obj)
      p = getappdata(0, 'LTPDApreferences');
      value = char(p.getTimePrefs.getTimeTimezone);
      if ischar(value)
        value = java.util.TimeZone.getTimeZone(value);
      end
    end

    function value = get.timeformat(obj)
      p = getappdata(0, 'LTPDApreferences');
      value = char(p.getTimePrefs.getTimestringFormat);
    end
  end
  
  % constructor
  methods
    function obj = time(varargin)

      switch nargin
        case 0
          % no input arguments. return the current time
          obj.utc_epoch_milli = time.now();
        case 1
          % one input

          if isa(varargin{1}, 'time')
            % t1 = time(time-object)
            obj = copy(varargin{1}, 1);

          elseif ischar(varargin{1})
            % t1 = time('2007-08-03 10:00:00')
            obj.utc_epoch_milli = time.parse(varargin{1});

          elseif isstruct(varargin{1})
            % t1 = time(structure)
            obj = fromStruct(obj, varargin{1});

          elseif isnumeric(varargin{1})
            % t1 = time(12345)
            for kk = 1:numel(varargin{1})
              obj(kk).utc_epoch_milli = 1000*varargin{1}(kk);
            end
            obj = reshape(obj, size(varargin{1}));

          elseif iscell(varargin{1})
            % t1 = time({'14:00:00', '15:00:00'})
            for kk = 1:numel(varargin{1})
              obj(kk) = time(varargin{1}{kk});
            end
            obj = reshape(obj, size(varargin{1}));

          elseif isa(varargin{1}, 'plist')
            % t1 = time(plist)
            pl = varargin{1};
            pl_msec = find(pl, 'milliseconds');
            pl_time = find(pl, 'time');

            if ~isempty(pl_msec)
              % construct from milliseconds time definition
              obj.utc_epoch_milli = pl_msec;

            elseif ~isempty(pl_time)
              % construct from numefic value or string
              if ischar(pl_time)
                pl_timezone = find(pl, 'timezone');
                pl_format   = find(pl, 'timeformat');
                obj.utc_epoch_milli = time.parse(pl_time, pl_format, pl_timezone);
              elseif isnumeric(pl_time)
                obj.utc_epoch_milli = 1000*pl_time;
              end

            else
              % if the plist is empty then return the default time object
              if nparams(pl) == 0
                % default time object
              else
                error('### Unknown TIME constructor method.');
              end
            end

          else
            error('### Unknown single argument constructor.');
          end

        case 2
          % two input

          if iscellstr(varargin)
            % t1 = time('14:00:00', 'HH:MM:SS')
            obj.utc_epoch_milli = time.parse(varargin{1}, varargin{2});
            
          elseif isnumeric(varargin{1}) && ischar(varargin{2})
            % t1 = time(1234.5, 'HH:MM:SS')
            % NOTE: this is kept for back compatibility only. the second argument is just ignored
            warning('LTPDA:time', 'time(numeric, char) costructor is deprecated and will be soon removed');
            obj = time(varargin{1});

          elseif isa(varargin{1}, 'time') && ischar(varargin{2})
            % t1 = time(1234.5, 'HH:MM:SS')
            % NOTE: this is kept for back compatibility only. the second argument is just ignored
            warning('LTPDA:time', 'time(time, char) costructor is deprecated and will be soon removed');
            obj = time(varargin{1});
            
          elseif isa(varargin{1}, 'org.apache.xerces.dom.DeferredElementImpl') && isa(varargin{2}, 'history')
            % t1 = time(dom-node, history-objects)
            obj = fromDom(obj, varargin{1}, varargin{2});            
            
          else
            error('### Unknown constructor with two inputs: %s %s.', class(varargin{1}), class(varargin{2}));
          end

        otherwise
          error('### Unknown number of constructor arguments.');
      end

    end
  end

  % public methods
  methods
    varargout = copy(varargin)
    varargout = format(varargin)
    varargout = minus(varargin)
    varargout = plus(varargin)
    varargout = string(varargin)
    varargout = double(varargin)
    varargout = datenum(varargin)
  end

  % hidden methods
  methods (Hidden = true)
    varargout = attachToDom(varargin)
  end

  % private methods
  methods (Access = private)
  end
  
  % protected methods
  methods (Access = protected)
    varargout = fromStruct(varargin)
    varargout = fromDom(varargin)
  end

  % static methods
  methods (Static)

    varargout = parse(varargin);
    varargout = getdateform(varargin);
    varargout = matfrmt2javafrmt(varargin);
    varargout = strftime(varargin);
    varargout = getTimezones(varargin)

    function msec = now()
      msec = java.util.Date().getTime();
    end

    function ii = getInfo(varargin)
      ii = utils.helper.generic_getInfo(varargin{:}, 'time');
    end

    function out = VEROUT()
      out = '$Id: time.m,v 1.90 2011/03/28 17:02:29 ingo Exp $';
    end

    function out = SETS()
      out = {...
        'Default', ...
        'From Milliseconds', ...
        'From Time' };
    end

    function out = getDefaultPlist(set)
      switch lower(set)
        case 'default'
          out = plist();
        case 'from milliseconds'
          out = plist('milliseconds', 0);
        case 'from time'
          out = plist('time', '1970-01-01 00:00:00.000 UTC', 'timezone', '', 'timeformat', '');
        otherwise
          error('### Unknown set ''%s'' to get the default plist.', set);
      end
    end

    function obj = initObjectWithSize(n,m)
      obj = time.newarray([n m]);
    end

  end % end static methods

  % static hidden methods
  methods (Static = true, Hidden = true)
    varargout = loadobj(varargin)
    varargout = update_struct(varargin)
  end

end % end classdef

