Index: /applications/editors/josm/plugins/smed/build.xml
===================================================================
--- /applications/editors/josm/plugins/smed/build.xml	(revision 23178)
+++ /applications/editors/josm/plugins/smed/build.xml	(revision 23178)
@@ -0,0 +1,146 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+** This is a template build file for a JOSM  plugin.
+**
+** Maintaining versions
+** ====================
+** see README.template
+**
+** Usage
+** =====
+** To build it run
+**
+**    > ant  dist
+**
+** To install the generated plugin locally (in you default plugin directory) run
+**
+**    > ant  install
+**
+** The generated plugin jar is not automatically available in JOSMs plugin configuration
+** dialog. You have to check it in first.
+**
+** Use the ant target 'publish' to check in the plugin and make it available to other
+** JOSM users:
+**    set the properties commit.message and plugin.main.version
+** and run
+**    > ant  publish
+**
+**
+-->
+<project name="smed" basedir=".">
+
+	<!-- enter the SVN commit message -->
+	<property name="commit.message" value="New release" />
+	<!-- enter the *lowest* JOSM version this plugin is currently compatible with -->
+	<property name="plugin.main.version" value="3329" />
+
+
+	<!--
+      ************************************************
+      ** should not be necessary to change the following properties
+     -->
+	<property name="josm"                   location="../../core/dist/josm-custom.jar"/>
+	<property name="plugin.build.dir"       value="build"/>
+	<property name="plugin.src.dir"         value="src"/>
+	<!-- this is the directory where the plugin jar is copied to -->
+	<property name="plugin.dist.dir"        value="../../dist"/>
+	<property name="ant.build.javac.target" value="1.5"/>
+	<property name="plugin.dist.dir"        value="../../dist"/>
+	<property name="plugin.jar"             value="${plugin.dist.dir}/${ant.project.name}.jar"/>
+
+	<!--
+    **********************************************************
+    ** init - initializes the build
+    **********************************************************
+    -->
+	<target name="init">
+		<mkdir dir="${plugin.build.dir}"/>
+	</target>
+
+	<!--
+    **********************************************************
+    ** compile - complies the source tree
+    **********************************************************
+    -->
+	<target name="compile" depends="init">
+		<echo message="compiling sources for  ${plugin.jar} ... "/>
+		<javac srcdir="src" classpath="${josm}" debug="true" destdir="${plugin.build.dir}">
+			<compilerarg value="-Xlint:deprecation"/>
+			<compilerarg value="-Xlint:unchecked"/>
+		</javac>
+	</target>
+
+	<!--
+    **********************************************************
+    ** dist - creates the plugin jar
+    **********************************************************
+    -->
+	<target name="dist" depends="compile">
+		<echo message="creating ${ant.project.name}.jar ... "/>
+
+        <copy todir="${plugin.build.dir}/images">
+            <fileset dir="${plugin.src.dir}/images"/>
+        </copy>
+
+		<copy todir="${plugin.build.dir}/images">
+			<fileset dir="images"/>
+		</copy>
+		<copy todir="${plugin.build.dir}/smed/msg">
+			<fileset dir="${plugin.src.dir}/smed/msg"/>
+		</copy>
+		<copy todir="${plugin.build.dir}">
+			<fileset dir=".">
+                <include name="copyright.txt" />
+                <include name="LICENSE.txt" />
+			</fileset>
+		</copy>
+		<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
+			<!--
+        ************************************************
+        ** configure these properties. Most of them will be copied to the plugins
+        ** manifest file. Property values will also show up in the list available
+        ** plugins: http://josm.openstreetmap.de/wiki/Plugins.
+        **
+        ************************************************
+    -->
+			<manifest>
+				<attribute name="Author" value="Werner, Malcolm"/>
+				<attribute name="Plugin-Class" value="smed.Smed"/>
+				<attribute name="Plugin-Date" value="${version.entry.commit.date}"/>
+				<attribute name="Plugin-Description" value="Create and edit seamaps for OpenSeaMap"/>
+				<attribute name="Plugin-Icon" value="images/Smed.png"/>
+				<attribute name="Plugin-Link" value="http://openseamap.org/"/>
+				<attribute name="Plugin-Mainversion" value="${plugin.main.version}"/>
+				<attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
+				<attribute name="Class-Path" value="./tplug/ifc.jar"/>
+			</manifest>
+		</jar>
+	</target>
+	
+	<!--
+    **********************************************************
+    ** clean - clean up the build environment
+    **********************************************************
+    -->
+	<target name="clean">
+		<delete dir="${plugin.build.dir}"/>
+		<delete file="${plugin.jar}"/>
+	</target>
+
+	<!--
+    **********************************************************
+    ** install - install the plugin in your local JOSM installation
+    **********************************************************
+    -->
+	<target name="install" depends="dist">
+		<property environment="env"/>
+		<condition property="josm.plugins.dir" value="${env.APPDATA}/JOSM/plugins" else="${user.home}/.josm/plugins">
+			<and>
+				<os family="windows"/>
+			</and>
+		</condition>
+		<copy file="${plugin.jar}" todir="${josm.plugins.dir}"/>
+	</target>
+
+	
+</project>
Index: /applications/editors/josm/plugins/smed/src/smed/Smed.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/Smed.java	(revision 23178)
+++ /applications/editors/josm/plugins/smed/src/smed/Smed.java	(revision 23178)
@@ -0,0 +1,118 @@
+package smed;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+
+import javax.swing.JMenuItem;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.plugins.Plugin;
+import org.openstreetmap.josm.plugins.PluginInformation;
+
+import smed.plug.SmedPluginApp;
+import smed.plug.ifc.SmedPluggable;
+import smed.plug.util.SmedPluginLoader;
+import smed.tabs.SmedTabAction;
+
+public class Smed extends Plugin{
+	
+	private JMenuItem item;
+	private SmedTabAction SmedTab;
+	
+	public Smed(PluginInformation info) {
+		super(info);
+		
+		String os = "";
+		String userHome = "";
+				
+		File pluginDir = Main.pref.getPluginsDirectory();
+		String pluginDirName = pluginDir.getAbsolutePath();
+		File splug = new File(pluginDirName + "/splug");
+		if(!splug.exists()) splug.mkdir();
+		
+		// build smed_ifc.jar from smed.jar
+		JarEntry ent = null;
+		BufferedInputStream inp = null;
+		String entName = null;
+		byte[] buffer = new byte[16384];
+		int len;
+
+		try {
+			JarFile file = new JarFile(pluginDirName  + "/smed.jar");			
+			FileOutputStream fos = new FileOutputStream(pluginDirName + "/splug/smed_ifc.jar");			
+			JarOutputStream jos = new JarOutputStream(fos);
+			BufferedOutputStream oos = new BufferedOutputStream( jos);
+
+			ent = file.getJarEntry("smed/plug/ifc/SmedPluggable.class");
+			inp = new BufferedInputStream(file.getInputStream( ent ));
+			entName = ent.getName();
+
+			jos.putNextEntry(new JarEntry(entName));
+			
+		    while ((len = inp.read(buffer)) > 0) {
+		    	oos.write(buffer, 0, len);
+            }
+
+		    oos.flush();
+		    inp.close();
+	    
+		    ent = file.getJarEntry("smed/plug/ifc/SmedPluginManager.class");
+		    inp = new BufferedInputStream(file.getInputStream( ent ));
+		    entName = ent.getName();
+		    jos.putNextEntry(new JarEntry(entName));
+		    
+		    while ((len = inp.read(buffer)) > 0) {
+		    	oos.write(buffer, 0, len);
+            }
+
+			oos.flush();
+			oos.close();
+		    fos.flush();
+		    fos.close();
+		    inp.close();
+			
+		} catch (Exception e) {
+			e.printStackTrace();
+		} 
+
+		
+		// add smed_ifc.jar to classpath (josm need this archive, or perhaps only the interface)
+		File f = new java.io.File(pluginDirName + "/splug/smed_ifc.jar");
+		ClassLoader myClassLoader = Thread.currentThread().getContextClassLoader();
+
+		try {
+			Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
+			addUrlMethod.setAccessible(true);
+			addUrlMethod.invoke(myClassLoader, f.toURI().toURL());
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		
+		SmedTab = new SmedTabAction();
+		item = Main.main.menu.toolsMenu.add(SmedTab);
+		
+		item.setEnabled(false);
+
+	}
+	
+	@Override
+	public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+		if (oldFrame == null && newFrame != null) {
+			item.setEnabled(true);
+		} else {
+			item.setEnabled(false);
+			// SmpDialog.CloseDialog();
+		}
+	}
+
+}
Index: /applications/editors/josm/plugins/smed/src/smed/plug/SmedPluginApp.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/plug/SmedPluginApp.java	(revision 23178)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/SmedPluginApp.java	(revision 23178)
@@ -0,0 +1,30 @@
+package smed.plug;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.openstreetmap.josm.Main;
+
+import smed.plug.ifc.SmedPluggable;
+import smed.plug.util.SmedPluginLoader;
+
+public class SmedPluginApp implements Runnable {
+
+	@Override
+	public void run() {
+		try {
+			runPlugins();
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public static void runPlugins() throws IOException {
+		String pluginDirName = Main.pref.getPluginsDirectory().getAbsolutePath();
+		
+		List<SmedPluggable> plugins = SmedPluginLoader.loadPlugins(new File(pluginDirName + "/splug"));
+		
+	}
+
+}
Index: /applications/editors/josm/plugins/smed/src/smed/plug/ifc/SmedPluggable.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/plug/ifc/SmedPluggable.java	(revision 23178)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/ifc/SmedPluggable.java	(revision 23178)
@@ -0,0 +1,15 @@
+package smed.plug.ifc;
+
+import javax.swing.JComponent;
+
+
+public interface SmedPluggable {
+
+	boolean start();
+	boolean start(JComponent panel);
+	boolean stop();
+	String getName();
+	
+	void setPluginManager(SmedPluginManager manager);
+}
+
Index: /applications/editors/josm/plugins/smed/src/smed/plug/ifc/SmedPluginManager.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/plug/ifc/SmedPluginManager.java	(revision 23178)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/ifc/SmedPluginManager.java	(revision 23178)
@@ -0,0 +1,5 @@
+package smed.plug.ifc;
+
+public interface SmedPluginManager {
+	void showVisualMessage(String message);
+}
Index: /applications/editors/josm/plugins/smed/src/smed/plug/util/JARFileFilter.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/plug/util/JARFileFilter.java	(revision 23178)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/util/JARFileFilter.java	(revision 23178)
@@ -0,0 +1,13 @@
+package smed.plug.util;
+
+import java.io.File;
+import java.io.FileFilter;
+
+public class JARFileFilter implements FileFilter {
+
+	@Override
+	public boolean accept(File f) {
+		return f.getName().toLowerCase().endsWith(".jar");
+	}
+
+}
Index: /applications/editors/josm/plugins/smed/src/smed/plug/util/SmedPluginLoader.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/plug/util/SmedPluginLoader.java	(revision 23178)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/util/SmedPluginLoader.java	(revision 23178)
@@ -0,0 +1,108 @@
+package smed.plug.util;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+
+import smed.plug.ifc.SmedPluggable;
+
+
+public class SmedPluginLoader {
+
+	public static List<SmedPluggable> loadPlugins(File plugDir) throws IOException {
+		File[] plugJars = plugDir.listFiles(new JARFileFilter());
+		
+		URL[] urls = fileArrayToURLArray(plugJars);
+		if(urls == null) return null;
+		
+		ClassLoader cl = new URLClassLoader(urls);
+		List<Class<SmedPluggable>> plugClasses = extractClassesFromJARs(plugJars, cl);
+		
+		if(plugClasses == null) return null;
+		else return createPluggableObjects(plugClasses);
+	}
+
+	private static List<SmedPluggable> createPluggableObjects(List<Class<SmedPluggable>> pluggables) {
+		List<SmedPluggable> plugs = new ArrayList<SmedPluggable>(pluggables.size());
+		for(Class<SmedPluggable> plug : pluggables) {
+			try {
+				plugs.add(plug.newInstance());
+			} catch (InstantiationException e) {
+				System.err.println("Can't instantiate plugin: " + plug.getName());
+				e.printStackTrace();
+			} catch (IllegalAccessException e) {
+				System.err.println("IllegalAccess for plugin: " + plug.getName());
+				e.printStackTrace();
+			}
+		}
+		
+		return plugs;
+	}
+
+	private static List<Class<SmedPluggable>> extractClassesFromJARs(File[] jars, ClassLoader cl) throws FileNotFoundException, IOException {
+		List<Class<SmedPluggable>> classes = new ArrayList<Class<SmedPluggable>>();
+		
+		for(File jar : jars) {
+			classes.addAll(extractClassesFromJAR(jar, cl));
+		}
+
+		if(classes.isEmpty()) return null;
+		else return classes;
+	}
+
+	@SuppressWarnings("unchecked")
+	private static Collection<? extends Class<SmedPluggable>> extractClassesFromJAR (File jar, ClassLoader cl) throws FileNotFoundException, IOException {
+		List<Class<SmedPluggable>> classes = new ArrayList<Class<SmedPluggable>>();
+		JarInputStream jaris = new JarInputStream(new FileInputStream(jar));
+		JarEntry ent = null;
+		
+		while ((ent = jaris.getNextJarEntry()) != null) {
+			String entName = ent.getName(); //.toLowerCase();
+			
+			if (entName.endsWith(".class")) {
+				try {
+					Class<?> cls = cl.loadClass(entName.substring(0, entName.length()- 6).replace('/', '.'));
+					if(isPluggableSmedClass(cls)) classes.add((Class<SmedPluggable>) cls);
+				} catch (ClassNotFoundException e) {
+					System.err.println("Can't load Class" + entName);
+					e.printStackTrace();
+				}
+			}
+		}
+		
+		jaris.close();
+		
+		return classes;
+	}
+
+	private static boolean isPluggableSmedClass(Class<?> cls) {
+		for (Class<?> i: cls.getInterfaces()) {
+			if (i.equals(SmedPluggable.class)) return true;
+		}
+		
+		return false;
+	}
+
+	private static URL[] fileArrayToURLArray(File[] files) throws MalformedURLException {
+		// splug contains at least smed_ifc.jar, but smed_ifc.jar isn't pluggable
+		if(files.length <= 1) return null;
+		
+		URL[] urls = new URL[files.length];
+		
+		
+		for(int i = 0; i < files.length; i++) {
+			urls[i] = files[i].toURI().toURL();
+		}
+		
+		return urls;
+	}
+}
Index: /applications/editors/josm/plugins/smed/src/smed/tabs/SmedTabAction.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/tabs/SmedTabAction.java	(revision 23178)
+++ /applications/editors/josm/plugins/smed/src/smed/tabs/SmedTabAction.java	(revision 23178)
@@ -0,0 +1,64 @@
+package smed.tabs;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.WindowConstants;
+
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.tools.Shortcut;
+
+public class SmedTabAction extends JosmAction {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	
+	public SmedTabAction() {
+		super( "Seekarten Editor", "Smed","Seekarten Editor", Shortcut.registerShortcut(
+								"tools:Semmaps",
+								tr("Tool: {0}", "Seekarten Editor"), KeyEvent.VK_K, //$NON-NLS-1$ //$NON-NLS-2$
+								Shortcut.GROUP_EDIT, Shortcut.SHIFT_DEFAULT), true);
+
+		try {
+			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+		} catch (Exception e) {
+			e.printStackTrace();
+		} 
+	}
+
+	
+	@Override
+	public void actionPerformed(ActionEvent e) {
+		SwingUtilities.invokeLater(new Runnable() {
+			public void run() {
+				createAndShowTabs();
+			}
+		});
+	}
+
+
+	protected void createAndShowTabs() {
+        //Create and set up the window.
+        JFrame frame = new JFrame("TabbedPaneDemo");
+        // frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        // frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
+        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+        
+        //Add content to the window.
+        frame.add(new SmedTabbedPane(), BorderLayout.CENTER);
+
+        //Display the window.
+        frame.pack();
+        frame.setVisible(true);
+	}
+
+
+}
Index: /applications/editors/josm/plugins/smed/src/smed/tabs/SmedTabbedPane.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/tabs/SmedTabbedPane.java	(revision 23178)
+++ /applications/editors/josm/plugins/smed/src/smed/tabs/SmedTabbedPane.java	(revision 23178)
@@ -0,0 +1,85 @@
+package smed.tabs;
+
+import java.awt.Dimension;
+import java.awt.GridLayout;
+import java.awt.event.KeyEvent;
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import javax.swing.Icon;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+
+import org.openstreetmap.josm.Main;
+
+import smed.plug.ifc.SmedPluggable;
+import smed.plug.util.SmedPluginLoader;
+
+public class SmedTabbedPane extends JPanel {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+
+	@SuppressWarnings("null")
+	public SmedTabbedPane() {
+		super(new GridLayout(1, 1));
+		
+		List<SmedPluggable> plugins = null;
+		String pluginDirName = Main.pref.getPluginsDirectory().getAbsolutePath();
+		try {
+			plugins = SmedPluginLoader.loadPlugins(new File(pluginDirName + "/splug"));
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		
+        Icon icon = null;
+		JTabbedPane tabbedPane = new JTabbedPane();
+
+		JComponent panel1;
+		if(plugins == null) {
+        	panel1 = makeTextPanel("Panel #1");
+        	tabbedPane.addTab("Tab 1", icon , panel1, "Does nothing");
+        } else {
+        	panel1 = new JPanel();
+        	plugins.get(0).start(panel1);
+        	tabbedPane.addTab(plugins.get(0).getName(), icon , panel1, "say hello");
+        }
+    	
+    	tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
+
+		
+        JComponent panel2 = makeTextPanel("Panel #2");
+        tabbedPane.addTab("Tab 2", icon, panel2, "Does twice as much nothing");
+        tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);
+        
+        JComponent panel3 = makeTextPanel("Panel #3");
+        tabbedPane.addTab("Tab 3", icon, panel3, "Still does nothing");
+        tabbedPane.setMnemonicAt(2, KeyEvent.VK_3);
+        
+        JComponent panel4 = makeTextPanel( "Panel #4 (has a preferred size of 410 x 50).");
+        panel4.setPreferredSize(new Dimension(410, 50));
+        tabbedPane.addTab("Tab 4", icon, panel4, "Does nothing at all");
+        tabbedPane.setMnemonicAt(3, KeyEvent.VK_4);
+		
+        //Add the tabbed pane to this panel.
+        add(tabbedPane);
+		
+        //The following line enables to use scrolling tabs.
+        tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+	}
+
+	private JComponent makeTextPanel(String text) {
+		JPanel panel = new JPanel(false);
+		JLabel filler = new JLabel(text);
+		filler.setHorizontalAlignment(JLabel.CENTER);
+		panel.setLayout(new GridLayout(1, 1));
+        panel.add(filler);
+        
+		return panel;
+	}
+}
