This application uses multiple plugin modules to enable more efficient storage and retrieval of map data.  Each map can have a couple hundred default annotations, with 3 language possibilites for each resource string, multiplied by 45 maps, and there are thousands of default annotations - if each map only has 100 annotations, that's 13,500 resource strings alone.  Keeping that information stored during the entire time the plugin is loaded will consume an excessive amount of memory with little if any benefit, not to mention the processing hit when all of those values have to be searched to display the current map's icons and seach list. For this reason, I chose to process the default data into separate files that would load only the data for the currently selected map whenever the user makes a selection.

Great. So why four separate plugins? Well, in an attempt to prevent interfacing with third party external applications in real time, Turbine does not allow plugins to save or load data from plugindata files in real time after the plugin has been initialized and prior to being unloaded. For this reason, there are four plugins that work together to allow the appearance of realtime data storage and retrieval. When the user selects a map, the main plugin "MoorMap" will load a secondary plugin, "MoorMapLoader" which exists solely to unload "MoorMap", which puts "MoorMap" into the "unloading" state and calls it's "Unload" method, allowing it to store a flag indicating that it is being reloaded as well as the current filter and search settings and the map to load. Then "MoorMapLoader" reloads "MoorMap".  Upon load, "MoorMap" checks for the "reloading" flag, and if present, loads the specified map, filter, and search settings while bypassing it's default settings.  This allows me to use far less memory and resources since I only retain the current map's annotations and resource strings in memory. This whole mechanism would be a LOT simpler without the ineffectual 15 second delay on saving/loading data (I say ineffectual because it is just an irritant to those who wish to write complex plugins that require external storage to be efficient and hasn't actually stopped anyone from accessing outside data in real time). I understand Turbine's concern, but the loss of efficiency in useful, legitimate plugins due to this mechanism is too high a price, especially when the restriction doesn't even work. OK. Enough soapboxing. A second set of plugins, "MoorMapDefaults" and "MoorMapTerminator" work in a similar fashion to allow re-processing the Defaults.lua file in response to a user request or automatically when a new version of the plugin loads for the first time.  "MoorMap" will load "MoorMapDefaults" which processes the data and then loads "MoorMapTerminator". "MoorMapTerminator" unloads "MoorMapDefaults" in it's initialization routine.  "MoorMap" detects the presence of "MoorMapTerminator" (which doesn't show up until it's done it's job) and unloads "MoorMapTerminator". Since the plugins can't directly communicate, there is no legitimate way for "MoorMapDefaults" to have a status UI AND tell "MoorMap" when it's done processing, thus the need for the third plugin since "MoorMapTerminator" doesn't get loaded until "MoorMapDefaults" is done processing, so it's very existance IS the communication.

EXTERNAL INTEGRATION USING THE "PING" COMMAND:
MoorMap can be controlled from an external plugin by adding a quickslot control with a shortcut command.  The shortcut can be programatically updated to contain the desired information so that when the user clicks on it, the correct map opens, an annotation is located or added and then a flashing "ping" is put on the map at the location.

The syntax for the "ping" command is fairly simple, "/Moormap ping MapID:NSCoord:EWCoord:Name:Description".  MapID is one of the predefined map IDs below. NSCoord is the North/South map coordinate, with north values being positive and south values being negative.  EWCoord is the East/West map coordinate with East values being positive and West values being negative.  Name is a short name that will be listed on the annotation and should be the proper name of the location/npc if possible to avoid creating duplicate annotations with different names. Description is the text that will be displayed when a user clicks on the annotation on the map.

Note, map ID and the coordinates must be valid for the map indicated or an error message will be written to the standard chat channel and no annotation will be added. Annotations with the same exact name within one map coordinate unit of each other will be considered to be the same annotation, no new annotation will be added, but the ping will display at the position in the ping command, either at or next to the existing annotation.

You may want to add an additional control on top of the quickslot control with a map icon for cosmetic purposes, just be sure to make the icon not mouse visible so that clicks will be sent through to the quickslot under it since the only way for Lua to actually cause an action is by user input.

Remember to verify that MoorMap is loaded when you set the shortcut command or it will not be able to respond.  To verify that MoorMap is loaded, use the following code:
	local tmpIndex;
	local found=false;
	for tmpIndex=1,#Turbine.PluginManager:GetLoadedPlugins() do
		if Turbine.PluginManager:GetLoadedPlugins()[tmpIndex].Name=="MoorMap" then
			found=true;
			break;
		end
	end
	if not found then
		Turbine.PluginManager.LoadPlugin("MoorMap");
	end

You should test whether the user has installed MoorMap and use a variable to track that status so that you can conditionally enable/disable the quickslot functionality.  To test whether MoorMap is installed, use:

MoorMapInstalled=false;
	local tmpIndex;
	Turbine.PluginManager:RefreshAvailablePlugins(); -- just in case the user installed MoorMap since the client has been running.
	for tmpIndex=1,#Turbine.PluginManager:GetAvailablePlugins() do
		if Turbine.PluginManager:GetAvailablePlugins()[tmpIndex].Name=="MoorMap" then
			MoorMapInstalled=true;
			break;
		end
	end


If MoorMap has never been run before, it will automatically load it's defaults, unload and then reload. MoorMap will load minimized by default (there are options to display on load or to hide the minimized icon in the Options dialog).

MAP IDs
This is a list of the Parchement maps and their assigned IDs in MoorMap:
Ettenmoors              	1
Middle Earth             	2
Eriador                 	3
Angmar                  	4
Bree-land               	5
Archet                  	6
Northern Barrow Downs        	7
Southern Barrow Downs        	8
Bree                    	9
Bree-land Homesteads        	10
The Old Forest            	11
Enedwaith               	12
Ered Luin               	13
Falathlorn Homesteads        	14
Thorin's Gate            	15
Thorin's Hall Homesteads	16
Eregion                 	17
The Walls of Moria         	18
Evendim                     	19
Annuminas                	20
Forochel                	21
Frostbluff                	22
Lone-lands              	23
Misty Mountatins        	24
North Downs                	25
The Shire                	26
Shire Homesteads        	27
Trollshaws                	28
Rivendell                	29
Rhovanion                	30
Lothlrien              	31
Caras Galadhon             	32
Mirkwood                	33
Moria                    	34
Durin's Way                	35
Flaming Deeps                	36
Foundations of Stone        	37
Nud Melek                	38
Redhorn Lodes                	39
The Grand Stair           	40
The Great Delving           	41
The Silvertine Lodes        	42
The Waterworks          	43
Zelem Melek              	44
Zirak Zigil                	45
