/
area/
classes/net/sourceforge/pain/logic/
classes/net/sourceforge/pain/logic/event/
classes/net/sourceforge/pain/logic/fn/util/
classes/net/sourceforge/pain/network/console/
classes/net/sourceforge/pain/plugin/
classes/net/sourceforge/pain/plugin/reset/
classes/net/sourceforge/pain/plugin/shutdown/
classes/net/sourceforge/pain/plugin/social/
classest/net/sourceforge/pain/db/data/
doc/
doc/paindb/resources/
src/net/sourceforge/pain/logic/
src/net/sourceforge/pain/logic/event/
src/net/sourceforge/pain/logic/fn/util/
src/net/sourceforge/pain/network/console/
src/net/sourceforge/pain/network/console/telnet/
src/net/sourceforge/pain/plugin/
src/net/sourceforge/pain/plugin/command/
src/net/sourceforge/pain/plugin/reset/
src/net/sourceforge/pain/plugin/shutdown/
src/net/sourceforge/pain/plugin/social/
src/net/sourceforge/pain/util/
tests/
tests/net/sourceforge/pain/db/data/
package net.sourceforge.pain.util.rom;


import net.sourceforge.pain.data.*;
import net.sourceforge.pain.data.prototype.*;
import net.sourceforge.pain.data.type.*;
import net.sourceforge.pain.db.*;
import net.sourceforge.pain.util.*;
import net.sourceforge.pain.*;
import net.sourceforge.pain.logic.fn.*;

import java.io.*;
import java.util.*;


public final class Rom24ToPainConverter {

	private static final int[] defaultMoveDice = new int[]{1, 100, 0};

	private Rom24ToPainConverter() {
	};
	public static PainDB db = null;

	public static void main(String[] args) throws Exception {
		if (args.length < 2 || args[0] == null || args[1] == null) {
			System.err.println("Usage: <db file name> <area list file name>");
			return;
		}
		Log.info("Creating DB...");
		db = new PainDB(args[0]);
		db.ALLOW_PLAIN_WRITE = true;
		Core.setDB(db);
		Log.info("DB created");

		Log.info("Reading area list file..");
		File file = new File(args[1]);

		if (!file.exists()) {
			throw new RuntimeException("file " + args[1] + " not exists");
		}
		if (file.isDirectory()) {
			throw new RuntimeException("file " + args[1] + " is directory");
		}

		String path = file.getParent();
		BufferedReader reader = new BufferedReader(new FileReader(file));
		ArrayList files = new ArrayList();

		try {
			while (true) {
				String areaFileName = reader.readLine();
				if (areaFileName == null) {
					break;
				}
				areaFileName = areaFileName.trim();
				if (areaFileName.equals("$")) { // end of list
					break;
				}
				if (!areaFileName.startsWith("#") && !areaFileName.startsWith("!")) {
					files.add(path + File.separator + areaFileName);
				}
			}
		} finally {
			reader.close();
		}
		Log.info("Area list file read");

		Log.info("Loading areas..");
		ArrayList areas = new ArrayList();
		for (int i = 0; i < files.size(); i++) {
			String fileName = (String) files.get(i);
			Log.info("Loading area:" + fileName);
			Rom24AreaLoader area = new Rom24AreaLoader(fileName);
			area.load();
			if (area.areaName == null) {
				Log.warn("Area without name! file:" + fileName + " SKIPPING");
				continue;
			}
			areas.add(area);
			Log.info("Area:" + fileName + " loaded OK");
		}

		Log.info("ROM areas parsed!");

		// loading finished! converting

		Log.info("Creating world");

		World world = (World) db.getRoot();
		if (world == null) {
			world = Launcher.DatabaseConstructor.createSmallFantasyWorld(db);//:)
			db.setRoot(world);
		}
		world.setName("some world");

		Log.info("Creating areas and rooms");

		HashMap prototypes = new HashMap(); // by VNUM;
		HashMap spaces = new HashMap(); // room space by VNUM;
		HashMap resetGroupByArea = new HashMap(); // ResetGroup by rom area - used for reset binding

		Space birthSpaceCandidate = null;

		IndexedSpacesRegistry namedSpacesRegistry = world.getIndexedSpacesRegistry();
		for (int j = 0; j < areas.size(); j++) {
			Rom24AreaLoader romArea = (Rom24AreaLoader) areas.get(j);
			SpaceGroup area = (SpaceGroup) ObjectFactory.create(SpaceGroup.class);
			ResetGroup rg = (ResetGroup) ObjectFactory.create(ResetGroup.class);
			rg.setResetMessage(romArea.resetMessage);
			rg.setResetPeriod(Time.PULSE_PER_MIN * 3);
			rg.setNextResetTime(0);
			rg.setGroupInfo(romArea.areaName);
			rg.setGroupId(romArea.areaName.trim());
			world.getResetGroupRegistry().registerResetGroup(rg);
			resetGroupByArea.put(romArea, rg);
//			p.setVnum("area:" + j);
//			p.setLogin(romArea.areaName);
//			p.setAuthor(romArea.areaAuthor);
//			p.setDesc(romArea.areaName);

			// creating rooms;
			for (Iterator it = romArea.rooms.values().iterator(); it.hasNext();) {
				ROMRoom romRoom = (ROMRoom) it.next();
				Log.info("creating room:" + romRoom.vnum);
				IndexedSpace named = (IndexedSpace) ObjectFactory.create(IndexedSpace.class);
				named.setSpaceUniqueId(romRoom.vnum);
				namedSpacesRegistry.registerSpace(named);
				Space room = named.asSpace();

				room.setName(romRoom.name);
				room.setDesc(romRoom.desc);
				room.setCapacity(1000);
				//!!!rInfo.setArea(romArea);
				spaces.put(romRoom.vnum, room);
				area.addSpace(room);
				// exits will be bound later
			}

			//creating mobile prototypes
			Log.info("Creating creatures prototypes");
			Race defaultRace = (Race) world.getRaces().iterator().next(); // temporaty unprocessed
			for (Iterator it = romArea.mobiles.values().iterator(); it.hasNext();) {
				ROMMobile romMobile = (ROMMobile) it.next();
				Log.info("creating creature prototype:" + romMobile.vnum);
				PrototypeInfo p = (PrototypeInfo) ObjectFactory.create(PrototypeInfo.class);
				p.setVnum("creature:" + romMobile.vnum);
				p.setName(romMobile.shortDesc);
				LifeFormPrototype lfp = (LifeFormPrototype) p.addRole(LifeFormPrototype.class);
				PhysicalPrototype ph = (PhysicalPrototype) p.addRole(PhysicalPrototype.class);
				ph.setAppearanceDesc(romMobile.lookDesc);
				ph.setWeight(1);
				ph.setSize(1);

				InteractivePrototype ip = ph.asInteractivePrototype();
				ip.setTargetList(romMobile.nameList);
				ip.setInteractiveName(romMobile.shortDesc);
				ip.setDesc(romMobile.longDesc);


				lfp.setLifePointsDice(new Dice(romMobile.hitDice));
				lfp.setSex(romMobile.gender.equals("male") ? LifeFormPrototype.SEX_MALE : romMobile.gender.equals("female") ? LifeFormPrototype.SEX_FEMALE : romMobile.gender.equals("either") ? LifeFormPrototype.SEX_EITHER : LifeFormPrototype.SEX_UNDEFINED);
				lfp.setRace(defaultRace);

				MobilePrototype mp = (MobilePrototype) p.addRole(MobilePrototype.class);
				mp.setMovePointsDice(new Dice(defaultMoveDice));
				prototypes.put("creature:" + romMobile.vnum, p);

				EquippedPrototype eqp = (EquippedPrototype) p.addRole(EquippedPrototype.class);
				final SpacePrototype inventoryPrototype = (SpacePrototype) ObjectFactory.create(SpacePrototype.class);
				inventoryPrototype.setSpaceName("Inventory");
				inventoryPrototype.setSpaceDesc("");
				inventoryPrototype.setCapacity(Integer.MAX_VALUE);
				eqp.setInventoryPrototype(inventoryPrototype);

			}

			//creating object prototypes
			Log.info("Creating thing prototypes");
			for (Iterator it = romArea.objects.values().iterator(); it.hasNext();) {
				ROMObject romObject = (ROMObject) it.next();
				Log.info("creating thing prototype:" + romObject.vnum);
				PrototypeInfo p = (PrototypeInfo) ObjectFactory.create(PrototypeInfo.class);
				p.setName(romObject.shortDesc);
				p.setVnum("thing:" + romObject.vnum);
				PhysicalPrototype ph = (PhysicalPrototype) p.addRole(PhysicalPrototype.class);
				ph.setAppearanceDesc(romObject.longDesc);
				ph.setWeight(1);
				ph.setSize(1);

				InteractivePrototype ip = ph.asInteractivePrototype();
				ip.setTargetList(romObject.nameList);
				ip.setDesc(romObject.shortDesc);

				prototypes.put("thing:" + romObject.vnum, p);
			}
		}
		// binding room exits
		// and resets
		Log.info("Creating exits and resets");
		for (int j = 0; j < areas.size(); j++) {
			Rom24AreaLoader romArea = (Rom24AreaLoader) areas.get(j);
			ResetGroup rg = (ResetGroup) resetGroupByArea.get(romArea);
			for (Iterator it = romArea.rooms.values().iterator(); it.hasNext();) {
				ROMRoom romRoom = (ROMRoom) it.next();
				Space space1 = (Space) spaces.get(romRoom.vnum);
				for (int i = 0; i < romRoom.exits.length; i++) {
					if (romRoom.exits[i] != null) {
						if (birthSpaceCandidate == null) {
							if (space1.getName().toLowerCase().indexOf("temple") > 0) {
								birthSpaceCandidate = space1;
							}
						}
						Space space2 = (Space) spaces.get(romRoom.exits[i]);
						if (space2 == null) {
							continue;
						}
						LinkedSpace link1 = (LinkedSpace) (space1.is(LinkedSpace.class) ? space1.getRole(LinkedSpace.class) : space1.addRole(LinkedSpace.class));
//						LinkedSpace link2 = (LinkedSpace) (space2.is(LinkedSpace.class) ? space2.getRole(LinkedSpace.class) : space2.addRole(LinkedSpace.class));
						Exit exit1 = (Exit) ObjectFactory.create(Exit.class);
//						Exit exit2 = (Exit) ObjectFactory.create(Exit.class);
						exit1.setTargetSpace(space2);
						exit1.setExitDesc(romRoom.exitsDescs[i]);
						exit1.setMoveConst(1);
						link1.setExit(i, exit1);
//						link2.setExit(LinkedSpace.reverseDir[i], exit2);
//						exit2.setTargetSpace(space1);
					}
				}
				// adding one dir way from the initial space1 to our world
				Space sp = (Space) spaces.values().iterator().next();
				IndexedSpace initial = namedSpacesRegistry.getSpace("initial");
				LinkedSpace link = (LinkedSpace) initial.getRole(LinkedSpace.class);
				if (link == null) {
					link = (LinkedSpace) initial.addRole(LinkedSpace.class);
				}
				Exit e = (Exit) ObjectFactory.create(Exit.class);
				link.setExit(LinkedSpace.DIR_DOWN, e);
				e.setTargetSpace(sp);


				if (romRoom.resets.size() > 0) {
					for (int r = 0; r < romRoom.resets.size(); r++) {
						Object romReset = romRoom.resets.get(r);
						PrototypeInfo p;
						if (romReset instanceof ROMMobileReset) {
							ROMMobileReset mreset = (ROMMobileReset) romReset;
							Log.info("mob reset :" + mreset.mob.vnum);
							p = (PrototypeInfo) prototypes.get("creature:" + mreset.mob.vnum);
						} else {// this is ROMObjectReset
							ROMObjectReset oreset = (ROMObjectReset) romReset;
							Log.info("obj reset :" + oreset.obj.vnum);
							p = (PrototypeInfo) prototypes.get("thing:" + oreset.obj.vnum);
						}
						if (p == null) {
							Log.warn("Prototype is not found for reset:" + romReset.toString() + "space1:" + romRoom.vnum + " space1 name:" + romRoom.name);
						} else {
							SpaceReset reset = (SpaceReset) ObjectFactory.create(SpaceReset.class);
							reset.setResettedPrototype(p);
							reset.setLocation(space1);
							RelocateFn.addToSpace(space1, reset.asLocated());
							rg.addReset(reset.asReset());
						}
					}
				}
			}// rooms
		} // areas
		if (birthSpaceCandidate == null && world.getDefaultBirthSpace() == null) {
			// any space
			world.setDefaultBirthSpace((Space) spaces.values().iterator().next());
		}

		Log.debug("commiting!");
		db.flush();
		Log.info("schema converted OK!");
		db.close();
	}
}