package adecWatt.model;

import java.io.File;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.TreeMap;
import javax.swing.JOptionPane;

import misc.Bundle;
import misc.Config;
import misc.RemoteUpdate;
import misc.StateNotifier;
import misc.Story;

/**
 */
public class AdecWatt extends StateNotifier {

    static public final double lowLevel = 0.3;

    static public final String
	BroadcastUnitRoots		= "UnitRoots",
	BroadcastConsole		= "Console",
	BroadcastUnitStory		= "UnitStory",
	BroadcastStory			= Story.BroadcastStory,
	BroadcastTitle			= "Title",
	BroadcastUpdateUnitTree		= "UpdateUnitTree", //UpdateWorkspaceTree
	BroadcastUpdateWorkspace	= "UpdateWorkspace";

    // ========================================
    private ImageDB iconDB = new ImageDB (this, ImageDB.iconDirName);
    private ImageDB imageDB = new ImageDB (this, ImageDB.imageDirName);
    private PermanentDB permanentDB = new PermanentDB (this);
    private InseeDB inseeDB;
    private User user = new User ();
    private boolean
	handleGlue = Config.getBoolean ("HandleGlue", true),
	boundGlue = Config.getBoolean ("BoundGlue", true),
	gridGlue = Config.getBoolean ("GridGlue", true),
	inSegmentGlue = Config.getBoolean ("InSegmentGlue", true);

    public User				getUser ()		{ return user; }
    public PermanentDB 			getPermanentDB ()	{ return permanentDB; }
    public ImageDB 			getIconDB ()		{ return iconDB; }
    public ImageDB 			getImageDB ()		{ return imageDB; }
    public InseeDB 			getInseeDB ()		{ return inseeDB; }
    public Hashtable<String, Unit<?>>	getNamedRoots ()	{ return permanentDB.namedRoots; }
    public boolean			getHandleGlue ()	{ return handleGlue; }
    public boolean			getBoundGlue ()		{ return boundGlue; }
    public boolean			getGridGlue ()		{ return gridGlue; }
    public boolean			getInSegmentGlue ()	{ return inSegmentGlue; }
    public void	setHandleGlue (boolean handleGlue)		{ Config.setBoolean ("HandleGlue", this.handleGlue = handleGlue); }
    public void	setBoundGlue (boolean boundGlue)		{ Config.setBoolean ("BoundGlue", this.boundGlue = boundGlue); }
    public void	setGridGlue (boolean gridGlue)			{ Config.setBoolean ("GridGlue", this.gridGlue = gridGlue); }
    public void	setInSegmentGlue (boolean inSegmentGlue)	{ Config.setBoolean ("InSegmentGlue", this.inSegmentGlue = inSegmentGlue); }

    // ========================================
    public AdecWatt () {
	reset ();
    }

    public void reloadSoft () {
	if (JOptionPane.showConfirmDialog (null, Bundle.getMessage ("UpdateSoft"),
					   Bundle.getTitle ("UpdateSoft"),
					   JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE) == JOptionPane.YES_OPTION)
	    return;
	File softDir = new File (Config.getPWD ().getParentFile (), "soft");
	File jar = new File (softDir, "UpdatedAdecWatt.jar");
	RemoteUpdate.launch (jar);
    }

    public void reset () {
	File dir = Config.getPWD ().getParentFile ();
	RemoteUpdate.renameNewFile (dir);
	if (RemoteUpdate.newFileExists (dir))
	    reloadSoft ();
	iconDB.reload ();
	imageDB.reload ();
	permanentDB.reload ();
	inseeDB = InseeDB.readDocument (Config.getDataUrl ("data", "server", "Insee.xml"));
	broadcastUpdate (BroadcastUnitRoots);
    }

    public void updateStory () {
	broadcastUpdate (BroadcastStory);
    }


    // ========================================
    public void newNamePlan () {
	TreeMap<String, String> iconMap = iconDB.newNamePlan ();
	TreeMap<String, String> imageMap = imageDB.newNamePlan ();
	permanentDB.newNamePlan (iconMap, imageMap);
	saveAll ();
    }

    // ========================================
    public boolean getModified () {
	for (Unit<?> unit : permanentDB.idUnit.values ())
	    if (unit.story.isModified ())
		return true;
	return false;
    }

    // ========================================
    public void saveAll () {
	for (Unit<?> root : permanentDB.namedRoots.values ()) {
	    // if (root.story.isModified ())
	    // 	root.save ();
	    for (Enumeration<?> e = root.unitNode.depthFirstEnumeration (); e.hasMoreElements (); ) {
		Unit<?> unit = ((UnitNode<?>) e.nextElement ()).getUnit ();
		if (unit.story.isModified ())
		    unit.save ();
	    }
	}
    }

    // ========================================
}
