/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * @author Paul Smith &lt;psmith@apache.org&gt;
 *
*/
package org.apache.log4j.chainsaw;

import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.util.Iterator;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.apache.log4j.chainsaw.icons.ChainsawIcons;
import org.apache.log4j.chainsaw.osx.OSXIntegration;
import org.apache.log4j.chainsaw.prefs.MRUFileList;
import org.apache.log4j.xml.UtilLoggingXMLDecoder;
import org.apache.log4j.xml.XMLDecoder;


/**
 * The complete File Menu for the main GUI, containing
 * the Load, Save, Close Welcome Tab, and Exit actions
 *
 * @author Paul Smith &lt;psmith@apache.org&gt;
 * @author Scott Deboy &lt;sdeboy@apache.org&gt;
 */
class FileMenu extends JMenu {
  private Action loadConfigAction;
  private Action exitAction;
  private Action loadLog4JAction;
  private Action loadUtilLoggingAction;
  private Action remoteLog4JAction;
  private Action remoteUtilLoggingAction;
  private Action saveAction;

  public FileMenu(final LogUI logUI) {
    super("File");
    setMnemonic(KeyEvent.VK_F);

    loadConfigAction = new AbstractAction("Load Chainsaw configuration"){
        public void actionPerformed(ActionEvent actionEvent) {
            logUI.showReceiverConfiguration();
        }
    };

    loadLog4JAction =
      new FileLoadAction(
        logUI, new XMLDecoder(logUI), "Open log4j XML-formatted file (.xml or .zip)...", false);

      loadLog4JAction.putValue(
        Action.ACCELERATOR_KEY,
        KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
      loadLog4JAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_L));
      loadLog4JAction.putValue(Action.SHORT_DESCRIPTION, "Loads events from a local XMLLayout-formatted file ");
      loadLog4JAction.putValue(Action.SMALL_ICON, new ImageIcon(ChainsawIcons.FILE_OPEN));

    loadUtilLoggingAction =
      new FileLoadAction(
        logUI, new UtilLoggingXMLDecoder(logUI),
        "Open util.logging XML-formatted file (.xml or .zip)...", false);

    remoteLog4JAction =
      new FileLoadAction(
        logUI, new XMLDecoder(logUI), "Open remote log4j XML-formatted file (.xml or .zip)...",
        true);
    remoteUtilLoggingAction =
      new FileLoadAction(
        logUI, new UtilLoggingXMLDecoder(logUI),
        "Open remote util.logging XML-formatted file (.xml or .zip)...", true);

    saveAction = new FileSaveAction(logUI);

    JMenuItem loadChainsawConfig = new JMenuItem(loadConfigAction);
    JMenuItem loadLog4JFile = new JMenuItem(loadLog4JAction);
    JMenuItem loadUtilLoggingFile = new JMenuItem(loadUtilLoggingAction);
    JMenuItem remoteLog4JFile = new JMenuItem(remoteLog4JAction);
    JMenuItem remoteUtilLoggingFile = new JMenuItem(remoteUtilLoggingAction);
    JMenuItem saveFile = new JMenuItem(saveAction);

    exitAction =
      new AbstractAction() {
          public void actionPerformed(ActionEvent e) {
            logUI.exit();
          }
        };

    exitAction.putValue(
      Action.ACCELERATOR_KEY,
      KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
    exitAction.putValue(Action.SHORT_DESCRIPTION, "Exits the Application");
    exitAction.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_X));
    exitAction.putValue(Action.NAME, "Exit");

    JMenuItem menuItemExit = new JMenuItem(exitAction);

    add(loadChainsawConfig);
    add(loadLog4JFile);
    add(loadUtilLoggingFile);
    addSeparator();
    add(remoteLog4JFile);
    add(remoteUtilLoggingFile);
    addSeparator();
    add(saveFile);
    addSeparator();

    final JMenu mrulog4j = new JMenu("MRU...");
    
  
    
    MRUFileList.addChangeListener(new ChangeListener() {
        
        public void stateChanged(ChangeEvent e) {
            
            buildMRUMenu(mrulog4j, logUI);
        }
        
    });
    buildMRUMenu(mrulog4j, logUI);
    
    add(mrulog4j);
    if (!OSXIntegration.IS_OSX) {
        addSeparator();
        add(menuItemExit);
    }
    
    
  }

  private void buildMRUMenu(final JMenu mrulog4j, final LogUI logui) {
        mrulog4j.removeAll();
        int counter = 1;
        if (MRUFileList.log4jMRU().getMRUList().size() > 0) {
            for (Iterator iter = MRUFileList.log4jMRU().getMRUList().iterator(); iter
                    .hasNext();) {
                final URL url = (URL) iter.next();
                // TODO work out the 'name', for local files it can't just be the full path
                final String name = url.getProtocol().startsWith("file")?url.getPath().substring(url.getPath().lastIndexOf('/')+1):url.getPath();
                String title = (counter++) + " - " + url.toExternalForm();
                JMenuItem menuItem = new JMenuItem(new AbstractAction(title) {

                    public void actionPerformed(ActionEvent e) {
                        FileLoadAction.importURL(logui.handler,
                                new XMLDecoder(), name, url);
                    }
                });
                mrulog4j.add(menuItem);
            }
        } else {
            JMenuItem none = new JMenuItem("None as yet...");
            none.setEnabled(false);
            mrulog4j.add(none);
        }
    }
  Action getLog4JFileOpenAction() {
    return loadLog4JAction;
  }

  Action getUtilLoggingJFileOpenAction() {
    return loadUtilLoggingAction;
  }

  Action getFileSaveAction() {
    return saveAction;
  }

  Action getExitAction() {
    return exitAction;
  }
}
