Index: /applications/editors/josm/plugins/smed/LICENSE.txt
===================================================================
--- /applications/editors/josm/plugins/smed/LICENSE.txt	(revision 23236)
+++ /applications/editors/josm/plugins/smed/LICENSE.txt	(revision 23236)
@@ -0,0 +1,12 @@
+toms License
+============
+
+toms, and all its integral parts, are released under the GNU General 
+Public License v2 or later.
+
+The GPL v3 is accessible here:
+http://www.gnu.org/licenses/gpl.html
+
+The GPL v2 is accessible here:
+http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+
Index: /applications/editors/josm/plugins/smed/build.xml
===================================================================
--- /applications/editors/josm/plugins/smed/build.xml	(revision 23236)
+++ /applications/editors/josm/plugins/smed/build.xml	(revision 23236)
@@ -0,0 +1,151 @@
+<?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="plugins"/>
+		</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}"/>
+			</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/copyright.txt
===================================================================
--- /applications/editors/josm/plugins/smed/copyright.txt	(revision 23236)
+++ /applications/editors/josm/plugins/smed/copyright.txt	(revision 23236)
@@ -0,0 +1,7 @@
+Plugin toms
+
+This plugin is copyrighted 2009-2010 
+by Werner Koenig <werner.koenig@t-online.de>
+and by Malcolm Herring <malcolm.herring@btinternet.com>.
+
+It is distributed under GPL-v3 license (see file  LICENSE.txt in this directory).
Index: /applications/editors/josm/plugins/smed/src/smed/Smed.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/Smed.java	(revision 23236)
+++ /applications/editors/josm/plugins/smed/src/smed/Smed.java	(revision 23236)
@@ -0,0 +1,144 @@
+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.Enumeration;
+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 e = null;
+        BufferedInputStream inp = null;
+        String eName = null;
+        byte[] buffer = new byte[16384];
+        int len;
+
+        System.out.println(new java.util.Date());
+        
+        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);
+            
+            /* nicht ohne Versionierung freigeben
+            // extract *.jar to splug
+            Enumeration<JarEntry> ent = file.entries();
+            while(ent.hasMoreElements()) {
+            	e = ent.nextElement();
+            	eName = e.getName(); 
+            	if(eName.endsWith(".jar")) {
+            		FileOutputStream pfos = new FileOutputStream(pluginDirName + "/splug/" + eName);
+            		BufferedOutputStream pos = new BufferedOutputStream(pfos);
+            		inp = new BufferedInputStream(file.getInputStream( e ));
+            		
+                    while ((len = inp.read(buffer)) > 0) {
+                        pos.write(buffer, 0, len);
+                    }
+            		
+            		pos.flush();
+            		pos.close();
+            		inp.close();
+            		pfos.close();
+            	}
+            }
+            */
+            
+            // write smed_ifc.jar to splug
+            e = file.getJarEntry("smed/plug/ifc/SmedPluggable.class");
+            inp = new BufferedInputStream(file.getInputStream( e ));
+            eName = e.getName();
+
+            jos.putNextEntry(new JarEntry(eName));
+
+            while ((len = inp.read(buffer)) > 0) {
+                oos.write(buffer, 0, len);
+            }
+
+            oos.flush();
+            inp.close();
+
+            e = file.getJarEntry("smed/plug/ifc/SmedPluginManager.class");
+            inp = new BufferedInputStream(file.getInputStream( e ));
+            eName = e.getName();
+            jos.putNextEntry(new JarEntry(eName));
+
+            while ((len = inp.read(buffer)) > 0) {
+                oos.write(buffer, 0, len);
+            }
+
+            oos.flush();
+            oos.close();
+            fos.flush();
+            fos.close();
+            inp.close();
+
+        } catch (Exception ex) {
+            ex.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 ex) {
+            ex.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 23236)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/SmedPluginApp.java	(revision 23236)
@@ -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 23236)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/ifc/SmedPluggable.java	(revision 23236)
@@ -0,0 +1,17 @@
+package smed.plug.ifc;
+
+import javax.swing.JComponent;
+
+
+public interface SmedPluggable {
+
+    boolean start();
+    boolean stop();
+    String getName();
+    String getInfo();
+    JComponent getComponent();
+    
+    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 23236)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/ifc/SmedPluginManager.java	(revision 23236)
@@ -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 23236)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/util/JARFileFilter.java	(revision 23236)
@@ -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 23236)
+++ /applications/editors/josm/plugins/smed/src/smed/plug/util/SmedPluginLoader.java	(revision 23236)
@@ -0,0 +1,111 @@
+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.Arrays;
+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());
+		Arrays.sort(plugJars);
+		
+		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 23236)
+++ /applications/editors/josm/plugins/smed/src/smed/tabs/SmedTabAction.java	(revision 23236)
@@ -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 23236)
+++ /applications/editors/josm/plugins/smed/src/smed/tabs/SmedTabbedPane.java	(revision 23236)
@@ -0,0 +1,58 @@
+package smed.tabs;
+
+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.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;
+
+	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();
+		}
+		
+		if(plugins != null) {
+			Icon icon = null;
+			JTabbedPane tabbedPane = new JTabbedPane();
+
+			JComponent panel;
+			int i = 0;
+			for(SmedPluggable p : plugins) {
+				panel = p.getComponent();
+				tabbedPane.addTab(p.getName(),icon, panel, p.getInfo());
+				tabbedPane.setMnemonicAt(i, KeyEvent.VK_1 + i);
+			
+				i++;
+			}
+
+			//Add the tabbed pane to this panel.
+			add(tabbedPane);
+
+			//The following line enables to use scrolling tabs.
+			tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
+		}
+    }
+}
