package org.jcon.df.util.security;

import org.jcon.ba.system.BeanActionStart;
import org.jcon.df.Database;
import org.jcon.df.DatastoreServices;
import org.jcon.df.edit.ViewSpeedup;
import org.jcon.df.SystemUser;
import org.jcon.df.request.Filter;
import org.jcon.df.work.DatabaseUtil;
import org.jcon.df.work.Row;
import org.jcon.ui.FieldWindow;
import org.jcon.util.GenLib;
import org.jcon.util.msg.Message;
import org.jcon.util.msg.MessageDef;
import org.jcon.util.msg.MessageListener;
import org.jcon.util.msg.MessageSourceStd;
import org.jcon.util.service.ContainerServices;
import org.jcon.util.service.ContainerServicesUser;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;

/**
* This class provides user security for a system. Features are: <p> </pre>
* - Flexible and reusable
* - One user at a time
* - Standard logon window with UserID and Password
* - Controls access to "SecureItems" via name filter
* - SecureItem names are hierarchial, ie "Awards.Menu.Edit"
* - Reusable UserProfile is defined via SecureItems </pre>
*
* @author Jack Harich
*/

public class UserSecurity extends MessageSourceStd
    implements MessageListener, ActionListener,
    ContainerServicesUser {

//---------- Private Fields ------------------------------  
/**@supplierCardinality 1*/
private User              user; // Current user, null if none
/**@supplierCardinality 1*/
private UserEntity        userEntity;
private FieldWindow       logon;
private DatastoreServices datastoreServices;
private ContainerServices containerServices;
private Database          database;
private DatabaseUtil      databaseUtil;

private static final String LOGON_TITLE = "Logon Please";

//---------- MessageSourceStd Abstractions ---------------
public Vector getMessageDefs() {
    Vector defs = new Vector();
    MessageDef def;

    def = new MessageDef("LogonApproved", this);
    // Not used def.add("User", User.class, "The user who logged on.");
    def.add("UserID", String.class, "User's UserID");
    defs.addElement(def);

    def = new MessageDef("SystemUserChanged", this);
    def.add("SystemUser", SystemUser.class, "The new user.");
    defs.addElement(def);

    defs.addElement(new MessageDef("LogonCancelled", this));

    return defs;
}
//---------- MessageListener Implementation --------------
public void processMessage(Message message) {
    String name = message.getName();
    //print(".processMessage() - name is " + name);

    if (name == "LogonRequested") {
        logonRequested();
    }
}
public String[] loadMessageInterests() {
    return new String[] {"LogonRequested"};
}
//---------- ActionListener Implementation ---------------
public void actionPerformed(ActionEvent evt) {
    String command = evt.getActionCommand().intern();

    if (command == "LogonCancel") {
        logon.dispose();
        logon = null;
        messageRouter.fire("LogonCancelled", this);

    } else if (command == "LogonOkay") {
        processLogonOkay();
    }
}
//---------- ContainerServicesUser Implementation --------
public void setContainerServices(ContainerServices services) {
    containerServices = services;
}
public String[] getContainerServicesInterests() {
    return new String[] {"DatastoreServices", "SecurityServices"};
}    
//---------- Public Methods ------------------------------    
public boolean isAllowed(String secureItem) {
    return user.isAllowed(secureItem);
}
//---------- Private Methods -----------------------------
private void logonRequested() {
    checkServices();
    logon = startLogonDialog();
}
private void processLogonOkay() {
    
    String userID = logon.getFieldText("UserID").trim().toUpperCase();
    String password = logon.getFieldText("Password").trim();

    if (userID.equals("") || password.equals("")) {
        GenLib.helpfulHint("UserID and Password are both required.");
        logon.requestFocusFirstField();
        return; // <-----<<<
    }
    // Get User
    logon.setTitle("Authorizing User...");
    logon.setEnabled(false);
    User newUser = userEntity.createUser(userID, password);
    if (newUser == null) {
        GenLib.helpfulHint("Invalid UserID or Password.");
        logon.setTitle(LOGON_TITLE);
        logon.setEnabled(true);
        logon.requestFocusFirstField();
        return; // <-----<<<
    }
    // newUser is valid, so proceed
    user = newUser;
    fireLogonApproved(user);
    // Remove non-modal dialog AFTER menu appears
    logon.dispose();
    logon = null;
}
private FieldWindow startLogonDialog() {
    //print(".startLogonDialog() - Entered");
    FieldWindow logon = new FieldWindow();

    logon.setActionListener(this);
    logon.setTitle(LOGON_TITLE);
    logon.setFrame(false);
    logon.setShowInThread(true);

    logon.addTextField("UserID", "UserID", 15);
    logon.setTextFieldUpperCase("UserID");
    logon.addTextField("Password", "Password", 15);

    logon.addButton("Okay", "LogonOkay");
    logon.addButton("Cancel", "LogonCancel");
    logon.setWindowClosingCommand("LogonCancel");

    //print(".startLogonDialog() - Before logon.start()");
    logon.start();
    //print(".startLogonDialog() - After logon.start()");

    // Speedup DataEditor
    //print(".startLogonDialog() - Calling ViewSpeedup().speedup()");
    //new ViewSpeedup().speedup();

    return logon;
}
private void checkServices() {
    if (datastoreServices == null) {

        datastoreServices = (DatastoreServices)
            containerServices.getService("DatastoreServices");

        database = datastoreServices.createDatabase("atsdr");
        databaseUtil = new DatabaseUtil(database);

        //----- userEntity
        userEntity = new UserEntity();
        userEntity.setDatabase(database);
        //----- SecurityServices
        SecurityServices ss = (SecurityServices)
            containerServices.getService("SecurityServices");    
        ss.setUserSecurity(this);
    }
}
private void fireLogonApproved(User user) {
    Message message;

    message = new Message("SystemUserChanged");
    message.set("SystemUser", user);
    messageRouter.fire(message, this);

    message = new Message("LogonApproved");
    //message.set("User", user);
    message.set("UserID", user.getUserID());
    messageRouter.fire(message, this);
}
//--- Std
private static void print(String text) {
    System.out.println("UserSecurity" + text);
}

} // End class

