/*
 * jNPad v0.3 - jNPad's an Simple Text Editor written in Java
 *
 * Copyright (C) 2014-2017  rgs
 *
 * Require JDK 1.6 (or later)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 *
 *
 * Info, Questions, Suggestions & Bugs Report to rgsevero@gmail.com
 */

package jnpad.action;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.Action;

import jnpad.text.IDirtyAction;
import jnpad.text.IEditAction;
import jnpad.text.ISelectionAction;

/**
 * The Class ActionManager.
 *
 * @version 0.3
 * @since   jNPad v0.1
 */
public enum ActionManager {
  /** The INSTANCE. */
  INSTANCE;
  
  private Map<Object, Action>  actions = new HashMap<Object, Action>();
  
  /**
   * Register actions.
   *
   * @param actions_ the actions
   */
  public void registerActions(Map<?, Action> actions_) {
    for (Map.Entry<?, Action> entry : actions_.entrySet()) {
      actions.put(entry.getKey(), entry.getValue());
    }
  }

  /**
   * Register action.
   *
   * @param action the action
   */
  public void registerAction(Action action) {
    actions.put(action.getValue(Action.NAME), action);
  }

  /**
   * Unregister action.
   *
   * @param action the action
   */
  public void unregisterAction(Action action) {
    actions.remove(action.getValue(Action.NAME));
  }
 
  /**
   * Gets the.
   *
   * @param name the name
   * @return the action
   */
  public Action get(String name) {
    return actions.get(name);
  }

  /**
   * Sets the enabled.
   *
   * @param name the name
   * @param b the b
   */
  public void setEnabled(String name, boolean b) {
    Action action = get(name);
    if (action != null) {
      action.setEnabled(b);
    }
  }

  /**
   * Checks if is enabled.
   *
   * @param name the name
   * @return true, if is enabled
   */
  public boolean isEnabled(String name) {
    Action action = get(name);
    return action != null && action.isEnabled();
  }

  /**
   * Execute action.
   *
   * @param name the name
   * @return true, if successful
   */
  public boolean executeAction(String name) {
    Action action = get(name);
    if (action != null && action instanceof JNPadAction && action.isEnabled()) {
      if (((JNPadAction) action).isStateAction())
        ((JNPadAction) action).setSelected(!((JNPadAction) action).isSelected());
      else
        ((JNPadAction) action).performAction();
      return true;
    }
    return false;
  }

  /**
   * Gets the completions for prefix.
   *
   * @param prefix the prefix
   * @return the completions for prefix
   */
  public List<String> getCompletionsForPrefix(String prefix) {
    List<String> list = new ArrayList<String>();
    for (Object key : actions.keySet()) {
      Action a = actions.get(key);
      String s_key = key.toString();
      if (s_key.startsWith(prefix) && a.isEnabled()) {
        list.add(s_key);
      }
    }
    Collections.sort(list);
    return list;
  }
  
  /**
   * Sets the enabled by.
   *
   * @param edit the edit
   * @param selection the selection
   * @param undo the undo
   * @param redo the redo
   * @param dirty the dirty
   */
  public void setEnabledBy(final boolean edit, final boolean selection, 
                           final boolean undo, final boolean redo,
                           final boolean dirty) {
    for (Object key : actions.keySet()) {
      Action a = actions.get(key);
      if(a instanceof UndoAction) {
        a.setEnabled(edit & undo);
      }
      else if (a instanceof RedoAction) {
        a.setEnabled(edit & redo);
      }
      else if (a instanceof IEditAction && a instanceof ISelectionAction) {
        a.setEnabled(edit && selection);
      }
      else if (a instanceof IEditAction && a instanceof IDirtyAction) {
        a.setEnabled(edit && dirty);
      }
      else if (a instanceof IEditAction) {
        a.setEnabled(edit);
      }
      else if (a instanceof ISelectionAction) {
        a.setEnabled(selection);
      }
    }
  }
  
}
