/*
 * @(#)MultiShowApplicationModel.java  1.0  2009-12-20
 * 
 * Copyright (c) 2009 Werner Randelshofer, Immensee, Switzerland.
 * All rights reserved.
 *
 * You may not use, copy or modify this file, except in compliance with the
 * license agreement you entered into with Werner Randelshofer.
 * For details see accompanying license terms.
 */
package ch.randelshofer.multishow;

import ch.randelshofer.app.action.DebugAction;
import ch.randelshofer.app.action.LoadNextAction;
import ch.randelshofer.app.action.LoadPreviousAction;
import ch.randelshofer.util.PropertyModel;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.activation.CommandInfo;
import javax.swing.ActionMap;
import javax.swing.filechooser.FileFilter;
import org.jhotdraw.app.*;
import org.jhotdraw.app.action.file.*;
import org.jhotdraw.gui.JFileURIChooser;

/**
 * MultiShowApplicationModel.
 *
 * @author Werner Randelshofer
 * @version 1.0 2009-12-20 Created.
 */
public class MultiShowApplicationModel extends EmptyApplicationModel {

    private PropertyModel applicationProperties = new PropertyModel();
    private PropertyModel viewProperties = new PropertyModel();
    private ViewRegistry registry;
    private MultiShowMenuBuilder menuBuilder;

    @Override
    public ActionMap createActionMap(Application a, View v) {
        ActionMap m = new ActionMap();
        m.put(CloseFileAction.ID, new CloseFileAction(a, v));
        m.put(NewWindowAction.ID, new NewWindowAction(a));
        m.put(LoadFileAction.ID, new LoadFileAction(a, v));
        m.put(LoadNextAction.ID, new LoadNextAction(a, v));
        m.put(LoadPreviousAction.ID, new LoadPreviousAction(a, v));
        m.put(InfoAction.ID, new InfoAction(a, v));
        m.put(DebugAction.ID, new DebugAction(a));
        return m;
    }

    @Override
    public MenuBuilder getMenuBuilder() {
        if (menuBuilder == null) {
            menuBuilder = new MultiShowMenuBuilder();
        }
        return menuBuilder;
    }

    public synchronized ViewRegistry getRegistry() {
        if (registry == null) {
            registry = new ViewRegistry();
            registry.registerViews();
        }
        return registry;
    }

    public PropertyModel getApplicationProperties() {
        return applicationProperties;
    }

    public PropertyModel getViewProperties() {
        return applicationProperties;
    }

    @Override
    public JFileURIChooser createOpenChooser(Application a, View v) {
        JFileURIChooser fileChooser = new JFileURIChooser();

        Map<FileFilter, CommandInfo> map = getRegistry().getFileFilterMap();
        Iterator iter = map.keySet().iterator();
        while (iter.hasNext()) {
            fileChooser.addChoosableFileFilter((javax.swing.filechooser.FileFilter) iter.next());
        }
        fileChooser.setFileFilter(fileChooser.getAcceptAllFileFilter());

        List<URI> uris = a.getRecentURIs();
        if (!uris.isEmpty()) {
            fileChooser.setSelectedURI(uris.get(0));
        }

        return fileChooser;
    }

    /**
     * Loads the properties.
     */
    public void loadProperties(String propertiesFile) throws IOException {
        FileInputStream in = null;
        try {
            in = new FileInputStream(propertiesFile);
            applicationProperties.clear();
            viewProperties.clear();

            Properties p = new Properties();
            p.load(in);
            Enumeration enm = p.keys();
            while (enm.hasMoreElements()) {
                String key = (String) enm.nextElement();
                String value = (String) p.get(key);
                if (value != null) {
                    if (key.startsWith("project.")) {
                        viewProperties.put(key.substring(8), value);
                    } else if (key.startsWith("application.")) {
                        applicationProperties.put(key.substring(12), value);
                    }
                }
            }
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                }
            }
        }
    }

    public void saveProperties(String propertiesFile) throws IOException {
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(propertiesFile);
            Properties p = new Properties();
            Enumeration enm = viewProperties.keys();
            while (enm.hasMoreElements()) {
                Object key = enm.nextElement();
                p.put("project." + key, viewProperties.get(key));
            }
            enm = applicationProperties.keys();
            while (enm.hasMoreElements()) {
                Object key = enm.nextElement();
                p.put("application." + key, applicationProperties.get(key));
            }

            p.store(out, "MultiShow Preferences");
        } finally {
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                }
            }
        }
    }

    @Override
    public void initApplication(Application a) {
        try {
            applicationProperties = new PropertyModel();
            viewProperties = new PropertyModel();
            loadProperties(getPropertiesFileName());
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    @Override
    public void destroyApplication(Application a) {
        try {
            saveProperties(getPropertiesFileName());
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    /**
     * Returns the properties file name.
     */
    public String getPropertiesFileName() {
        if (System.getProperty("os.name").toLowerCase().startsWith("mac")) {
            return System.getProperty("user.home") + "/Library/Preferences/" + getName() + ".prefs";
        } else {
            return System.getProperty("user.home") + File.separator + getName() + ".prefs";
        }
    }
}
