Index: /applications/editors/josm/plugins/smed/src/seamarks/SeaMark.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/seamarks/SeaMark.java	(revision 29895)
+++ /applications/editors/josm/plugins/smed/src/seamarks/SeaMark.java	(revision 29895)
@@ -0,0 +1,2798 @@
+package seamarks;
+
+import javax.swing.*;
+
+import java.awt.*;
+import java.awt.geom.Arc2D;
+
+import java.util.*;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.*;
+import org.openstreetmap.josm.command.ChangePropertyCommand;
+
+import panels.PanelMain;
+
+import messages.Messages;
+import smed.SmedAction;
+
+public class SeaMark extends JPanel {
+
+	public SmedAction dlg = null;
+
+	public SeaMark(SmedAction dia) {
+		dlg = dia;
+		clrLight();
+	}
+
+	public enum Reg {
+		A, B, C, R, X
+	}
+
+	public static final EnumMap<Reg, String> RegSTR = new EnumMap<Reg, String>(Reg.class);
+	static {
+		RegSTR.put(Reg.A, "iala-a");
+		RegSTR.put(Reg.B, "iala-b");
+		RegSTR.put(Reg.C, "cevni");
+		RegSTR.put(Reg.R, "riwr");
+		RegSTR.put(Reg.X, "other");
+	}
+
+	private Reg region = Reg.A;
+
+	public Reg getRegion() {
+		return region;
+	}
+
+	public void setRegion(Reg reg) {
+		region = reg;
+	}
+
+	private String name = "";
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String str) {
+		name = str.trim();
+		repaint();
+	}
+	
+	public enum Obj {
+		UNKOBJ, BCNCAR, BCNISD, BCNLAT, BCNSAW, BCNSPP,
+		BOYCAR, BOYISD, BOYLAT, BOYSAW, BOYSPP, NOTMRK,
+		FLTCAR, FLTISD, FLTLAT, FLTSAW, FLTSPP,
+		LITMAJ, LITMIN, LITFLT, LITVES, LITHSE, LNDMRK,
+		MORFAC, BOYINB, SISTAW, SISTAT, OFSPLF,
+		CGUSTA, PILBOP, RSCSTA, RDOSTA, RADSTA
+	}
+
+	public static final EnumMap<Obj, String> ObjSTR = new EnumMap<Obj, String>(Obj.class);
+	static {
+		ObjSTR.put(Obj.BCNCAR, "beacon_cardinal");
+		ObjSTR.put(Obj.BCNISD, "beacon_isolated_danger");
+		ObjSTR.put(Obj.BCNLAT, "beacon_lateral");
+		ObjSTR.put(Obj.BCNSAW, "beacon_safe_water");
+		ObjSTR.put(Obj.BCNSPP, "beacon_special_purpose");
+		ObjSTR.put(Obj.BOYCAR, "buoy_cardinal");
+		ObjSTR.put(Obj.BOYISD, "buoy_isolated_danger");
+		ObjSTR.put(Obj.BOYLAT, "buoy_lateral");
+		ObjSTR.put(Obj.BOYSAW, "buoy_safe_water");
+		ObjSTR.put(Obj.BOYSPP, "buoy_special_purpose");
+		ObjSTR.put(Obj.FLTCAR, "light_float");
+		ObjSTR.put(Obj.FLTLAT, "light_float");
+		ObjSTR.put(Obj.FLTSAW, "light_float");
+		ObjSTR.put(Obj.FLTISD, "light_float");
+		ObjSTR.put(Obj.FLTSPP, "light_float");
+		ObjSTR.put(Obj.LITMAJ, "light_major");
+		ObjSTR.put(Obj.LITMIN, "light_minor");
+		ObjSTR.put(Obj.LITFLT, "light_float");
+		ObjSTR.put(Obj.LITVES, "light_vessel");
+		ObjSTR.put(Obj.NOTMRK, "notice");
+		ObjSTR.put(Obj.LNDMRK, "landmark");
+		ObjSTR.put(Obj.LITHSE, "landmark");
+		ObjSTR.put(Obj.MORFAC, "mooring");
+		ObjSTR.put(Obj.BOYINB, "buoy_installation");
+		ObjSTR.put(Obj.OFSPLF, "platform");
+		ObjSTR.put(Obj.SISTAW, "signal_station_warning");
+		ObjSTR.put(Obj.SISTAT, "signal_station_traffic");
+		ObjSTR.put(Obj.CGUSTA, "coastguard_station");
+		ObjSTR.put(Obj.PILBOP, "pilot_boarding");
+		ObjSTR.put(Obj.RSCSTA, "rescue_station");
+		ObjSTR.put(Obj.RDOSTA, "radio_station");
+		ObjSTR.put(Obj.RADSTA, "radar_station");
+	}
+
+	private Obj object = Obj.UNKOBJ;
+
+	public Obj getObject() {
+		return object;
+	}
+
+	public void setObject(Obj obj) {
+		object = obj;
+		if (obj == Obj.UNKOBJ) {
+			setCategory(Cat.NOCAT);
+			setFunc(Fnc.UNKFNC);
+			setShape(Shp.UNKSHP);
+			setColour(Ent.BODY, Col.UNKCOL);
+			setPattern(Ent.BODY, Pat.NOPAT);
+			setTopmark(Top.NOTOP);
+			setColour(Ent.TOPMARK, Col.UNKCOL);
+			setPattern(Ent.TOPMARK, Pat.NOPAT);
+		}
+		repaint();
+	}
+
+	public enum Ent {
+		BODY, BUOY, BEACON, LFLOAT, TOPMARK, LIGHT, MOORING, STATION, PLATFORM, NOTICE
+	}
+
+	public static final EnumMap<Obj, Ent> EntMAP = new EnumMap<Obj, Ent>(Obj.class);
+	static {
+		EntMAP.put(Obj.BCNCAR, Ent.BEACON);
+		EntMAP.put(Obj.BCNISD, Ent.BEACON);
+		EntMAP.put(Obj.BCNLAT, Ent.BEACON);
+		EntMAP.put(Obj.BCNSAW, Ent.BEACON);
+		EntMAP.put(Obj.BCNSPP, Ent.BEACON);
+		EntMAP.put(Obj.BOYCAR, Ent.BUOY);
+		EntMAP.put(Obj.BOYISD, Ent.BUOY);
+		EntMAP.put(Obj.BOYLAT, Ent.BUOY);
+		EntMAP.put(Obj.BOYSAW, Ent.BUOY);
+		EntMAP.put(Obj.BOYSPP, Ent.BUOY);
+		EntMAP.put(Obj.LITMAJ, Ent.LIGHT);
+		EntMAP.put(Obj.LITMIN, Ent.LIGHT);
+		EntMAP.put(Obj.LITFLT, Ent.LFLOAT);
+		EntMAP.put(Obj.FLTCAR, Ent.LFLOAT);
+		EntMAP.put(Obj.FLTLAT, Ent.LFLOAT);
+		EntMAP.put(Obj.FLTSAW, Ent.LFLOAT);
+		EntMAP.put(Obj.FLTISD, Ent.LFLOAT);
+		EntMAP.put(Obj.FLTSPP, Ent.LFLOAT);
+		EntMAP.put(Obj.LITVES, Ent.LFLOAT);
+		EntMAP.put(Obj.LITHSE, Ent.LIGHT);
+		EntMAP.put(Obj.LNDMRK, Ent.LIGHT);
+		EntMAP.put(Obj.MORFAC, Ent.MOORING);
+		EntMAP.put(Obj.BOYINB, Ent.MOORING);
+		EntMAP.put(Obj.OFSPLF, Ent.PLATFORM);
+		EntMAP.put(Obj.SISTAW, Ent.STATION);
+		EntMAP.put(Obj.SISTAT, Ent.STATION);
+		EntMAP.put(Obj.CGUSTA, Ent.STATION);
+		EntMAP.put(Obj.PILBOP, Ent.STATION);
+		EntMAP.put(Obj.RSCSTA, Ent.STATION);
+		EntMAP.put(Obj.RDOSTA, Ent.STATION);
+		EntMAP.put(Obj.RADSTA, Ent.STATION);
+		EntMAP.put(Obj.NOTMRK, Ent.NOTICE);
+	}
+
+	public enum Grp {
+		NUL, LAT, CAR, SAW, ISD, SPP, LGT, STN, PLF, NTC
+	}
+
+	public static final EnumMap<Obj, Grp> GrpMAP = new EnumMap<Obj, Grp>(Obj.class);
+	static {
+		GrpMAP.put(Obj.UNKOBJ, Grp.NUL);
+		GrpMAP.put(Obj.BCNCAR, Grp.CAR);
+		GrpMAP.put(Obj.BCNISD, Grp.ISD);
+		GrpMAP.put(Obj.BCNLAT, Grp.LAT);
+		GrpMAP.put(Obj.BCNSAW, Grp.SAW);
+		GrpMAP.put(Obj.BCNSPP, Grp.SPP);
+		GrpMAP.put(Obj.BOYCAR, Grp.CAR);
+		GrpMAP.put(Obj.BOYISD, Grp.ISD);
+		GrpMAP.put(Obj.BOYLAT, Grp.LAT);
+		GrpMAP.put(Obj.BOYSAW, Grp.SAW);
+		GrpMAP.put(Obj.BOYSPP, Grp.SPP);
+		GrpMAP.put(Obj.FLTCAR, Grp.CAR);
+		GrpMAP.put(Obj.FLTLAT, Grp.LAT);
+		GrpMAP.put(Obj.FLTSAW, Grp.SAW);
+		GrpMAP.put(Obj.FLTISD, Grp.ISD);
+		GrpMAP.put(Obj.FLTSPP, Grp.SPP);
+		GrpMAP.put(Obj.LITFLT, Grp.LGT);
+		GrpMAP.put(Obj.LITMAJ, Grp.LGT);
+		GrpMAP.put(Obj.LITMIN, Grp.LGT);
+		GrpMAP.put(Obj.LITVES, Grp.LGT);
+		GrpMAP.put(Obj.LITHSE, Grp.LGT);
+		GrpMAP.put(Obj.LNDMRK, Grp.LGT);
+		GrpMAP.put(Obj.MORFAC, Grp.SPP);
+		GrpMAP.put(Obj.BOYINB, Grp.SPP);
+		GrpMAP.put(Obj.OFSPLF, Grp.PLF);
+		GrpMAP.put(Obj.SISTAW, Grp.STN);
+		GrpMAP.put(Obj.SISTAT, Grp.STN);
+		GrpMAP.put(Obj.CGUSTA, Grp.STN);
+		GrpMAP.put(Obj.PILBOP, Grp.STN);
+		GrpMAP.put(Obj.RSCSTA, Grp.STN);
+		GrpMAP.put(Obj.RDOSTA, Grp.STN);
+		GrpMAP.put(Obj.RADSTA, Grp.STN);
+		GrpMAP.put(Obj.NOTMRK, Grp.NTC);
+	}
+
+	public enum Cat {
+		NOCAT, LAM_PORT, LAM_STBD, LAM_PPORT, LAM_PSTBD, CAM_NORTH, CAM_EAST, CAM_SOUTH, CAM_WEST,
+		ACH_URST, ACH_DEEP, ACH_TANK, ACH_EXPL, ACH_QUAR, ACH_SPLN, ACH_SCAN, ACH_SCMO, ACH_T24H, ACH_TLIM,
+		SPM_UNKN, SPM_WARN, SPM_CHBF, SPM_YCHT, SPM_CABL, SPM_OFAL, SPM_ODAS, SPM_RECN, SPM_MOOR, SPM_LNBY,
+		SPM_LDNG, SPM_NOTC, SPM_TSS, SPM_FOUL, SPM_DIVE, SPM_FRRY, SPM_ANCH,
+		MOR_DLPN, MOR_DDPN, MOR_BLRD, MOR_WALL, MOR_POST, MOR_CHWR, MOR_ROPE, MOR_AUTO, MOR_BUOY, INB_CALM, INB_SBM,
+		SIS_PTCL, SIS_PTED, SIS_IPT, SIS_BRTH, SIS_DOCK, SIS_LOCK, SIS_FBAR, SIS_BRDG, SIS_DRDG, SIS_TRFC,
+		SIS_DNGR, SIS_OBST, SIS_CABL, SIS_MILY, SIS_DSTR, SIS_WTHR, SIS_STRM, SIS_ICE, SIS_TIME, SIS_TIDE,
+		SIS_TSTM, SIS_TGAG, SIS_TSCL, SIS_DIVE, SIS_LGAG, LIT_DIRF, LIT_LEDG,
+		LMK_CHMY, LMK_CARN, LMK_DSHA, LMK_FLGS, LMK_FLRS, LMK_MNMT, LMK_TOWR, LMK_WNDM, LMK_WTRT, LMK_MNRT,
+		LMK_MAST, LMK_WNDS, LMK_CLMN, LMK_OBLK, LMK_STAT, LMK_CROS, LMK_DOME, LMK_SCNR, LMK_WNDL, LMK_SPIR,
+		OFP_OIL, OFP_PRD, OFP_OBS, OFP_ALP, OFP_SALM, OFP_MOR, OFP_ISL, OFP_FPSO, OFP_ACC, OFP_NCCB,
+		RSC_LFB, RSC_RKT, RSC_RSW, RSC_RIT, RSC_MLB, RSC_RAD, RSC_FAE, RSC_SPL, RSC_AIR, RSC_TUG,
+		RAS_SRV, RAS_CST, PIL_VESS, PIL_HELI, PIL_SHORE,
+		NTC_A1, NTC_A1a, NTC_A2, NTC_A3, NTC_A4, NTC_A4_1, NTC_A5, NTC_A5_1, NTC_A6, NTC_A7, NTC_A8, NTC_A9,
+		NTC_A10a, NTC_A10b, NTC_A12, NTC_A13, NTC_A14, NTC_A15, NTC_A16, NTC_A17, NTC_A18, NTC_A19, NTC_A20,
+		NTC_B1a, NTC_B1b, NTC_B2a, NTC_B2b, NTC_B3a, NTC_B3b, NTC_B4a, NTC_B4b, NTC_B5, NTC_B6, NTC_B7, NTC_B8, NTC_B9a, NTC_B9b, NTC_B11,
+		NTC_C1, NTC_C2, NTC_C3, NTC_C4, NTC_C5a, NTC_C5b, NTC_D1a, NTC_D1b, NTC_D2a, NTC_D2b, NTC_D3a, NTC_D3b,
+		NOROS, ROS_UNKN, ROS_OMNI, ROS_DIRL, ROS_ROTP, ROS_CNSL, ROS_RDF, ROS_QTG, ROS_AERO, ROS_DECA, ROS_LORN, ROS_DGPS, ROS_TORN, ROS_OMGA, ROS_SYLD, ROS_CHKA,
+		ROS_PCOM, ROS_COMB, ROS_FACS, ROS_TIME, ROS_PAIS, ROS_SAIS, ROS_VAIS, ROS_VANC, ROS_VASC, ROS_VAEC, ROS_VAWC, ROS_VAPL, ROS_VASL, ROS_VAID, ROS_VASW, ROS_VASP, ROS_VAWK
+	}
+		 
+	public static final EnumMap<Cat, String> CatSTR = new EnumMap<Cat, String>(Cat.class);
+	static {
+		CatSTR.put(Cat.LAM_PORT, "port");
+		CatSTR.put(Cat.LAM_STBD, "starboard");
+		CatSTR.put(Cat.LAM_PPORT, "preferred_channel_port");
+		CatSTR.put(Cat.LAM_PSTBD, "preferred_channel_starboard");
+		CatSTR.put(Cat.CAM_NORTH, "north");
+		CatSTR.put(Cat.CAM_EAST, "east");
+		CatSTR.put(Cat.CAM_SOUTH, "south");
+		CatSTR.put(Cat.CAM_WEST, "west");
+		CatSTR.put(Cat.SPM_UNKN, "unknown_purpose");
+		CatSTR.put(Cat.SPM_WARN, "warning");
+		CatSTR.put(Cat.SPM_CHBF, "channel_separation");
+		CatSTR.put(Cat.SPM_YCHT, "yachting");
+		CatSTR.put(Cat.SPM_CABL, "cable");
+		CatSTR.put(Cat.SPM_OFAL, "outfall");
+		CatSTR.put(Cat.SPM_ODAS, "odas");
+		CatSTR.put(Cat.SPM_RECN, "recreational");
+		CatSTR.put(Cat.SPM_MOOR, "mooring");
+		CatSTR.put(Cat.SPM_LNBY, "lanby");
+		CatSTR.put(Cat.SPM_LDNG, "leading");
+		CatSTR.put(Cat.SPM_NOTC, "notice");
+		CatSTR.put(Cat.SPM_TSS, "tss");
+		CatSTR.put(Cat.SPM_FOUL, "foul");
+		CatSTR.put(Cat.SPM_DIVE, "diving");
+		CatSTR.put(Cat.SPM_FRRY, "ferry");
+		CatSTR.put(Cat.SPM_ANCH, "anchorage");
+		CatSTR.put(Cat.MOR_DLPN, "dolphin");
+		CatSTR.put(Cat.MOR_DDPN, "deviation_dolphin");
+		CatSTR.put(Cat.MOR_BLRD, "bollard");
+		CatSTR.put(Cat.MOR_WALL, "wall");
+		CatSTR.put(Cat.MOR_POST, "post");
+		CatSTR.put(Cat.MOR_CHWR, "chain");
+		CatSTR.put(Cat.MOR_ROPE, "shore_rope");
+		CatSTR.put(Cat.MOR_AUTO, "automatic");
+		CatSTR.put(Cat.MOR_BUOY, "buoy");
+		CatSTR.put(Cat.INB_CALM, "calm");
+		CatSTR.put(Cat.INB_SBM, "sbm");
+		CatSTR.put(Cat.SIS_PTCL, "port_control");
+		CatSTR.put(Cat.SIS_PTED, "port_entry");
+		CatSTR.put(Cat.SIS_IPT, "ipt");
+		CatSTR.put(Cat.SIS_BRTH, "berthing");
+		CatSTR.put(Cat.SIS_DOCK, "dock");
+		CatSTR.put(Cat.SIS_LOCK, "lock");
+		CatSTR.put(Cat.SIS_FBAR, "barrage");
+		CatSTR.put(Cat.SIS_BRDG, "bridge");
+		CatSTR.put(Cat.SIS_DRDG, "dredging");
+		CatSTR.put(Cat.SIS_TRFC, "traffic");
+		CatSTR.put(Cat.SIS_DNGR, "danger");
+		CatSTR.put(Cat.SIS_OBST, "obstruction");
+		CatSTR.put(Cat.SIS_CABL, "cable");
+		CatSTR.put(Cat.SIS_MILY, "military");
+		CatSTR.put(Cat.SIS_DSTR, "distress");
+		CatSTR.put(Cat.SIS_WTHR, "weather");
+		CatSTR.put(Cat.SIS_STRM, "storm");
+		CatSTR.put(Cat.SIS_ICE, "ice");
+		CatSTR.put(Cat.SIS_TIME, "time");
+		CatSTR.put(Cat.SIS_TIDE, "tide");
+		CatSTR.put(Cat.SIS_TSTM, "stream");
+		CatSTR.put(Cat.SIS_TGAG, "gauge");
+		CatSTR.put(Cat.SIS_TSCL, "scale");
+		CatSTR.put(Cat.SIS_DIVE, "diving");
+		CatSTR.put(Cat.SIS_LGAG, "level");
+		CatSTR.put(Cat.LMK_CHMY, "chimney");
+		CatSTR.put(Cat.LMK_CARN, "cairn");
+		CatSTR.put(Cat.LMK_DSHA, "dish_aerial");
+		CatSTR.put(Cat.LMK_FLGS, "flagstaff");
+		CatSTR.put(Cat.LMK_FLRS, "flare_stack");
+		CatSTR.put(Cat.LMK_MNMT, "monument");
+		CatSTR.put(Cat.LMK_TOWR, "tower");
+		CatSTR.put(Cat.LMK_WNDM, "windmotor");
+		CatSTR.put(Cat.LMK_WTRT, "water_tower");
+		CatSTR.put(Cat.LMK_MAST, "mast");
+		CatSTR.put(Cat.LMK_WNDS, "windsock");
+		CatSTR.put(Cat.LMK_CLMN, "column");
+		CatSTR.put(Cat.LMK_OBLK, "obelisk");
+		CatSTR.put(Cat.LMK_STAT, "statue");
+		CatSTR.put(Cat.LMK_CROS, "cross");
+		CatSTR.put(Cat.LMK_DOME, "dome");
+		CatSTR.put(Cat.LMK_SCNR, "radar_scanner");
+		CatSTR.put(Cat.LMK_WNDL, "windmill");
+		CatSTR.put(Cat.LMK_SPIR, "spire");
+		CatSTR.put(Cat.LMK_MNRT, "minaret");
+		CatSTR.put(Cat.OFP_OIL, "oil");
+		CatSTR.put(Cat.OFP_PRD,  "production");
+		CatSTR.put(Cat.OFP_OBS, "observation"); 
+		CatSTR.put(Cat.OFP_ALP, "alp");
+		CatSTR.put(Cat.OFP_SALM, "salm");
+		CatSTR.put(Cat.OFP_MOR, "mooring");
+		CatSTR.put(Cat.OFP_ISL, "island");
+		CatSTR.put(Cat.OFP_FPSO, "fpso");
+		CatSTR.put(Cat.OFP_ACC, "accommodation");
+		CatSTR.put(Cat.OFP_NCCB, "nccb");
+		CatSTR.put(Cat.PIL_VESS, "cruising_vessel");
+		CatSTR.put(Cat.PIL_HELI, "helicopter");
+		CatSTR.put(Cat.PIL_SHORE, "from_shore");
+		CatSTR.put(Cat.RSC_LFB, "lifeboat");
+		CatSTR.put(Cat.RSC_RKT, "rocket");
+		CatSTR.put(Cat.RSC_RSW, "refuge_shipwrecked");
+		CatSTR.put(Cat.RSC_RIT, "refuge_intertidal");
+		CatSTR.put(Cat.RSC_MLB, "lifeboat_moored");
+		CatSTR.put(Cat.RSC_RAD, "radio");
+		CatSTR.put(Cat.RSC_FAE, "firstaid");
+		CatSTR.put(Cat.RSC_SPL, "seaplane");
+		CatSTR.put(Cat.RSC_AIR, "aircraft");
+		CatSTR.put(Cat.RSC_TUG, "tug");
+		CatSTR.put(Cat.RAS_SRV, "surveillance");
+		CatSTR.put(Cat.RAS_CST, "coast");
+		CatSTR.put(Cat.ROS_OMNI, "omnidirectional");
+		CatSTR.put(Cat.ROS_DIRL, "directional");
+		CatSTR.put(Cat.ROS_ROTP, "rotating_pattern");
+		CatSTR.put(Cat.ROS_CNSL, "consol");
+		CatSTR.put(Cat.ROS_RDF, "rdf");
+		CatSTR.put(Cat.ROS_QTG, "qtg");
+		CatSTR.put(Cat.ROS_AERO, "aeronautical");
+		CatSTR.put(Cat.ROS_DECA, "decca");
+		CatSTR.put(Cat.ROS_LORN, "loran");
+		CatSTR.put(Cat.ROS_DGPS, "dgps");
+		CatSTR.put(Cat.ROS_TORN, "toran");
+		CatSTR.put(Cat.ROS_OMGA, "omega");
+		CatSTR.put(Cat.ROS_SYLD, "syledis");
+		CatSTR.put(Cat.ROS_CHKA, "chiaka");
+		CatSTR.put(Cat.ROS_PCOM, "public_communication");
+		CatSTR.put(Cat.ROS_COMB, "commercial_broadcast");
+		CatSTR.put(Cat.ROS_FACS, "facsimile");
+		CatSTR.put(Cat.ROS_TIME, "time_signal");
+		CatSTR.put(Cat.ROS_PAIS, "ais");
+		CatSTR.put(Cat.ROS_SAIS, "s-ais");
+		CatSTR.put(Cat.ROS_VAIS, "v-ais");
+		CatSTR.put(Cat.ROS_VANC, "v-ais_north_cardinal");
+		CatSTR.put(Cat.ROS_VASC, "v-ais_south_cardinal");
+		CatSTR.put(Cat.ROS_VAEC, "v-ais_east_cardinal");
+		CatSTR.put(Cat.ROS_VAWC, "v-ais_west_cardinal");
+		CatSTR.put(Cat.ROS_VAPL, "v-ais_port_lateral");
+		CatSTR.put(Cat.ROS_VASL, "v-ais_starboard_lateral");
+		CatSTR.put(Cat.ROS_VAID, "v-ais_isolated_danger");
+		CatSTR.put(Cat.ROS_VASW, "v-ais_safe_water");
+		CatSTR.put(Cat.ROS_VASP, "v-ais_special_purpose");
+		CatSTR.put(Cat.ROS_VAWK, "v-ais_wreck"); 
+		CatSTR.put(Cat.NTC_A1, "no_entry");
+		CatSTR.put(Cat.NTC_A1a, "closed_area");
+		CatSTR.put(Cat.NTC_A2, "no_overtaking");
+		CatSTR.put(Cat.NTC_A3, "no_convoy_overtaking");
+		CatSTR.put(Cat.NTC_A4, "no_passing");
+		CatSTR.put(Cat.NTC_A4, "no_convoy_passing");
+		CatSTR.put(Cat.NTC_A5, "no_berthing");
+		CatSTR.put(Cat.NTC_A5_1, "no_berthing_lateral_limit");
+		CatSTR.put(Cat.NTC_A6, "no_anchoring");
+		CatSTR.put(Cat.NTC_A7, "no_mooring");
+		CatSTR.put(Cat.NTC_A8, "no_turning");
+		CatSTR.put(Cat.NTC_A9, "no_wash");
+		CatSTR.put(Cat.NTC_A10a, "no_passage_left");
+		CatSTR.put(Cat.NTC_A10b, "no_passage_right");
+		CatSTR.put(Cat.NTC_A12, "no_motor_craft");
+		CatSTR.put(Cat.NTC_A13, "no_sport_craft");
+		CatSTR.put(Cat.NTC_A14, "no_waterskiing");
+		CatSTR.put(Cat.NTC_A15, "no_sailing_craft");
+		CatSTR.put(Cat.NTC_A16, "no_unpowered_craft");
+		CatSTR.put(Cat.NTC_A17, "no_sailboards");
+		CatSTR.put(Cat.NTC_A18, "no_high_speeds");
+		CatSTR.put(Cat.NTC_A19, "no_launching_beaching");
+		CatSTR.put(Cat.NTC_A20, "no_waterbikes");
+		CatSTR.put(Cat.NTC_B1a, "");
+		CatSTR.put(Cat.NTC_B1b, "");
+		CatSTR.put(Cat.NTC_B2a, "");
+		CatSTR.put(Cat.NTC_B2a, "");
+		CatSTR.put(Cat.NTC_B3a, "");
+		CatSTR.put(Cat.NTC_B3a, "");
+		CatSTR.put(Cat.NTC_B4a, "");
+		CatSTR.put(Cat.NTC_B4a, "");
+		CatSTR.put(Cat.NTC_B5, "");
+		CatSTR.put(Cat.NTC_B6, "");
+		CatSTR.put(Cat.NTC_B7, "");
+		CatSTR.put(Cat.NTC_B8, "");
+		CatSTR.put(Cat.NTC_B9a, "");
+		CatSTR.put(Cat.NTC_B9b, "");
+		CatSTR.put(Cat.NTC_B11, "");
+		CatSTR.put(Cat.NTC_C1, "");
+		CatSTR.put(Cat.NTC_C2, "");
+		CatSTR.put(Cat.NTC_C3, "");
+		CatSTR.put(Cat.NTC_C4, "");
+		CatSTR.put(Cat.NTC_C5a, "");
+		CatSTR.put(Cat.NTC_C5b, "");
+		CatSTR.put(Cat.NTC_D1a, "");
+		CatSTR.put(Cat.NTC_D1b, "");
+		CatSTR.put(Cat.NTC_D2a, "");
+		CatSTR.put(Cat.NTC_D2b, "");
+		CatSTR.put(Cat.NTC_D3a, "");
+		CatSTR.put(Cat.NTC_D3b, "");
+	}
+
+	private Cat category = Cat.NOCAT;
+
+	public Cat getCategory() {
+		return category;
+	}
+
+	public void setCategory(Cat cat) {
+		category = cat;
+		repaint();
+	}
+
+	public enum Shp {
+		UNKSHP, PILLAR, SPAR, CAN, CONI, SPHERI, BARREL, FLOAT, SUPER, BUOYANT, CAIRN, PILE, LATTICE, TOWER, STAKE, POLE, POST, PERCH, BUOY, BEACON
+	}
+
+	public static final EnumMap<Shp, String> ShpSTR = new EnumMap<Shp, String>(Shp.class);
+	static {
+		ShpSTR.put(Shp.PILLAR, "pillar");
+		ShpSTR.put(Shp.SPAR, "spar");
+		ShpSTR.put(Shp.CAN, "can");
+		ShpSTR.put(Shp.CONI, "conical");
+		ShpSTR.put(Shp.SPHERI, "spherical");
+		ShpSTR.put(Shp.BARREL, "barrel");
+		ShpSTR.put(Shp.FLOAT, "float");
+		ShpSTR.put(Shp.SUPER, "super-buoy");
+		ShpSTR.put(Shp.BUOYANT, "buoyant");
+		ShpSTR.put(Shp.CAIRN, "cairn");
+		ShpSTR.put(Shp.PILE, "pile");
+		ShpSTR.put(Shp.LATTICE, "lattice");
+		ShpSTR.put(Shp.TOWER, "tower");
+		ShpSTR.put(Shp.STAKE, "stake");
+		ShpSTR.put(Shp.PERCH, "perch");
+	}
+
+	private Shp shape = Shp.UNKSHP;
+
+	public Shp getShape() {
+		return shape;
+	}
+
+	public void setShape(Shp shp) {
+		shape = shp;
+		repaint();
+	}
+
+	public enum Col {
+		UNKCOL, BLANK, WHITE, RED, ORANGE, AMBER, YELLOW, GREEN, BLUE, VIOLET, BLACK, GREY, BROWN, MAGENTA, PINK
+	}
+
+	public static final EnumMap<Col, Color> ColMAP = new EnumMap<Col, Color>(Col.class);
+	static {
+		ColMAP.put(Col.UNKCOL, new Color(0xc0c0c0));
+		ColMAP.put(Col.WHITE, Color.WHITE);
+		ColMAP.put(Col.RED, Color.RED);
+		ColMAP.put(Col.ORANGE, Color.ORANGE);
+		ColMAP.put(Col.AMBER, new Color(0xfbf00f));
+		ColMAP.put(Col.YELLOW, Color.YELLOW);
+		ColMAP.put(Col.GREEN, Color.GREEN);
+		ColMAP.put(Col.BLUE, Color.BLUE);
+		ColMAP.put(Col.VIOLET, new Color(0x8f00ff));
+		ColMAP.put(Col.BLACK, Color.BLACK);
+		ColMAP.put(Col.GREY, Color.GRAY);
+		ColMAP.put(Col.BROWN, new Color(0xa45a58));
+		ColMAP.put(Col.MAGENTA, Color.MAGENTA);
+		ColMAP.put(Col.PINK, Color.PINK);
+	}
+
+	public static final EnumMap<Col, String> ColSTR = new EnumMap<Col, String>(Col.class);
+	static {
+		ColSTR.put(Col.WHITE, "white");
+		ColSTR.put(Col.RED, "red");
+		ColSTR.put(Col.ORANGE, "orange");
+		ColSTR.put(Col.AMBER, "amber");
+		ColSTR.put(Col.YELLOW, "yellow");
+		ColSTR.put(Col.GREEN, "green");
+		ColSTR.put(Col.BLUE, "blue");
+		ColSTR.put(Col.VIOLET, "violet");
+		ColSTR.put(Col.BLACK, "black");
+		ColSTR.put(Col.GREY, "grey");
+		ColSTR.put(Col.BROWN, "brown");
+		ColSTR.put(Col.MAGENTA, "magenta");
+		ColSTR.put(Col.PINK, "pink");
+	}
+
+	public Col getColour(Ent ent, int idx) {
+		if (ent == Ent.BODY)
+			return getObjColour(idx);
+		else
+			return getTopColour(idx);
+	}
+
+	public void setColour(Ent ent, Col col) {
+		if (ent == Ent.BODY)
+			setObjColour(col);
+		else
+			setTopColour(col);
+	}
+
+	public void setColour(Ent ent, int idx, Col col) {
+		if (ent == Ent.BODY)
+			setObjColour(idx, col);
+		else
+			setTopColour(idx, col);
+	}
+
+	public void addColour(Ent ent, int idx, Col col) {
+		if (ent == Ent.BODY)
+			addObjColour(idx, col);
+		else
+			addTopColour(idx, col);
+	}
+
+	public void subColour(Ent ent, int idx) {
+		if (ent == Ent.BODY)
+			subObjColour(idx);
+		else
+			subTopColour(idx);
+	}
+
+	private ArrayList<Col> bodyColour = new ArrayList<Col>();
+
+	public Col getObjColour(int i) {
+		if (i < bodyColour.size())
+			return bodyColour.get(i);
+		else
+			return Col.UNKCOL;
+	}
+
+	public void setObjColour(Col col) {
+		bodyColour.clear();
+		bodyColour.add(col);
+		repaint();
+	}
+
+	public void setObjColour(int i, Col col) {
+		if (i < bodyColour.size())
+			bodyColour.set(i, col);
+		repaint();
+	}
+
+	public void addObjColour(int i, Col col) {
+		if (bodyColour.size() >= i)
+			bodyColour.add(i, col);
+		repaint();
+	}
+
+	public void addObjColour(Col col) {
+		bodyColour.add(col);
+		repaint();
+	}
+
+	public void subObjColour(int i) {
+		if (bodyColour.size() > i)
+			bodyColour.remove(i);
+		repaint();
+	}
+
+	private ArrayList<Col> topmarkColour = new ArrayList<Col>();
+
+	public Col getTopColour(int i) {
+		if (i < topmarkColour.size())
+			return topmarkColour.get(i);
+		else
+			return Col.UNKCOL;
+	}
+
+	public void setTopColour(Col col) {
+		topmarkColour.clear();
+		topmarkColour.add(col);
+		repaint();
+	}
+
+	public void setTopColour(int i, Col col) {
+		if (topmarkColour.size() > i)
+			topmarkColour.set(i, col);
+		repaint();
+	}
+
+	public void addTopColour(int i, Col col) {
+		if (topmarkColour.size() >= i)
+			topmarkColour.add(i, col);
+		repaint();
+	}
+
+	public void addTopColour(Col col) {
+		topmarkColour.add(col);
+		repaint();
+	}
+
+	public void subTopColour(int i) {
+		if (topmarkColour.size() > i)
+			topmarkColour.remove(i);
+		repaint();
+	}
+
+	public enum Chr {
+		UNKCHR, FIXED, FLASH, LFLASH, QUICK, VQUICK, UQUICK, ISOPHASED, OCCULTING, MORSE, ALTERNATING, IQUICK, IVQUICK, IUQUICK
+	}
+
+	public static final Map<EnumSet<Chr>, String> ChrMAP = new HashMap<EnumSet<Chr>, String>();
+	static {
+		ChrMAP.put(EnumSet.of(Chr.FIXED), "F");
+		ChrMAP.put(EnumSet.of(Chr.FLASH), "Fl");
+		ChrMAP.put(EnumSet.of(Chr.LFLASH), "LFl");
+		ChrMAP.put(EnumSet.of(Chr.QUICK), "Q");
+		ChrMAP.put(EnumSet.of(Chr.VQUICK), "VQ");
+		ChrMAP.put(EnumSet.of(Chr.UQUICK), "UQ");
+		ChrMAP.put(EnumSet.of(Chr.ISOPHASED), "Iso");
+		ChrMAP.put(EnumSet.of(Chr.OCCULTING), "Oc");
+		ChrMAP.put(EnumSet.of(Chr.IQUICK), "IQ");
+		ChrMAP.put(EnumSet.of(Chr.IVQUICK), "IVQ");
+		ChrMAP.put(EnumSet.of(Chr.IUQUICK), "IUQ");
+		ChrMAP.put(EnumSet.of(Chr.MORSE), "Mo");
+		ChrMAP.put(EnumSet.of(Chr.FIXED, Chr.FLASH), "FFl");
+		ChrMAP.put(EnumSet.of(Chr.FLASH, Chr.LFLASH), "FlLFl");
+		ChrMAP.put(EnumSet.of(Chr.FIXED, Chr.OCCULTING), "FOc");
+		ChrMAP.put(EnumSet.of(Chr.FIXED, Chr.LFLASH), "FLFl");
+		ChrMAP.put(EnumSet.of(Chr.OCCULTING, Chr.FLASH), "OcFl");
+		ChrMAP.put(EnumSet.of(Chr.QUICK, Chr.LFLASH), "Q+LFl");
+		ChrMAP.put(EnumSet.of(Chr.VQUICK, Chr.LFLASH), "VQ+LFl");
+		ChrMAP.put(EnumSet.of(Chr.UQUICK, Chr.LFLASH), "UQ+LFl");
+		ChrMAP.put(EnumSet.of(Chr.ALTERNATING), "Al");
+		ChrMAP.put(EnumSet.of(Chr.ALTERNATING, Chr.OCCULTING), "Al.Oc");
+		ChrMAP.put(EnumSet.of(Chr.ALTERNATING, Chr.LFLASH), "Al.LFl");
+		ChrMAP.put(EnumSet.of(Chr.ALTERNATING, Chr.FLASH), "Al.Fl");
+		ChrMAP.put(EnumSet.of(Chr.ALTERNATING, Chr.FIXED), "Al.F");
+		ChrMAP.put(EnumSet.of(Chr.ALTERNATING, Chr.FIXED, Chr.FLASH), "Al.FFl");
+		ChrMAP.put(EnumSet.of(Chr.ALTERNATING, Chr.ISOPHASED), "Al.Iso");
+	}
+
+	public enum Vis {
+		UNKVIS, HIGH, LOW, FAINT, INTEN, UNINTEN, REST, OBS, PARTOBS
+	}
+
+	public static final EnumMap<Vis, String> VisSTR = new EnumMap<Vis, String>(Vis.class);
+	static {
+		VisSTR.put(Vis.HIGH, "high");
+		VisSTR.put(Vis.LOW, "low");
+		VisSTR.put(Vis.FAINT, "faint");
+		VisSTR.put(Vis.INTEN, "intensified");
+		VisSTR.put(Vis.UNINTEN, "unintensified");
+		VisSTR.put(Vis.REST, "restricted");
+		VisSTR.put(Vis.OBS, "obscured");
+		VisSTR.put(Vis.PARTOBS, "part_obscured");
+	}
+
+	public enum Lit {
+		UNKLIT, VERT, HORIZ, DIR, UPPER, LOWER, LEAD, REAR, FRONT, AERO, AIROBS, FOGDET, FLOOD, STRIP, SUBS, SPOT, MOIRE, EMERG, BEAR
+	}
+
+	public static final EnumMap<Lit, String> LitSTR = new EnumMap<Lit, String>(Lit.class);
+	static {
+		LitSTR.put(Lit.VERT, "vertical");
+		LitSTR.put(Lit.HORIZ, "horizontal");
+		LitSTR.put(Lit.DIR, "directional");
+		LitSTR.put(Lit.UPPER, "upper");
+		LitSTR.put(Lit.LOWER, "lower");
+		LitSTR.put(Lit.LEAD, "leading");
+		LitSTR.put(Lit.REAR, "rear");
+		LitSTR.put(Lit.FRONT, "front");
+		LitSTR.put(Lit.AERO, "aero");
+		LitSTR.put(Lit.AIROBS, "air_obstruction");
+		LitSTR.put(Lit.FOGDET, "fog_detector");
+		LitSTR.put(Lit.FLOOD, "floodlight");
+		LitSTR.put(Lit.STRIP, "striplight");
+		LitSTR.put(Lit.SUBS, "subsidairy");
+		LitSTR.put(Lit.SPOT, "spotlight");
+		LitSTR.put(Lit.MOIRE, "moire");
+		LitSTR.put(Lit.EMERG, "emergency");
+		LitSTR.put(Lit.BEAR, "bearing");
+	}
+
+	public enum Exh {
+		UNKEXH, H24, DAY, NIGHT, FOG, WARN, STORM
+	}
+
+	public static final EnumMap<Exh, String> ExhSTR = new EnumMap<Exh, String>(Exh.class);
+	static {
+		ExhSTR.put(Exh.H24, "24h");
+		ExhSTR.put(Exh.DAY, "day");
+		ExhSTR.put(Exh.NIGHT, "night");
+		ExhSTR.put(Exh.FOG, "fog");
+		ExhSTR.put(Exh.WARN, "warning");
+		ExhSTR.put(Exh.STORM, "storm");
+	}
+
+	public enum Att {
+		COL, CHR, GRP, SEQ, PER, LIT, BEG, END, RAD, HGT, RNG, VIS, EXH, ORT, MLT, ALT
+	}
+
+	public Object[] sector = { Col.UNKCOL, "", "", "", "", Lit.UNKLIT, "", "",
+			"", "", "", Vis.UNKVIS, Exh.UNKEXH, "", "", Col.UNKCOL };
+
+	private ArrayList<Object[]> sectors = new ArrayList<Object[]>();
+
+	public int getSectorCount() {
+		return sectors.size();
+	}
+
+	public boolean isSectored() {
+		return (sectors.size() > 1);
+	}
+
+	public Object getLightAtt(Att att, int i) {
+		return getLightAtt(att.ordinal(), i);
+	}
+
+	public Object getLightAtt(int att, int i) {
+		if (i < sectors.size())
+			return sectors.get(i)[att];
+		else
+			return null;
+	}
+
+	public void setLightAtt(Att att, int i, Object obj) {
+		setLightAtt(att.ordinal(), i, obj);
+	}
+
+	public void setLightAtt(int att, int i, Object obj) {
+		if (sectors.size() == i)
+			addLight(i);
+		if (sectors.size() > i)
+			switch (att) {
+			case 4:
+			case 8:
+			case 9:
+			case 10:
+				sectors.get(i)[att] = validDecimal((String)obj);
+				break;
+			case 6:
+			case 7:
+			case 13:
+				sectors.get(i)[att] = validDecimal((String)obj, 360);
+				break;
+			default:
+				sectors.get(i)[att] = obj;
+			}
+		repaint();
+	}
+
+	public void addLight(int i) {
+		if (sectors.size() >= i) {
+			if (sectors.size() == 0)
+				sectors.add(sector.clone());
+			else
+				sectors.add(i, sectors.get(0).clone());
+		}
+	}
+
+	public void nulLight(int i) {
+		if (i == 0) {
+			clrLight();
+		} else {
+			sectors.add(i, sector.clone());
+		}
+	}
+
+	public void addLight() {
+		if (sectors.size() == 0)
+			sectors.add(sector.clone());
+		else
+			sectors.add(sectors.get(0).clone());
+	}
+
+	public void delLight(int i) {
+		if (sectors.size() > i)
+			sectors.remove(i);
+		repaint();
+	}
+
+	public void clrLight() {
+		sectors.clear();
+		addLight();
+		setLightRef("");
+		repaint();
+	}
+
+	public enum Pat {
+		NOPAT, HSTRP, VSTRP, DIAG, SQUARED, BORDER, CROSS, SALTIRE
+	}
+
+	public static final EnumMap<Pat, String> PatSTR = new EnumMap<Pat, String>(Pat.class);
+	static {
+		PatSTR.put(Pat.HSTRP, "horizontal");
+		PatSTR.put(Pat.VSTRP, "vertical");
+		PatSTR.put(Pat.DIAG, "diagonal");
+		PatSTR.put(Pat.SQUARED, "squared");
+		PatSTR.put(Pat.BORDER, "border");
+		PatSTR.put(Pat.CROSS, "cross");
+		PatSTR.put(Pat.SALTIRE, "saltire");
+	}
+
+	public Pat getPattern(Ent ent) {
+		if (ent == Ent.BODY)
+			return getObjPattern();
+		else
+			return getTopPattern();
+	}
+
+	public void setPattern(Ent ent, Pat pat) {
+		if (ent == Ent.BODY)
+			setObjPattern(pat);
+		else
+			setTopPattern(pat);
+	}
+
+	private Pat bodyPattern = Pat.NOPAT;
+
+	public Pat getObjPattern() {
+		return bodyPattern;
+	}
+
+	public void setObjPattern(Pat pat) {
+		bodyPattern = pat;
+	}
+
+	private Pat topPattern = Pat.NOPAT;
+
+	public Pat getTopPattern() {
+		return topPattern;
+	}
+
+	public void setTopPattern(Pat pat) {
+		topPattern = pat;
+	}
+
+	public enum Top {
+		NOTOP, CYL, CONE, SPHERE, X_SHAPE, NORTH, SOUTH, EAST, WEST, SPHERES2, BOARD, RHOMBUS, CIRCLE, TRIANGLE, TRIANGLE_INV, SQUARE
+	}
+
+	public static final EnumMap<Top, String> TopSTR = new EnumMap<Top, String>(Top.class);
+	static {
+		TopSTR.put(Top.CYL, "cylinder");
+		TopSTR.put(Top.CONE, "cone, point up");
+		TopSTR.put(Top.SPHERE, "sphere");
+		TopSTR.put(Top.X_SHAPE, "x-shape");
+		TopSTR.put(Top.NORTH, "2 cones up");
+		TopSTR.put(Top.SOUTH, "2 cones down");
+		TopSTR.put(Top.EAST, "2 cones base together");
+		TopSTR.put(Top.WEST, "2 cones point together");
+		TopSTR.put(Top.SPHERES2, "2 spheres");
+		TopSTR.put(Top.BOARD, "board");
+		TopSTR.put(Top.RHOMBUS, "rhombus");
+		TopSTR.put(Top.CIRCLE, "circle");
+		TopSTR.put(Top.TRIANGLE, "triangle, point up");
+		TopSTR.put(Top.TRIANGLE_INV, "triangle, point down");
+		TopSTR.put(Top.SQUARE, "square");
+	}
+
+	private Top topShape = Top.NOTOP;
+
+	public Top getTopmark() {
+		return topShape;
+	}
+
+	public void setTopmark(Top top) {
+		topShape = top;
+		repaint();
+	}
+
+	private Cat RoType = Cat.NOROS;
+
+	public Cat getRadio() {
+		return RoType;
+	}
+
+	public void setRadio(Cat type) {
+		RoType = type;
+		repaint();
+	}
+
+	public enum Rtb {
+		NORTB, REFLECTOR, RACON, RAMARK, LEADING
+	}
+
+	public static final EnumMap<Rtb, String> RtbSTR = new EnumMap<Rtb, String>(Rtb.class);
+	static {
+		RtbSTR.put(Rtb.RACON, "racon");
+		RtbSTR.put(Rtb.RAMARK, "ramark");
+		RtbSTR.put(Rtb.LEADING, "leading");
+	}
+
+	private Rtb RaType = Rtb.NORTB;
+
+	public Rtb getRadar() {
+		return RaType;
+	}
+
+	public void setRadar(Rtb type) {
+		RaType = type;
+		if (type == Rtb.NORTB) {
+			setRaconGroup("");
+			setRaconSequence("");
+			setRaconPeriod("");
+			setRaconRange("");
+			setRaconSector1("");
+			setRaconSector2("");
+		}
+		repaint();
+	}
+
+	private String raconGroup = "";
+
+	public String getRaconGroup() {
+		return raconGroup;
+	}
+
+	public void setRaconGroup(String grp) {
+		raconGroup = grp;
+		repaint();
+	}
+
+	private String raconSequence = "";
+
+	public String getRaconSequence() {
+		return raconSequence;
+	}
+
+	public void setRaconSequence(String seq) {
+		raconSequence = seq;
+		repaint();
+	}
+
+	private String raconPeriod = "";
+
+	public String getRaconPeriod() {
+		return raconPeriod;
+	}
+
+	public void setRaconPeriod(String per) {
+		raconPeriod = validDecimal(per);
+		repaint();
+	}
+
+	private String raconRange = "";
+
+	public String getRaconRange() {
+		return raconRange;
+	}
+
+	public void setRaconRange(String rng) {
+		raconRange = validDecimal(rng);
+		repaint();
+	}
+
+	private String raconSector1 = "";
+
+	public String getRaconSector1() {
+		return raconSector1;
+	}
+
+	public void setRaconSector1(String sec) {
+		raconSector1 = validDecimal(sec);
+		repaint();
+	}
+
+	private String raconSector2 = "";
+
+	public String getRaconSector2() {
+		return raconSector2;
+	}
+
+	public void setRaconSector2(String sec) {
+		raconSector2 = validDecimal(sec);
+		repaint();
+	}
+
+	public enum Fog {
+		NOFOG, FOGSIG, HORN, SIREN, DIA, BELL, WHIS, GONG, EXPLOS
+	}
+
+	public static final EnumMap<Fog, String> FogSTR = new EnumMap<Fog, String>(Fog.class);
+	static {
+		FogSTR.put(Fog.FOGSIG, "yes");
+		FogSTR.put(Fog.HORN, "horn");
+		FogSTR.put(Fog.SIREN, "siren");
+		FogSTR.put(Fog.DIA, "diaphone");
+		FogSTR.put(Fog.BELL, "bell");
+		FogSTR.put(Fog.WHIS, "whistle");
+		FogSTR.put(Fog.GONG, "gong");
+		FogSTR.put(Fog.EXPLOS, "explosion");
+	}
+
+	private Fog fogSound = Fog.NOFOG;
+
+	public Fog getFogSound() {
+		return fogSound;
+	}
+
+	public void setFogSound(Fog sound) {
+		fogSound = sound;
+		if (sound == Fog.NOFOG) {
+			setFogGroup("");
+			setFogSequence("");
+			setFogPeriod("");
+			setFogRange("");
+		}
+		repaint();
+	}
+
+	private String fogGroup = "";
+
+	public String getFogGroup() {
+		return fogGroup;
+	}
+
+	public void setFogGroup(String grp) {
+		fogGroup = grp;
+		repaint();
+	}
+
+	private String fogSequence = "";
+
+	public String getFogSequence() {
+		return fogSequence;
+	}
+
+	public void setFogSequence(String seq) {
+		fogSequence = seq;
+		repaint();
+	}
+
+	private String fogRange = "";
+
+	public String getFogRange() {
+		return fogRange;
+	}
+
+	public void setFogRange(String rng) {
+		fogRange = validDecimal(rng);
+		repaint();
+	}
+
+	private String fogPeriod = "";
+
+	public String getFogPeriod() {
+		return fogPeriod;
+	}
+
+	public void setFogPeriod(String per) {
+		fogPeriod = validDecimal(per);
+		repaint();
+	}
+
+	public enum Sts {
+		UNKSTS, PERM, OCC, REC, NIU, INT, RESV, TEMP, PRIV, MAND, DEST, EXT, ILLUM, HIST, PUB, SYNC, WATCH, UNWAT, DOUBT
+	}
+
+	public static final EnumMap<Sts, String> StsSTR = new EnumMap<Sts, String>(Sts.class);
+	static {
+		StsSTR.put(Sts.PERM, "permanent");
+		StsSTR.put(Sts.OCC, "occasional");
+		StsSTR.put(Sts.REC, "recommended");
+		StsSTR.put(Sts.NIU, "not_in_use");
+		StsSTR.put(Sts.INT, "intermittent");
+		StsSTR.put(Sts.RESV, "reserved");
+		StsSTR.put(Sts.TEMP, "tempory");
+		StsSTR.put(Sts.PRIV, "private");
+		StsSTR.put(Sts.MAND, "mandatory");
+		StsSTR.put(Sts.DEST, "destroyed");
+		StsSTR.put(Sts.EXT, "extinguished");
+		StsSTR.put(Sts.ILLUM, "illuminated");
+		StsSTR.put(Sts.HIST, "historic");
+		StsSTR.put(Sts.PUB, "public");
+		StsSTR.put(Sts.SYNC, "synchronized");
+		StsSTR.put(Sts.WATCH, "watched");
+		StsSTR.put(Sts.UNWAT, "unwatched");
+		StsSTR.put(Sts.DOUBT, "existence_doubtful");
+	}
+
+	private Sts status = Sts.UNKSTS;
+
+	public Sts getStatus() {
+		return status;
+	}
+
+	public void setStatus(Sts sts) {
+		status = sts;
+	}
+
+	public enum Cns {
+		UNKCNS, BRICK, CONC, BOULD, HSURF, USURF, WOOD, METAL, GLAS, PAINT
+	}
+
+	public static final EnumMap<Cns, String> CnsSTR = new EnumMap<Cns, String>(Cns.class);
+	static {
+		CnsSTR.put(Cns.BRICK, "masonry");
+		CnsSTR.put(Cns.CONC, "concreted");
+		CnsSTR.put(Cns.BOULD, "boulders");
+		CnsSTR.put(Cns.HSURF, "hard_surfaced");
+		CnsSTR.put(Cns.USURF, "unsurfaced");
+		CnsSTR.put(Cns.WOOD, "wooden");
+		CnsSTR.put(Cns.METAL, "metal");
+		CnsSTR.put(Cns.GLAS, "grp");
+		CnsSTR.put(Cns.PAINT, "painted");
+	}
+
+	private Cns construction = Cns.UNKCNS;
+
+	public Cns getConstr() {
+		return construction;
+	}
+
+	public void setConstr(Cns cns) {
+		construction = cns;
+	}
+
+	public enum Con {
+		UNKCON, CONSP, NCONS, REFL
+	}
+
+	public static final EnumMap<Con, String> ConSTR = new EnumMap<Con, String>(Con.class);
+	static {
+		ConSTR.put(Con.CONSP, "conspicuous");
+		ConSTR.put(Con.NCONS, "not_conspicuous");
+		ConSTR.put(Con.REFL, "reflector");
+	}
+
+	private Con conspicuity = Con.UNKCON;
+
+	public Con getConsp() {
+		return conspicuity;
+	}
+
+	public void setConsp(Con con) {
+		conspicuity = con;
+	}
+
+	private Con reflectivity = Con.UNKCON;
+
+	public Con getRefl() {
+		return reflectivity;
+	}
+
+	public void setRefl(Con con) {
+		reflectivity = con;
+	}
+
+	public enum Fnc {
+	  UNKFNC, HMO, CSTM, HLTH, HOSP, POFF, HOTEL, RWSTA, POLICE, WPOL, PILO, PILL, BANK, DCHQ, TRNS, FACT, PWRS, ADMIN, EDUC, CHCH, CHPL,
+	  TMPL, PGDA, SHSH, BTMP, MOSQ, MRBT, LOOK, COMS, TV, RADO, RADR, LSUP, MWAV, COOL, OBSV, TIMB, CLK, CTRL, AMOR, STAD, BUSS,
+	  PRHB, RGLN, RSTN, RCMD, INFO
+	}
+
+	public static final EnumMap<Fnc, String> FncSTR = new EnumMap<Fnc, String>(Fnc.class);
+	static {
+		FncSTR.put(Fnc.UNKFNC, "");
+		FncSTR.put(Fnc.HMO, "harbour-master");
+		FncSTR.put(Fnc.CSTM, "customs");
+		FncSTR.put(Fnc.HLTH, "health");
+		FncSTR.put(Fnc.HOSP, "hospital");
+		FncSTR.put(Fnc.POFF, "post_office");
+		FncSTR.put(Fnc.HOTEL, "hotel");
+		FncSTR.put(Fnc.RWSTA, "railway_station");
+		FncSTR.put(Fnc.POLICE, "police_station");
+		FncSTR.put(Fnc.WPOL, "water-police_station");
+		FncSTR.put(Fnc.PILO, "pilot_office");
+		FncSTR.put(Fnc.PILL, "pilot_lookout");
+		FncSTR.put(Fnc.BANK, "bank");
+		FncSTR.put(Fnc.DCHQ, "district_control");
+		FncSTR.put(Fnc.TRNS, "transit_shed");
+		FncSTR.put(Fnc.FACT, "factory");
+		FncSTR.put(Fnc.PWRS, "power_station");
+		FncSTR.put(Fnc.ADMIN, "administrative");
+		FncSTR.put(Fnc.EDUC, "educational");
+		FncSTR.put(Fnc.CHCH, "church");
+		FncSTR.put(Fnc.CHPL, "chapel");
+		FncSTR.put(Fnc.TMPL, "temple");
+		FncSTR.put(Fnc.PGDA, "pagoda");
+		FncSTR.put(Fnc.SHSH, "shinto_shrine");
+		FncSTR.put(Fnc.BTMP, "buddhist_temple");
+		FncSTR.put(Fnc.MOSQ, "mosque");
+		FncSTR.put(Fnc.MRBT, "marabout");
+		FncSTR.put(Fnc.LOOK, "lookout");
+		FncSTR.put(Fnc.COMS, "communication");
+		FncSTR.put(Fnc.TV, "television");
+		FncSTR.put(Fnc.RADO, "radio");
+		FncSTR.put(Fnc.RADR, "radar");
+		FncSTR.put(Fnc.LSUP, "light_support");
+		FncSTR.put(Fnc.MWAV, "microwave");
+		FncSTR.put(Fnc.COOL, "cooling");
+		FncSTR.put(Fnc.OBSV, "observation");
+		FncSTR.put(Fnc.TIMB, "time_ball");
+		FncSTR.put(Fnc.CLK, "clock");
+		FncSTR.put(Fnc.CTRL, "control");
+		FncSTR.put(Fnc.AMOR, "airship_mooring");
+		FncSTR.put(Fnc.STAD, "stadium");
+		FncSTR.put(Fnc.BUSS, "bus_station");
+		FncSTR.put(Fnc.PRHB, "prohibition");
+		FncSTR.put(Fnc.RGLN, "regulation");
+		FncSTR.put(Fnc.RSTN, "restriction");
+		FncSTR.put(Fnc.RCMD, "recommendation");
+		FncSTR.put(Fnc.INFO, "information");
+	}
+
+	private Fnc function = Fnc.UNKFNC;
+
+	public Fnc getFunc() {
+		return function;
+	}
+
+	public void setFunc(Fnc fnc) {
+		function = fnc;
+		repaint();
+	}
+
+	public String information = "";
+
+	public String getInfo() {
+		return information;
+	}
+
+	public void setInfo(String str) {
+		information = str.trim();
+	}
+
+	public String source = "";
+
+	public String getSource() {
+		return source;
+	}
+
+	public void setSource(String str) {
+		source = str.trim();
+	}
+
+	public String elevation = "";
+
+	public String getElevation() {
+		return elevation;
+	}
+
+	public void setElevation(String str) {
+		elevation = validDecimal(str);
+	}
+
+	public String height = "";
+
+	public String getObjectHeight() {
+		return height;
+	}
+
+	public void setObjectHeight(String str) {
+		height = validDecimal(str);
+	}
+
+	private String channel = "";
+
+	public String getChannel() {
+		return channel;
+	}
+
+	public void setChannel(String per) {
+		channel = validDecimal(per);
+		repaint();
+	}
+
+	public String ref = "";
+
+	public String getRef() {
+		return ref;
+	}
+
+	public void setRef(String str) {
+		ref = str;
+	}
+
+	public String lightRef = "";
+
+	public String getLightRef() {
+		return lightRef;
+	}
+
+	public void setLightRef(String str) {
+		lightRef = str;
+	}
+
+	public String fixme = "";
+
+	public String getFixme() {
+		return fixme;
+	}
+
+	public void setFixme(String str) {
+		fixme = str;
+	}
+
+	public boolean testValid() {
+		if (dlg.node == null) return false;
+		boolean tmp = false;
+		PanelMain.messageBar.setText("");
+		switch (getObject()) {
+		case BCNCAR:
+		case BCNLAT:
+		case BOYCAR:
+		case BOYLAT:
+			if ((getCategory() != Cat.NOCAT) && (getShape() != Shp.UNKSHP))
+				tmp = true;
+			break;
+		case BCNISD:
+		case BCNSAW:
+		case BCNSPP:
+		case BOYISD:
+		case BOYSAW:
+		case BOYSPP:
+			if (getShape() != Shp.UNKSHP)
+				tmp = true;
+			break;
+		case FLTCAR:
+		case FLTISD:
+		case FLTLAT:
+		case FLTSAW:
+		case FLTSPP:
+			if (getObjColour(0) != Col.UNKCOL)
+				tmp = true;
+			break;
+		case LITMAJ:
+		case LITMIN:
+		case LITFLT:
+		case LITVES:
+		case LITHSE:
+		case SISTAW:
+		case SISTAT:
+		case OFSPLF:
+		case MORFAC:
+		case BOYINB:
+		case PILBOP:
+		case RSCSTA:
+		case RDOSTA:
+		case RADSTA:
+ 			tmp = true;
+			break;
+		case NOTMRK:
+			if (getCategory() != Cat.NOCAT) 
+				tmp = true;
+		case LNDMRK:
+			if ((getCategory() != Cat.NOCAT) || (getFunc() != Fnc.UNKFNC))
+				tmp = true;
+			break;
+		}
+		if (tmp) {
+			dlg.panelMain.moreButton.setVisible(true);
+			dlg.panelMain.saveButton.setEnabled(true);
+			dlg.panelMain.topButton.setEnabled(true);
+			dlg.panelMain.fogButton.setEnabled(true);
+			dlg.panelMain.radButton.setEnabled(true);
+			dlg.panelMain.litButton.setEnabled(true);
+			return true;
+		} else {
+			dlg.panelMain.moreButton.setVisible(false);
+			dlg.panelMain.moreButton.setText(">>");
+			dlg.panelMain.topButton.setEnabled(false);
+			dlg.panelMain.fogButton.setEnabled(false);
+			dlg.panelMain.radButton.setEnabled(false);
+			dlg.panelMain.litButton.setEnabled(false);
+			PanelMain.messageBar.setText("Seamark not recognised");
+			return false;
+		}
+	}
+
+	public void clrMark() {
+		setName("");
+		setObject(Obj.UNKOBJ);
+		clrLight();
+		setFogSound(Fog.NOFOG);
+		setRadar(Rtb.NORTB);
+		setRadio(Cat.NOROS);
+		setStatus(Sts.UNKSTS);
+		setConstr(Cns.UNKCNS);
+		setConsp(Con.UNKCON);
+		setRefl(Con.UNKCON);
+		setRef("");
+		setObjectHeight("");
+		setElevation("");
+		setChannel("");
+		setInfo("");
+		setSource("");
+		setFixme("");
+		dlg.panelMain.syncPanel();
+		repaint();
+	}
+
+	public String validDecimal(String str) {
+		str = str.trim().replace(',', '.');
+		if (!(str.isEmpty()) && !(str.matches("^[+-]??\\d+(\\.\\d+)??$"))) {
+			PanelMain.messageBar.setText(Messages.getString("NotDecimal"));
+			return "";
+		} else {
+			PanelMain.messageBar.setText("");
+			return str;
+		}
+	}
+
+	public String validDecimal(String str, float max) {
+		str = validDecimal(str);
+		if (!(str.isEmpty()) && (new Float(str) > max)) {
+			PanelMain.messageBar.setText(Messages.getString("TooBig") + " (" + max + ")");
+			return "";
+		} else {
+			PanelMain.messageBar.setText("");
+			return str;
+		}
+	}
+
+	public void parseMark(OsmPrimitive node) {
+		PanelMain.messageBar.setText("");
+		String str = Main.pref.get("smedplugin.IALA");
+		if (str.equals("C"))
+			setRegion(Reg.C);
+		else if (str.equals("B"))
+			setRegion(Reg.B);
+		else
+			setRegion(Reg.A);
+
+		Map<String, String> keys = node.getKeys();
+
+		str = "";
+		if (keys.containsKey("seamark:type"))
+			str = keys.get("seamark:type");
+
+		clrMark();
+		for (Obj obj : ObjSTR.keySet()) {
+			if (ObjSTR.get(obj).equals(str)) {
+				setObject(obj);
+			}
+		}
+
+		if (str.equals("")) {
+			PanelMain.messageBar.setText("No seamark");
+		}
+		if (getObject() == Obj.UNKOBJ) {
+			PanelMain.messageBar.setText("Seamark not recognised");
+		}
+
+		setName("");
+		for (Obj obj : ObjSTR.keySet()) {
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":name")) {
+				str = keys.get("seamark:" + ObjSTR.get(obj) + ":name");
+				setName(str);
+			}
+		}
+		if (keys.containsKey("seamark:name")) {
+			str = keys.get("seamark:name");
+			setName(str);
+		}
+		
+		for (Obj obj : ObjSTR.keySet()) {
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":category")) {
+				str = keys.get("seamark:" + ObjSTR.get(obj) + ":category");
+				if (obj == getObject()) {
+					setCategory(Cat.NOCAT);
+					for (Cat cat : CatSTR.keySet()) {
+						if (CatSTR.get(cat).equals(str)) {
+							setCategory(cat);
+						}
+					}
+				}
+			}
+		}
+
+		for (Obj obj : ObjSTR.keySet()) {
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":shape")) {
+				str = keys.get("seamark:" + ObjSTR.get(obj) + ":shape");
+				setShape(Shp.UNKSHP);
+				for (Shp shp : ShpSTR.keySet()) {
+					if (ShpSTR.get(shp).equals(str)) {
+						setShape(shp);
+					}
+				}
+			}
+		}
+		if (getShape() == Shp.UNKSHP) {
+			if (EntMAP.get(getObject()) == Ent.BUOY)
+				setShape(Shp.BUOY);
+			if (EntMAP.get(getObject()) == Ent.BEACON)
+				setShape(Shp.BEACON);
+			if (EntMAP.get(getObject()) == Ent.LFLOAT)
+				if (getObject() == Obj.LITVES)
+					setShape(Shp.SUPER);
+				else
+					setShape(Shp.FLOAT);
+		}
+
+		for (Obj obj : ObjSTR.keySet()) {
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":colour")) {
+				str = keys.get("seamark:" + ObjSTR.get(obj) + ":colour");
+				bodyColour.clear();
+				for (String item : str.split(";")) {
+					for (Col col : ColSTR.keySet()) {
+						if (ColSTR.get(col).equals(item)) {
+							bodyColour.add(col);
+						}
+					}
+				}
+			}
+		}
+
+		for (Obj obj : ObjSTR.keySet()) {
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":colour_pattern")) {
+				str = keys.get("seamark:" + ObjSTR.get(obj) + ":colour_pattern");
+				setObjPattern(Pat.NOPAT);
+				for (Pat pat : PatSTR.keySet()) {
+					if (PatSTR.get(pat).equals(str)) {
+						setObjPattern(pat);
+					}
+				}
+			}
+
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":height")) {
+				setObjectHeight(keys.get("seamark:" + ObjSTR.get(obj) + ":height"));
+			}
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":elevation")) {
+				setElevation(keys.get("seamark:" + ObjSTR.get(obj) + ":elevation"));
+			}
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":channel")) {
+				setChannel(keys.get("seamark:" + ObjSTR.get(obj) + ":channel"));
+			}
+		}
+
+		for (Obj obj : ObjSTR.keySet()) {
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":function")) {
+				str = keys.get("seamark:" + ObjSTR.get(obj) + ":function");
+				setFunc(Fnc.UNKFNC);
+				for (Fnc fnc : FncSTR.keySet()) {
+					if (FncSTR.get(fnc).equals(str)) {
+						setFunc(fnc);
+					}
+				}
+			}
+		}
+
+		if ((getObject() == Obj.LNDMRK) && (getCategory() == Cat.NOCAT) && (getFunc() == Fnc.UNKFNC)) {
+			setObject(Obj.LITHSE);
+		}
+
+		if (getObject() == Obj.LITFLT) {
+			switch (getObjColour(0)) {
+			case RED:
+				if ((getObjColour(1) == Col.WHITE) && (getObjColour(2) == Col.UNKCOL)) {
+					setObject(Obj.FLTSAW);
+					setCategory(Cat.NOCAT);
+				} else if (getObjColour(1) == Col.UNKCOL) {
+					setObject(Obj.FLTLAT);
+					if (getRegion() == Reg.B) {
+						setCategory(Cat.LAM_STBD);
+					} else {
+						setCategory(Cat.LAM_PORT);
+					}
+				} else if ((getObjColour(1) == Col.GREEN)
+						&& (getObjColour(2) == Col.RED)) {
+					setObject(Obj.FLTLAT);
+					if (getRegion() == Reg.B) {
+						setCategory(Cat.LAM_PSTBD);
+					} else {
+						setCategory(Cat.LAM_PPORT);
+					}
+				} else if ((getObjColour(1) == Col.WHITE)
+						&& (getObjColour(2) == Col.RED)) {
+					setObject(Obj.FLTLAT);
+					setCategory(Cat.LAM_PORT);
+				} else {
+					setObject(Obj.FLTSPP);
+					setCategory(Cat.NOCAT);
+				}
+				break;
+			case GREEN:
+				if (getObjColour(1) == Col.UNKCOL) {
+					setObject(Obj.FLTLAT);
+					if (getRegion() == Reg.B) {
+						setCategory(Cat.LAM_PORT);
+					} else {
+						setCategory(Cat.LAM_STBD);
+					}
+				} else if ((getObjColour(1) == Col.RED)
+						&& (getObjColour(2) == Col.GREEN)) {
+					setObject(Obj.FLTLAT);
+					if (getRegion() == Reg.B) {
+						setCategory(Cat.LAM_PPORT);
+					} else {
+						setCategory(Cat.LAM_PSTBD);
+					}
+				} else if ((getObjColour(1) == Col.WHITE)
+						&& (getObjColour(2) == Col.GREEN)) {
+					setObject(Obj.FLTLAT);
+					setCategory(Cat.LAM_STBD);
+				} else {
+					setObject(Obj.FLTSPP);
+					setCategory(Cat.NOCAT);
+				}
+				break;
+			case YELLOW:
+				if (getObjColour(1) == Col.BLACK) {
+					setObject(Obj.FLTCAR);
+					if (getObjColour(2) == Col.YELLOW) {
+						setCategory(Cat.CAM_WEST);
+					} else {
+						setCategory(Cat.CAM_SOUTH);
+					}
+				} else {
+					setObject(Obj.FLTSPP);
+					setCategory(Cat.NOCAT);
+				}
+				break;
+			case BLACK:
+				if (getObjColour(1) == Col.RED) {
+					setObject(Obj.FLTISD);
+					setCategory(Cat.NOCAT);
+				} else if (getObjColour(1) == Col.YELLOW) {
+					setObject(Obj.FLTCAR);
+					if (getObjColour(2) == Col.BLACK) {
+						setCategory(Cat.CAM_EAST);
+					} else {
+						setCategory(Cat.CAM_NORTH);
+					}
+				} else {
+					setObject(Obj.FLTSPP);
+					setCategory(Cat.NOCAT);
+				}
+				break;
+			default:
+				setCategory(Cat.NOCAT);
+			}
+		}
+
+		for (Obj obj : ObjSTR.keySet()) {
+			if (keys.containsKey("seamark:" + ObjSTR.get(obj) + ":system")) {
+				str = keys.get("seamark:" + ObjSTR.get(obj) + ":system");
+				if (str.equals("iala-a"))
+					setRegion(Reg.A);
+				else if (str.equals("iala-b"))
+					setRegion(Reg.B);
+				else
+					setRegion(Reg.C);
+			} else if (GrpMAP.get(object) == Grp.LAT) {
+				switch (getCategory()) {
+				case LAM_PORT:
+					if (getObjColour(0) == Col.RED) {
+						if (getObjColour(1) == Col.WHITE)
+							setRegion(Reg.C);
+						else
+							setRegion(Reg.A);
+					}
+					if (getObjColour(0) == Col.GREEN)
+						setRegion(Reg.B);
+					break;
+				case LAM_PPORT:
+					if (getObjColour(0) == Col.RED) {
+						if (getObjColour(3) == Col.GREEN)
+							setRegion(Reg.C);
+						else
+							setRegion(Reg.B);
+					}
+					if (getObjColour(0) == Col.GREEN)
+						setRegion(Reg.A);
+					break;
+				case LAM_STBD:
+					if (getObjColour(0) == Col.GREEN) {
+						if (getObjColour(1) == Col.WHITE)
+							setRegion(Reg.C);
+						else
+							setRegion(Reg.A);
+					}
+					if (getObjColour(0) == Col.RED)
+						setRegion(Reg.B);
+					break;
+				case LAM_PSTBD:
+					if (getObjColour(0) == Col.GREEN)
+						setRegion(Reg.B);
+					if (getObjColour(0) == Col.RED) {
+						if (getObjColour(3) == Col.GREEN)
+							setRegion(Reg.C);
+						else
+							setRegion(Reg.A);
+					}
+					break;
+				}
+			}
+		}
+
+		if (keys.containsKey("seamark:topmark:shape")) {
+			str = keys.get("seamark:topmark:shape");
+			setTopmark(Top.NOTOP);
+			for (Top top : TopSTR.keySet()) {
+				if (TopSTR.get(top).equals(str)) {
+					setTopmark(top);
+				}
+			}
+		}
+		if (keys.containsKey("seamark:topmark:colour")) {
+			str = keys.get("seamark:topmark:colour");
+			setTopColour(Col.UNKCOL);
+			for (Col col : ColSTR.keySet()) {
+				if (ColSTR.get(col).equals(str)) {
+					setTopColour(col);
+				}
+			}
+		}
+		if (keys.containsKey("seamark:topmark:colour_pattern")) {
+			str = keys.get("seamark:topmark:colour_pattern");
+			setTopPattern(Pat.NOPAT);
+			for (Pat pat : PatSTR.keySet()) {
+				if (PatSTR.get(pat).equals(str)) {
+					setTopPattern(pat);
+				}
+			}
+		}
+
+		clrLight();
+		for (int i = 0; i < 30; i++) {
+			String secStr = (i == 0) ? "" : (":" + Integer.toString(i));
+			if (keys.containsKey("seamark:light" + secStr + ":colour")) {
+				nulLight(i);
+				str = keys.get("seamark:light" + secStr + ":colour");
+				if (str.contains(";")) {
+					String strs[] = str.split(";");
+					for (Col col : ColSTR.keySet())
+						if ((strs.length > 1) && ColSTR.get(col).equals(strs[1]))
+							setLightAtt(Att.ALT, i, col);
+					str = strs[0];
+				}
+				for (Col col : ColSTR.keySet())
+					if (ColSTR.get(col).equals(str))
+						setLightAtt(Att.COL, i, col);
+			}
+			if (keys.containsKey("seamark:light" + secStr + ":character")) {
+				str = keys.get("seamark:light" + secStr + ":character");
+				if (str.contains("(") && str.contains(")")) {
+					int i1 = str.indexOf("(");
+					int i2 = str.indexOf(")");
+					setLightAtt(Att.GRP, i, str.substring((i1+1), i2));
+					str = str.substring(0, i1) + str.substring((i2+1), str.length());
+					}
+				setLightAtt(Att.CHR, i, str);
+			}
+			if (keys.containsKey("seamark:light" + secStr + ":group"))
+				setLightAtt(Att.GRP, i, keys.get("seamark:light" + secStr + ":group"));
+			if (keys.containsKey("seamark:light" + secStr + ":sequence"))
+				setLightAtt(Att.SEQ, i, keys.get("seamark:light" + secStr + ":sequence"));
+			if (keys.containsKey("seamark:light" + secStr + ":period"))
+				setLightAtt(Att.PER, i, keys.get("seamark:light" + secStr + ":period"));
+			if (keys.containsKey("seamark:light" + secStr + ":category")) {
+				str = keys.get("seamark:light" + secStr + ":category");
+				if (str.equals("vert"))
+					str = "vertical";
+				if (str.equals("horiz"))
+					str = "horizontal";
+				for (Lit lit : LitSTR.keySet())
+					if (LitSTR.get(lit).equals(str))
+						setLightAtt(Att.LIT, i, lit);
+			}
+			if (keys.containsKey("seamark:light" + secStr + ":sector_start"))
+				setLightAtt(Att.BEG, i, keys.get("seamark:light" + secStr + ":sector_start"));
+			if (keys.containsKey("seamark:light" + secStr + ":sector_end"))
+				setLightAtt(Att.END, i, keys.get("seamark:light" + secStr + ":sector_end"));
+			if (keys.containsKey("seamark:light" + secStr + ":radius"))
+				setLightAtt(Att.RAD, i, keys.get("seamark:light" + secStr + ":radius"));
+			if (keys.containsKey("seamark:light" + secStr + ":height"))
+				setLightAtt(Att.HGT, i, keys.get("seamark:light" + secStr + ":height"));
+			if (keys.containsKey("seamark:light" + secStr + ":range"))
+				setLightAtt(Att.RNG, i, keys.get("seamark:light" + secStr + ":range"));
+			if (keys.containsKey("seamark:light" + secStr + ":visibility")) {
+				str = keys.get("seamark:light" + secStr + ":visibility");
+				for (Vis vis : VisSTR.keySet())
+					if (VisSTR.get(vis).equals(str))
+						setLightAtt(Att.VIS, i, vis);
+			}
+			if (keys.containsKey("seamark:light" + secStr + ":exhibition")) {
+				str = keys.get("seamark:light" + secStr + ":exhibition");
+				for (Exh exh : ExhSTR.keySet())
+					if (ExhSTR.get(exh).equals(str))
+						setLightAtt(Att.EXH, i, exh);
+			}
+			if (keys.containsKey("seamark:light" + secStr + ":orientation"))
+				setLightAtt(Att.ORT, i, keys.get("seamark:light" + secStr + ":orientation"));
+			if (keys.containsKey("seamark:light" + secStr + ":multiple"))
+				setLightAtt(Att.MLT, i, keys.get("seamark:light" + secStr + ":multiple"));
+			
+			if (sectors.size() == i)
+				break;
+		}
+
+		if (keys.containsKey("seamark:fog_signal")) {
+			setFogSound(Fog.FOGSIG);
+		}
+		if (keys.containsKey("seamark:fog_signal:category")) {
+			str = keys.get("seamark:fog_signal:category");
+			setFogSound(Fog.NOFOG);
+			for (Fog fog : FogSTR.keySet()) {
+				if (FogSTR.get(fog).equals(str)) {
+					setFogSound(fog);
+				}
+			}
+		}
+		if (keys.containsKey("seamark:fog_signal:group")) {
+			setFogGroup(keys.get("seamark:fog_signal:group"));
+		}
+		if (keys.containsKey("seamark:fog_signal:period")) {
+			setFogPeriod(keys.get("seamark:fog_signal:period"));
+		}
+		if (keys.containsKey("seamark:fog_signal:sequence")) {
+			setFogSequence(keys.get("seamark:fog_signal:sequence"));
+		}
+		if (keys.containsKey("seamark:fog_signal:range")) {
+			setFogRange(keys.get("seamark:fog_signal:range"));
+		}
+
+		if (keys.containsKey("seamark:radio_station:category")) {
+			str = keys.get("seamark:radio_station:category");
+			setRadio(Cat.NOROS);
+			for (Cat rdo : CatSTR.keySet()) {
+				if (CatSTR.get(rdo).equals(str)) {
+					setRadio(rdo);
+				}
+			}
+		}
+
+		if (keys.containsKey("seamark:radar_reflector")) {
+			setRadar(Rtb.REFLECTOR);
+		}
+		if (keys.containsKey("seamark:radar_transponder:category")) {
+			str = keys.get("seamark:radar_transponder:category");
+			setRadar(Rtb.NORTB);
+			for (Rtb rtb : RtbSTR.keySet()) {
+				if (RtbSTR.get(rtb).equals(str)) {
+					setRadar(rtb);
+				}
+			}
+		}
+		if (keys.containsKey("seamark:radar_transponder:group")) {
+			setRaconGroup(keys.get("seamark:radar_transponder:group"));
+		}
+		if (keys.containsKey("seamark:radar_transponder:period")) {
+			setRaconPeriod(keys.get("seamark:radar_transponder:period"));
+		}
+		if (keys.containsKey("seamark:radar_transponder:sequence")) {
+			setRaconSequence(keys.get("seamark:radar_transponder:sequence"));
+		}
+		if (keys.containsKey("seamark:radar_transponder:range")) {
+			setRaconRange(keys.get("seamark:radar_transponder:range"));
+		}
+		if (keys.containsKey("seamark:radar_transponder:sector_start")) {
+			setRaconSector1(keys.get("seamark:radar_transponder:sector_start"));
+		}
+		if (keys.containsKey("seamark:radar_transponder:sector_end")) {
+			setRaconSector2(keys.get("seamark:radar_transponder:sector_end"));
+		}
+
+		if (keys.containsKey("seamark:information")) {
+			setInfo(keys.get("seamark:information"));
+		}
+		if (keys.containsKey("seamark:light:information")) {
+			setInfo(getInfo() + keys.get("seamark:light:information"));
+		}
+		if (keys.containsKey("seamark:" + ObjSTR.get(getObject()) + "information")) {
+			setInfo(getInfo() + keys.get("seamark:" + ObjSTR.get(getObject()) + "information"));
+		}
+		if (keys.containsKey("seamark:source")) {
+			setSource(keys.get("seamark:source"));
+		}
+		if (keys.containsKey("seamark:light:source")) {
+			setSource(getSource() + keys.get("seamark:light:source"));
+		}
+		if (keys.containsKey("seamark:" + ObjSTR.get(getObject()) + "source")) {
+			setSource(getSource() + keys.get("seamark:" + ObjSTR.get(getObject()) + "source"));
+		}
+		if (keys.containsKey("seamark:height")) {
+			setObjectHeight(keys.get("seamark:height"));
+		}
+		if (keys.containsKey("seamark:elevation")) {
+			setElevation(keys.get("seamark:elevation"));
+		}
+		if (keys.containsKey("seamark:status")) {
+			str = keys.get("seamark:status");
+			setStatus(Sts.UNKSTS);
+			for (Sts sts : StsSTR.keySet()) {
+				if (StsSTR.get(sts).equals(str)) {
+					setStatus(sts);
+				}
+			}
+		}
+		if (keys.containsKey("seamark:construction")) {
+			str = keys.get("seamark:construction");
+			setConstr(Cns.UNKCNS);
+			for (Cns cns : CnsSTR.keySet()) {
+				if (CnsSTR.get(cns).equals(str)) {
+					setConstr(cns);
+				}
+			}
+		}
+		if (keys.containsKey("seamark:conspicuity")) {
+			str = keys.get("seamark:conspicuity");
+			setConsp(Con.UNKCON);
+			for (Con con : ConSTR.keySet()) {
+				if (ConSTR.get(con).equals(str)) {
+					setConsp(con);
+				}
+			}
+		}
+		if (keys.containsKey("seamark:reflectivity")) {
+			str = keys.get("seamark:reflectivity");
+			setRefl(Con.UNKCON);
+			for (Con con : ConSTR.keySet()) {
+				if (ConSTR.get(con).equals(str)) {
+					setRefl(con);
+				}
+			}
+		}
+
+		if (keys.containsKey("seamark:ref")) {
+			setRef(keys.get("seamark:ref"));
+		}
+		if (keys.containsKey("seamark:reference")) {
+			setRef(keys.get("seamark:reference"));
+		}
+		if (keys.containsKey("seamark:light:ref")) {
+			setLightRef(keys.get("seamark:light:ref"));
+		}
+		if (keys.containsKey("seamark:light:reference")) {
+			setLightRef(keys.get("seamark:light:reference"));
+		}
+		if (keys.containsKey("seamark:fixme")) {
+			setFixme(keys.get("seamark:fixme"));
+		}
+
+		dlg.panelMain.syncPanel();
+	}
+
+	public void paintComponent(Graphics g) {
+		super.paintComponent(g);
+		
+		if (dlg.node == null) return;
+		
+    Graphics2D g2 = (Graphics2D) g;
+    
+    String colStr;
+		String lblStr;
+		String imgStr = "/images/";
+		if (getShape() != Shp.UNKSHP) {
+			switch (getShape()) {
+			case TOWER:
+				imgStr += "Tower";
+				break;
+			case BUOY:
+			case PILLAR:
+				imgStr += "Pillar";
+				break;
+			case SPAR:
+				imgStr += "Spar";
+				break;
+			case CAN:
+				imgStr += "Can";
+				break;
+			case CONI:
+				imgStr += "Cone";
+				break;
+			case SPHERI:
+				imgStr += "Sphere";
+				break;
+			case BARREL:
+				imgStr += "Barrel";
+				break;
+			case CAIRN:
+				imgStr += "Cairn";
+				break;
+			case FLOAT:
+				imgStr += "Float";
+				break;
+			case BEACON:
+			case PILE:
+			case LATTICE:
+			case BUOYANT:
+				imgStr += "Beacon";
+				break;
+			case SUPER:
+				imgStr += "Super";
+				break;
+			case STAKE:
+			case POLE:
+			case POST:
+				imgStr += "Stake";
+				break;
+			case PERCH:
+				if (getCategory() == Cat.LAM_PORT) {
+					imgStr += "Perch_Port";
+				} else {
+					imgStr += "Perch_Starboard";
+				}
+				break;
+			}
+			colStr = imgStr;
+			lblStr = "";
+			for (Col col : bodyColour) {
+				switch (col) {
+				case WHITE:
+					colStr += "_White";
+					lblStr += "W";
+					break;
+				case RED:
+					colStr += "_Red";
+					lblStr += "R";
+					break;
+				case ORANGE:
+					colStr += "_Orange";
+					lblStr += "Or";
+					break;
+				case AMBER:
+					colStr += "_Amber";
+					lblStr += "Am";
+					break;
+				case YELLOW:
+					colStr += "_Yellow";
+					lblStr += "Y";
+					break;
+				case GREEN:
+					colStr += "_Green";
+					lblStr += "G";
+					break;
+				case BLUE:
+					colStr += "_Blue";
+					lblStr += "Bu";
+					break;
+				case VIOLET:
+					colStr += "_Violet";
+					lblStr += "Vi";
+					break;
+				case BLACK:
+					colStr += "_Black";
+					lblStr += "B";
+					break;
+				case GREY:
+					colStr += "_Grey";
+					lblStr += "Gr";
+					break;
+				case BROWN:
+					colStr += "_Brown";
+					lblStr += "Br";
+					break;
+				case MAGENTA:
+					colStr += "_Magenta";
+					lblStr += "Mg";
+					break;
+				case PINK:
+					colStr += "_Pink";
+					lblStr += "Pk";
+					break;
+				}
+			}
+			if (!imgStr.equals("/images/")) {
+				colStr += ".png";
+				if (getClass().getResource(colStr) == null) {
+					System.out.println("Missing image1: " + colStr);
+					imgStr += ".png";
+					if (getClass().getResource(imgStr) == null) {
+						System.out.println("Missing image2: " + imgStr);
+					} else {
+						g2.drawImage(new ImageIcon(getClass().getResource(imgStr)).getImage(), 7, -15, null);
+						g2.drawString(lblStr, 75, 110);
+					}
+				} else {
+					g2.drawImage(new ImageIcon(getClass().getResource(colStr)).getImage(), 7, -15, null);
+				}
+			}
+		} else if (getObject() != Obj.UNKOBJ) {
+			switch (getObject()) {
+			case LNDMRK:
+				switch (getCategory()) {
+				case LMK_CHMY:
+					imgStr += "Chimney";
+					break;
+				case LMK_CARN:
+					imgStr += "Cairn";
+					break;
+				case LMK_DSHA:
+					imgStr += "DishAerial";
+					break;
+				case LMK_FLGS:
+					imgStr += "Flagstaff";
+					break;
+				case LMK_FLRS:
+					imgStr += "FlareStack";
+					break;
+				case LMK_MNMT:
+				case LMK_CLMN:
+				case LMK_OBLK:
+				case LMK_STAT:
+					imgStr += "Monument";
+					break;
+				case LMK_MAST:
+					imgStr += "RadioMast";
+					break;
+				case LMK_TOWR:
+					if ((getFunc() == Fnc.CHCH) || (getFunc() == Fnc.CHPL))
+						imgStr += "ChurchTower";
+					else
+						imgStr += "LandTower";
+					break;
+				case LMK_WNDM:
+					imgStr += "Wind_Motor";
+					break;
+				case LMK_WTRT:
+					imgStr += "WaterTower";
+					break;
+				case LMK_DOME:
+					if ((getFunc() == Fnc.CHCH) || (getFunc() == Fnc.CHPL))
+						imgStr += "ChurchDome";
+					else
+						imgStr += "Dome";
+					break;
+				case LMK_SPIR:
+					if ((getFunc() == Fnc.CHCH) || (getFunc() == Fnc.CHPL))
+						imgStr += "ChurchSpire";
+					else
+						imgStr += "Spire";
+					break;
+				case LMK_MNRT:
+					imgStr += "Minaret";
+					break;
+				case LMK_WNDS:
+					imgStr += "Windsock";
+					break;
+				case LMK_CROS:
+					imgStr += "Cross";
+					break;
+				case LMK_SCNR:
+					imgStr += "Signal_Station";
+					break;
+				case LMK_WNDL:
+					imgStr += "Windmill";
+					break;
+				case NOCAT:
+					switch (getFunc()) {
+					case CHCH:
+					case CHPL:
+						imgStr += "Church";
+						break;
+					case TMPL:
+					case PGDA:
+					case SHSH:
+					case BTMP:
+						imgStr += "Temple";
+						break;
+					case MOSQ:
+						imgStr += "Minaret";
+						break;
+					case MRBT:
+						imgStr += "Spire";
+						break;
+					}
+				}
+				break;
+			case LITHSE:
+				imgStr += "Light_House";
+				break;
+			case LITMAJ:
+				imgStr += "Light_Major";
+				break;
+			case LITMIN:
+				imgStr += "Light_Minor";
+				break;
+			case LITFLT:
+				imgStr += "Float";
+				break;
+			case LITVES:
+				imgStr += "Super";
+				break;
+			case SISTAW:
+				imgStr += "Signal_Station";
+				break;
+			case SISTAT:
+				imgStr += "Signal_Station";
+				break;
+			case OFSPLF:
+				if (getCategory() == Cat.OFP_FPSO)
+					imgStr += "Storage";
+				else
+					imgStr += "Platform";
+				break;
+			case MORFAC:
+				switch (getCategory()) {
+				case MOR_DLPN:
+					imgStr += "Dolphin";
+					break;
+				case MOR_DDPN:
+					imgStr += "DeviationDolphin";
+					break;
+				case MOR_POST:
+					imgStr += "Post";
+					break;
+				case MOR_BUOY:
+					imgStr += "Sphere";
+					break;
+				}
+				break;
+			case BOYINB:
+				imgStr += "Super";
+				break;
+			case CGUSTA:
+				imgStr += "Signal_Station";
+				break;
+			case PILBOP:
+				imgStr += "Pilot";
+				break;
+			case RSCSTA:
+				imgStr += "Rescue";
+				break;
+			case RDOSTA:
+			case RADSTA:
+				imgStr += "Signal_Station";
+				g2.drawImage(new ImageIcon(getClass().getResource("/images/Radar_Station.png")).getImage(), 7, -15, null);
+				break;
+			}
+			if (!imgStr.equals("/images/")) {
+				imgStr += ".png";
+				if (getClass().getResource(imgStr) == null) {
+					System.out.println("Missing image3: " + imgStr);
+				} else {
+					g2.drawImage(new ImageIcon(getClass().getResource(imgStr)).getImage(), 7, -15, null);
+				}
+			}
+		}
+
+		if (getTopmark() != Top.NOTOP) {
+			imgStr = "/images/Top_";
+			switch (getTopmark()) {
+			case CYL:
+				imgStr += "Can";
+				break;
+			case CONE:
+				imgStr += "Cone";
+				break;
+			case SPHERE:
+				imgStr += "Sphere";
+				break;
+			case X_SHAPE:
+				imgStr += "X";
+				break;
+			case NORTH:
+				imgStr += "North";
+				break;
+			case SOUTH:
+				imgStr += "South";
+				break;
+			case EAST:
+				imgStr += "East";
+				break;
+			case WEST:
+				imgStr += "West";
+				break;
+			case SPHERES2:
+				imgStr += "Isol";
+				break;
+			}
+			colStr = imgStr;
+			for (Col col : topmarkColour) {
+				switch (col) {
+				case WHITE:
+					colStr += "_White";
+					break;
+				case RED:
+					colStr += "_Red";
+					break;
+				case ORANGE:
+					colStr += "_Orange";
+					break;
+				case AMBER:
+					colStr += "_Amber";
+					break;
+				case YELLOW:
+					colStr += "_Yellow";
+					break;
+				case GREEN:
+					colStr += "_Green";
+					break;
+				case BLUE:
+					colStr += "_Blue";
+					break;
+				case VIOLET:
+					colStr += "_Violet";
+					break;
+				case BLACK:
+					colStr += "_Black";
+					break;
+				}
+			}
+			switch (getShape()) {
+			case CAN:
+			case CONI:
+			case SPHERI:
+			case BARREL:
+				imgStr += "_Buoy_Small";
+				colStr += "_Buoy_Small";
+				break;
+			case PILLAR:
+			case SPAR:
+				imgStr += "_Buoy";
+				colStr += "_Buoy";
+				break;
+			case FLOAT:
+			case SUPER:
+				imgStr += "_Float";
+				colStr += "_Float";
+				break;
+			case BUOYANT:
+			case CAIRN:
+			case PILE:
+			case LATTICE:
+			case TOWER:
+			case STAKE:
+			case POLE:
+			case POST:
+			case BEACON:
+				imgStr += "_Beacon";
+				colStr += "_Beacon";
+				break;
+			}
+			colStr += ".png";
+			if (getClass().getResource(colStr) == null) {
+				System.out.println("Missing image4: " + colStr);
+				imgStr += ".png";
+				if (getClass().getResource(imgStr) == null) {
+					System.out.println("Missing image5: " + imgStr);
+					return;
+				} else {
+					g2.drawImage(new ImageIcon(getClass().getResource(imgStr)).getImage(), 7, -15, null);
+				}
+			} else {
+				g2.drawImage(new ImageIcon(getClass().getResource(colStr)).getImage(), 7, -15, null);
+			}
+		} else {
+			if ((getObject() == Obj.BOYINB) || ((getObject() == Obj.MORFAC) && (getCategory() == Cat.MOR_BUOY))) {
+				imgStr = "/images/Top_Mooring";
+				switch (getShape()) {
+				case CAN:
+				case CONI:
+				case SPHERI:
+				case BARREL:
+					imgStr += "_Buoy_Small";
+					break;
+				case FLOAT:
+				case SUPER:
+					imgStr += "_Float";
+					break;
+				default:
+					if (getObject() == Obj.MORFAC) {
+						imgStr += "_Buoy_Small";
+					} else {
+						imgStr += "_Float";
+					}
+					break;
+				}
+				imgStr += ".png";
+				if (getClass().getResource(imgStr) == null) {
+					System.out.println("Missing image6: " + imgStr);
+					return;
+				} else {
+					g2.drawImage(new ImageIcon(getClass().getResource(imgStr)).getImage(), 7, -15, null);
+				}
+			}
+		}
+
+		for (int i = 1; i < sectors.size(); i++) {
+	    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+	    g2.setStroke(new BasicStroke(6.0f));
+	    if (!((String)getLightAtt(Att.BEG, i)).isEmpty() && !((String)getLightAtt(Att.END, i)).isEmpty()) {
+				if (getLightAtt(Att.COL, i) != Col.UNKCOL) {
+					g2.setPaint(ColMAP.get(getLightAtt(Att.COL, i)));
+					Double a0 = 270 - Double.parseDouble((String)getLightAtt(Att.BEG, i));
+					Double da = 270 - Double.parseDouble((String)getLightAtt(Att.END, i)) - a0;
+					da -= da > 0 ? 360 : 0;
+					g2.draw(new Arc2D.Double(12, 15, 140, 140, a0, da, Arc2D.OPEN));
+				}
+				if (getLightAtt(Att.ALT, i) != Col.UNKCOL) {
+					g2.setPaint(ColMAP.get(getLightAtt(Att.ALT, i)));
+					Double a0 = 270 - Double.parseDouble((String)getLightAtt(Att.BEG, i));
+					Double da = 270 - Double.parseDouble((String)getLightAtt(Att.END, i)) - a0;
+					da -= da > 0 ? 360 : 0;
+					g2.draw(new Arc2D.Double(17, 20, 130, 130, a0, da, Arc2D.OPEN));
+				}
+	    } else if ((getLightAtt(Att.LIT, i) == Lit.DIR) && !((String)getLightAtt(Att.ORT, i)).isEmpty()) {
+				if (getLightAtt(Att.COL, i) != Col.UNKCOL) {
+					g2.setPaint(ColMAP.get(getLightAtt(Att.COL, i)));
+					Double a0 = 270 - Double.parseDouble((String)getLightAtt(Att.ORT, i)) + 2.0;
+					Double da = -4.0;
+					g2.draw(new Arc2D.Double(12, 15, 140, 140, a0, da, Arc2D.OPEN));
+				}
+				if (getLightAtt(Att.ALT, i) != Col.UNKCOL) {
+					g2.setPaint(ColMAP.get(getLightAtt(Att.ALT, i)));
+					Double a0 = 270 - Double.parseDouble((String)getLightAtt(Att.ORT, i)) + 2.0;
+					Double da = -4.0;
+					g2.draw(new Arc2D.Double(17, 20, 130, 130, a0, da, Arc2D.OPEN));
+				}
+	    }
+		}
+    g2.setPaint(Color.BLACK);
+		if ((getLightAtt(Att.COL, 0) != Col.UNKCOL) || !(((String)getLightAtt(Att.CHR, 0)).isEmpty())) {
+			if (sectors.size() == 1) {
+				if (((String) getLightAtt(Att.CHR, 0)).contains("Al")) {
+					g2.drawImage(new ImageIcon(getClass().getResource("/images/Light_Magenta_120.png")).getImage(), 7, -15, null);
+				} else {
+					switch ((Col) getLightAtt(Att.COL, 0)) {
+					case RED:
+						g2.drawImage(new ImageIcon(getClass().getResource("/images/Light_Red_120.png")).getImage(), 7, -15, null);
+						break;
+					case GREEN:
+						g2.drawImage(new ImageIcon(getClass().getResource("/images/Light_Green_120.png")).getImage(), 7, -15, null);
+						break;
+					case WHITE:
+					case YELLOW:
+						g2.drawImage(new ImageIcon(getClass().getResource("/images/Light_White_120.png")).getImage(), 7, -15, null);
+						break;
+					default:
+						g2.drawImage(new ImageIcon(getClass().getResource("/images/Light_Magenta_120.png")).getImage(), 7, -15, null);
+					}
+				}
+			}
+			String c = (String) getLightAtt(Att.CHR, 0);
+			String tmp = "";
+			if (c.contains("+")) {
+				int i1 = c.indexOf("+");
+				tmp = c.substring(i1, c.length());
+				c = c.substring(0, i1);
+				if (!((String) getLightAtt(Att.GRP, 0)).isEmpty()) {
+					c += "(" + (String) getLightAtt(Att.GRP, 0) + ")";
+				}
+				if (tmp != null)
+					c += tmp;
+			} else if (!((String) getLightAtt(Att.GRP, 0)).isEmpty())
+				c += "(" + (String) getLightAtt(Att.GRP, 0) + ")";
+			switch ((Col) getLightAtt(Att.COL, 0)) {
+			case WHITE:
+				c += ".W";
+				break;
+			case YELLOW:
+				c += ".Y";
+				break;
+			case RED:
+				c += ".R";
+				break;
+			case GREEN:
+				c += ".G";
+				break;
+			case AMBER:
+				c += ".Am";
+				break;
+			case ORANGE:
+				c += ".Or";
+				break;
+			case BLUE:
+				c += ".Bu";
+				break;
+			case VIOLET:
+				c += ".Vi";
+				break;
+			}
+			switch ((Col) getLightAtt(Att.ALT, 0)) {
+			case WHITE:
+				c += "W";
+				break;
+			case YELLOW:
+				c += "Y";
+				break;
+			case RED:
+				c += "R";
+				break;
+			case GREEN:
+				c += "G";
+				break;
+			case AMBER:
+				c += "Am";
+				break;
+			case ORANGE:
+				c += "Or";
+				break;
+			case BLUE:
+				c += "Bu";
+				break;
+			case VIOLET:
+				c += "Vi";
+				break;
+			}
+			tmp = (String) getLightAtt(Att.MLT, 0);
+			if (!tmp.isEmpty())
+				c = tmp + c;
+			if (getLightAtt(Att.LIT, 0) != Lit.UNKLIT) {
+				switch ((Lit)getLightAtt(Att.LIT, 0)) {
+				case VERT:
+					c += "(Vert)";
+					break;
+				case HORIZ:
+						c += "(Horiz)";
+						break;
+				}
+			}
+			tmp = (String) getLightAtt(Att.PER, 0);
+			if (!tmp.isEmpty())
+				c += " " + tmp + "s";
+			g2.drawString(c, 100, 70);
+		}
+
+		if (getFogSound() != Fog.NOFOG) {
+			g2.drawImage(new ImageIcon(getClass().getResource("/images/Fog_Signal.png")).getImage(), 7, -15, null);
+			String str = "";
+			if (getFogSound() != Fog.FOGSIG)
+				switch (getFogSound()) {
+				case HORN:
+					str = "Horn";
+					break;
+				case SIREN:
+					str = "Siren";
+					break;
+				case DIA:
+					str = "Dia";
+					break;
+				case BELL:
+					str = "Bell";
+					break;
+				case WHIS:
+					str = "Whis";
+					break;
+				case GONG:
+					str = "Gong";
+					break;
+				case EXPLOS:
+					str = "Explos";
+					break;
+				}
+			if (!getFogGroup().isEmpty())
+				str += ("(" + getFogGroup() + ")");
+			else
+				str += " ";
+			if (!getFogPeriod().isEmpty())
+				str += getFogPeriod() + "s";
+			g2.drawString(str, 0, 70);
+		}
+
+		if (RaType != Rtb.NORTB) {
+			if (getRadar() == Rtb.REFLECTOR) {
+				g2.drawImage(new ImageIcon(getClass().getResource("/images/Radar_Reflector_355.png")).getImage(), 7, -15, null);
+			} else {
+				g2.drawImage(new ImageIcon(getClass().getResource("/images/Radar_Station.png")).getImage(), 7, -15, null);
+				String str = "";
+				if (getRadar() == Rtb.RAMARK)
+					str += "Ramark";
+				else
+					str += "Racon";
+				if (!getRaconGroup().isEmpty())
+					str += ("(" + getRaconGroup() + ")");
+				else
+					str += " ";
+				if (!getRaconPeriod().isEmpty())
+					str += getRaconPeriod() + "s";
+				g2.drawString(str, 0, 50);
+			}
+		}
+
+		if (RoType != Cat.NOROS) {
+			g2.drawImage(new ImageIcon(getClass().getResource("/images/Radar_Station.png")).getImage(), 7, -15, null);
+			g2.drawString("AIS", 0, 30);
+		}
+	}
+
+	public void saveSign(OsmPrimitive node) {
+		
+		if (getObject() != Obj.UNKOBJ) {
+
+			Main.pref.put("smedplugin.IALA", getRegion() == Reg.C ? "C" : (getRegion() == Reg.B ? "B" : "A"));
+
+			for (String str : node.getKeys().keySet()) {
+				if (str.trim().matches("^seamark:\\S+"))
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, str, null));
+			}
+
+			if (!getName().isEmpty())
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:name", getName()));
+
+			String objStr = ObjSTR.get(object);
+			if (objStr != null) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:type", objStr));
+
+				if (getShape() != Shp.FLOAT) {
+					String str = CatSTR.get(getCategory());
+					if (str != null)
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":category", str));
+					if ((getShape() != Shp.BUOY) && (getShape() != Shp.BEACON))
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":shape", ShpSTR.get(getShape())));
+				}
+
+				if ((getObjColour(0) != Col.UNKCOL) && getShape() != Shp.PERCH) {
+					String str = ColSTR.get(getObjColour(0));
+					for (int i = 1; bodyColour.size() > i; i++) {
+						str += (";" + ColSTR.get(getObjColour(i)));
+					}
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":colour", str));
+				}
+
+				if (getObjPattern() != Pat.NOPAT) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":colour_pattern", PatSTR.get(getObjPattern())));
+				}
+
+				if (getFunc() != Fnc.UNKFNC) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":function", FncSTR.get(getFunc())));
+				}
+
+				if ((GrpMAP.get(object) == Grp.LAT) && (getShape() != Shp.PERCH)
+						|| (getObject() == Obj.FLTLAT)) {
+					switch (region) {
+					case A:
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":system", "iala-a"));
+						break;
+					case B:
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":system", "iala-b"));
+						break;
+					case C:
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":system", "other"));
+						break;
+					}
+				}
+				if (!getObjectHeight().isEmpty()) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":height", getObjectHeight()));
+				}
+				if (!getElevation().isEmpty()) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":elevation", getElevation()));
+				}
+				if (!getChannel().isEmpty()) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:" + objStr + ":channel", getChannel()));
+				}
+			}
+			if (getTopmark() != Top.NOTOP) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:topmark:shape", TopSTR.get(getTopmark())));
+				if (getTopPattern() != Pat.NOPAT)
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:topmark:colour_pattern", PatSTR.get(getTopPattern())));
+				if (getTopColour(0) != Col.UNKCOL) {
+					String str = ColSTR.get(getTopColour(0));
+					for (int i = 1; topmarkColour.size() > i; i++) {
+						str += (";" + ColSTR.get(getTopColour(i)));
+					}
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:topmark:colour", str));
+				}
+			}
+
+			for (int i = (sectors.size() > 1 ? 1 : 0); i < sectors.size(); i++) {
+				String secStr = (i == 0) ? "" : (":" + Integer.toString(i));
+				if (sectors.get(i)[0] != Col.UNKCOL)
+					if ((sectors.get(i)[15] != Col.UNKCOL) && ((String)sectors.get(i)[1]).contains("Al"))
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":colour", (ColSTR.get(sectors.get(i)[0])) + ";" + ColSTR.get(sectors.get(i)[15])));
+					else
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":colour", ColSTR.get(sectors.get(i)[0])));
+				if (!((String) sectors.get(i)[1]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":character", (String) sectors.get(i)[1]));
+				else if (!((String) sectors.get(0)[1]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":character", (String) sectors.get(0)[1]));
+				if (!((String) sectors.get(i)[2]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":group", (String) sectors.get(i)[2]));
+				else if (!((String) sectors.get(0)[2]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":group", (String) sectors.get(0)[2]));
+				if (!((String) sectors.get(i)[3]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":sequence", (String) sectors.get(i)[3]));
+				else if (!((String) sectors.get(0)[3]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":sequence", (String) sectors.get(0)[3]));
+				if (!((String) sectors.get(i)[4]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":period", (String) sectors.get(i)[4]));
+				else if (!((String) sectors.get(0)[4]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":period", (String) sectors.get(0)[4]));
+				if (sectors.get(i)[5] != Lit.UNKLIT)
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":category", LitSTR.get(sectors.get(i)[5])));
+				else if (sectors.get(0)[5] != Lit.UNKLIT)
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":category", LitSTR.get(sectors.get(0)[5])));
+				if (!((String) sectors.get(i)[6]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":sector_start", (String) sectors.get(i)[6]));
+				if (!((String) sectors.get(i)[7]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":sector_end", (String) sectors.get(i)[7]));
+				if (!((String) sectors.get(i)[8]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":radius", (String) sectors.get(i)[8]));
+				else if (!((String) sectors.get(0)[8]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":radius", (String) sectors.get(0)[8]));
+				if (!((String) sectors.get(i)[9]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":height", (String) sectors.get(i)[9]));
+				else if (!((String) sectors.get(0)[9]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":height", (String) sectors.get(0)[9]));
+				if (!((String) sectors.get(i)[10]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":range", (String) sectors.get(i)[10]));
+				else if (!((String) sectors.get(0)[10]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":range", (String) sectors.get(0)[10]));
+				if (sectors.get(i)[11] != Vis.UNKVIS)
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":visibility", VisSTR.get(sectors.get(i)[11])));
+				else if (sectors.get(0)[11] != Vis.UNKVIS)
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":visibility", VisSTR.get(sectors.get(0)[11])));
+				if (sectors.get(i)[12] != Exh.UNKEXH)
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":exhibition", ExhSTR.get(sectors.get(i)[12])));
+				else if (sectors.get(0)[12] != Exh.UNKEXH)
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":exhibition", ExhSTR.get(sectors.get(0)[12])));
+				if (!((String) sectors.get(i)[13]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":orientation", (String) sectors.get(i)[13]));
+				if (!((String) sectors.get(i)[14]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":multiple", (String) sectors.get(i)[14]));
+				else if (!((String) sectors.get(0)[14]).isEmpty())
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light" + secStr + ":multiple", (String) sectors.get(0)[14]));
+			}
+
+			if (getFogSound() != Fog.NOFOG) {
+				if (getFogSound() == Fog.FOGSIG)
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:fog_signal", "yes"));
+				else
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:fog_signal:category", FogSTR.get(getFogSound())));
+				if (!getFogGroup().isEmpty()) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:fog_signal:group", getFogGroup()));
+				}
+				if (!getFogPeriod().isEmpty()) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:fog_signal:period", getFogPeriod()));
+				}
+				if (!getFogSequence().isEmpty()) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:fog_signal:sequence", getFogSequence()));
+				}
+				if (!getFogRange().isEmpty()) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:fog_signal:range", getFogRange()));
+				}
+			}
+
+			if (RoType != Cat.NOROS) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:radio_station:category", CatSTR.get(getRadio())));
+			}
+
+			if (RaType != Rtb.NORTB) {
+				if (getRadar() == Rtb.REFLECTOR) {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:radar_reflector", "yes"));
+				} else {
+					Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:radar_transponder:category", RtbSTR.get(getRadar())));
+					if (!getRaconGroup().isEmpty()) {
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:radar_transponder:group", getRaconGroup()));
+					}
+					if (!getRaconPeriod().isEmpty()) {
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:radar_transponder:period", getRaconPeriod()));
+					}
+					if (!getRaconSequence().isEmpty()) {
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:radar_transponder:sequence", getRaconSequence()));
+					}
+					if (!getRaconRange().isEmpty()) {
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:radar_transponder:range", getRaconRange()));
+					}
+					if ((!getRaconSector1().isEmpty()) && (!getRaconSector2().isEmpty())) {
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:radar_transponder:sector_start", getRaconSector1()));
+						Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:radar_transponder:sector_end", getRaconSector2()));
+					}
+				}
+			}
+
+			if (!getInfo().isEmpty()) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:information", getInfo()));
+			}
+			if (!getSource().isEmpty()) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:source", getSource()));
+			}
+			if (getStatus() != Sts.UNKSTS) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:status", StsSTR.get(getStatus())));
+			}
+			if (getConstr() != Cns.UNKCNS) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:construction", CnsSTR.get(getConstr())));
+			}
+			if (getConsp() != Con.UNKCON) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:conspicuity", ConSTR.get(getConsp())));
+			}
+			if (getRefl() != Con.UNKCON) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:reflectivity", ConSTR.get(getRefl())));
+			}
+			if (!getRef().isEmpty()) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:reference", getRef()));
+			}
+			if (!getLightRef().isEmpty()) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:light:reference", getLightRef()));
+			}
+			if (!getFixme().isEmpty()) {
+				Main.main.undoRedo.add(new ChangePropertyCommand(node, "seamark:fixme", getFixme()));
+			}
+		}
+	}
+
+}
Index: /applications/editors/josm/plugins/smed/src/smed/Smed.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/Smed.java	(revision 29895)
+++ /applications/editors/josm/plugins/smed/src/smed/Smed.java	(revision 29895)
@@ -0,0 +1,14 @@
+package smed;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.MainMenu;
+import org.openstreetmap.josm.plugins.Plugin;
+import org.openstreetmap.josm.plugins.PluginInformation;
+
+public class Smed extends Plugin {
+
+	public Smed(PluginInformation info) {
+        super(info);
+        MainMenu.add(Main.main.menu.toolsMenu, new SmedAction());
+    }
+}
Index: /applications/editors/josm/plugins/smed/src/smed/SmedAction.java
===================================================================
--- /applications/editors/josm/plugins/smed/src/smed/SmedAction.java	(revision 29895)
+++ /applications/editors/josm/plugins/smed/src/smed/SmedAction.java	(revision 29895)
@@ -0,0 +1,119 @@
+/* Copyright 2013 Malcolm Herring
+ *
+ * This 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, version 3 of the License.
+ *
+ * For a copy of the GNU General Public License, see <http://www.gnu.org/licenses/>.
+ */
+
+package smed;
+
+import java.awt.*;
+import java.awt.event.*;
+import java.util.*;
+import java.util.Map.Entry;
+
+import javax.swing.*;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+import org.openstreetmap.josm.actions.JosmAction;
+import org.openstreetmap.josm.gui.MapView;
+import org.openstreetmap.josm.gui.MapView.EditLayerChangeListener;
+import org.openstreetmap.josm.gui.layer.*;
+import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.imagery.ImageryInfo;
+import org.openstreetmap.josm.data.osm.*;
+import org.openstreetmap.josm.data.osm.event.*;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.*;
+
+import messages.Messages;
+
+import panels.PanelMain;
+
+public class SmedAction extends JosmAction implements SelectionChangedListener {
+
+	private static final long serialVersionUID = 1L;
+	private static String editor = tr("SeaMap Editor");
+	public static JFrame editFrame = null;
+	private boolean isOpen = false;
+	public static PanelMain panelMain = null;
+	public DataSet data = null;
+
+	public OsmPrimitive node = null;
+	private Collection<? extends OsmPrimitive> selection = null;
+
+	public SmedAction() {
+		super(editor, "Smed", editor, null, true);
+	}
+
+	@Override
+	public void actionPerformed(ActionEvent arg0) {
+		SwingUtilities.invokeLater(new Runnable() {
+			public void run() {
+				if (!isOpen)
+					createFrame();
+				else
+					editFrame.toFront();
+				isOpen = true;
+			}
+		});
+	}
+
+	protected void createFrame() {
+		editFrame = new JFrame(editor);
+		editFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
+		editFrame.addWindowListener(new java.awt.event.WindowAdapter() {
+			public void windowClosing(java.awt.event.WindowEvent e) {
+				closeDialog();
+			}
+		});
+		editFrame.setSize(new Dimension(480, 480));
+		editFrame.setLocation(100, 200);
+		editFrame.setResizable(true);
+		editFrame.setAlwaysOnTop(true);
+		editFrame.setVisible(false);
+		panelMain = new PanelMain(this);
+		editFrame.add(panelMain);
+		editFrame.add(panelMain);
+
+
+		// System.out.println("hello");
+	}
+
+	public void closeDialog() {
+		if (isOpen) {
+			editFrame.setVisible(false);
+			editFrame.dispose();
+			data = null;
+		}
+		isOpen = false;
+	}
+
+	@Override
+	public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
+		OsmPrimitive nextNode = null;
+		selection = newSelection;
+
+		for (OsmPrimitive osm : selection) {
+			nextNode = (OsmPrimitive) osm;
+			if (selection.size() == 1) {
+				if (nextNode.compareTo(node) != 0) {
+					node = nextNode;
+					panelMain.mark.parseMark(node);
+				}
+			} else {
+				node = null;
+				panelMain.mark.clrMark();
+				PanelMain.messageBar.setText(Messages.getString("OneNode"));
+			}
+		}
+		if (nextNode == null) {
+			node = null;
+			panelMain.mark.clrMark();
+			PanelMain.messageBar.setText(Messages.getString("SelectNode"));
+		}
+	}
+
+}
