% CONNECT connects to an LTPDA repository and returns the connection object.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% DESCRIPTION: CONNECT connects to an LTPDA repository and returns the
%              connection object.
% 
%              CONNECT stores a persistent set of logins where a login has
%              the fields:
%                  'hostname' - the hostname of the MySQL server
%                  'db'       - the name of the database
%                  'user'     - the username for connection to this db
%                  'passwd'   - the password for this user
% 
%              If a login for the requested hostname and db doesn't exist,
%              or if the existing login is too old (*) then the user is
%              prompted to log in again.
%               
%              (*) the expiry time for MySQL logins is set to 30s.
%
% CALL:        conn = connect(hostname)  % connects to 'test' database
%              conn = connect(hostname, dbname)  % dialog prompt for username and password
%              [conn, password] = connect(hostname, dbname) % return password to caller
%              conn = connect(hostname, dbname, dbuser, dbpass) % connect with explicit username and password
%
% VERSION:     $Id: connect.m,v 1.8 2010/01/22 12:46:08 ingo Exp $
%
% HISTORY:     24-05-2007 M Hewitson
%                 Creation
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


%              (*) the expiry time for MySQL logins is a property of the
%              LTPDA Toolbox and can be set in the LTPDA Preferences.


function varargout = connect(varargin)

  error('### Obsolete as of LTPDA version 2.2. Replaced my the utils class jmysql (utils.jmysql.%s)', mfilename());
  if nargin < 1
    error('### Incorrect inputs')
  end

  persistent logins;
  
  prefs = getappdata(0, 'LTPDApreferences');
  expTime = prefs.repository.loginExpiry;
  
  dbuser = '';
  dbpass = '';

  force = false;
  if nargin == 1
    dbhost = varargin{1};
    dbname = 'test';
  elseif nargin == 2
    dbhost = varargin{1};
    dbname = varargin{2};
  elseif nargin == 3
    dbhost = varargin{1};
    dbname = varargin{2};
    force = varargin{3};
  elseif nargin == 4
    dbhost = varargin{1};
    dbname = varargin{2};
    dbuser = varargin{3};
    dbpass = varargin{4};
  elseif nargin == 5
    dbhost = varargin{1};
    dbname = varargin{2};
    dbuser = varargin{3};
    dbpass = varargin{4};
    force = varargin{5};
  end
  
  if isempty(logins)
    % Prompt for username and password
    [dbuser, dbpass] = getlogin(dbhost, dbname, dbuser, dbpass, force);
        
    % in the case the user clicks cancel
    if ~ischar(dbuser) && ~ischar(dbpass)
      if (dbuser == -1 && dbpass == -1)
        varargout{1} = -1;
        varargout{2} = -1;
        return
      end
    end
    
    % Create a new login
    login.hostname = dbhost;
    login.db       = dbname;
    login.user     = dbuser;
    login.passwd   = dbpass;
    login.ts       = now;
    
    % store this login
    logins = [logins login];
    
  else
    % look for a login to this hostname/db
    loginFound = false;
    for kk=1:numel(logins)
      login = logins(kk);
      dt = (now - login.ts) * 86400; % [s]
      if strcmp(login.hostname, dbhost) && strcmp(login.db, dbname)
        if dt < expTime
          % get the username and password from here
          dbuser = login.user;
          dbpass = login.passwd;
          logins(kk).ts = now;
          loginFound = true;
          break;
        end
      end
    end    
    
    % If we didn't find a login then create a new one
    if force || isempty(dbuser) || isempty(dbpass)
      [dbuser, dbpass] = getlogin(dbhost, dbname, dbuser, dbpass, force);
      
      % Create a new login
      login.hostname = dbhost;
      login.db       = dbname;
      login.user     = dbuser;
      login.passwd   = dbpass;
      login.ts       = now;
      
      % store this login
      if ~loginFound
        logins = [logins login];      
      end
    end
    
  end
  
  %% return if we don't have a dbuser
  if isempty(dbuser)
    return
  end
  
  %% Database settings
  dbdriver = getappdata(0, 'mysql_driver');
  dburl    = sprintf('jdbc:mysql://%s/%s',dbhost,dbname);

  disp(sprintf('** Connecting to %s as %s...', dbhost, dbuser))

  conn     = database(dbname,dbuser,dbpass,dbdriver,dburl);
  disp('** Connection status:')
  disp(ping(conn))

  % Set outputs
  if nargout > 0
    varargout{1} = conn;
    if nargout == 2
      varargout{2} = dbpass;
    end
  end

end

function [dbuser, dbpass] = getlogin(dbhost, dbname, dbuser, dbpass, force)
      
    % first try defaults
    if isempty(dbuser)
      dbuser = getappdata(0, 'ltpda_repo_user');
    end
    if isempty(dbpass)
      dbpass = getappdata(0, 'ltpda_repo_pass');
    end
    
    % then log-in dialog
    if force || isempty(dbuser) || isempty(dbpass)

        ld = logindialog.LoginDialog([], true);
        ld.setVisible(true)
        if ~ld.isCancelled
            dbuser = char(ld.getUsername);
            dbpass = [char(ld.getPassword)]'; % for some reason we get a column here, so transpose.
        end

      if isempty(dbuser) || isempty(dbpass)
        warning('!!! Login process cancelled.');
        dbuser = -1;
        dbpass = -1;
        return
      end
    end
    
end
