/*
 * This file is part of NixNote/NeighborNote 
 * Copyright 2009 Randy Baumgarte
 * Copyright 2013 Yuki Takahashi
 * 
 * This file may be licensed under the terms of of the
 * GNU General Public License Version 2 (the ``GPL'').
 *
 * Software distributed under the License is distributed
 * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
 * express or implied. See the GPL for the specific language
 * governing rights and limitations.
 *
 * You should have received a copy of the GPL along with this
 * program. If not, go to http://www.gnu.org/licenses/gpl.html
 * or write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
*/

package cx.fbn.nevernote;


import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.lang3.StringEscapeUtils;

import com.evernote.edam.type.Accounting;
import com.evernote.edam.type.PrivilegeLevel;
import com.evernote.edam.type.User;
import com.evernote.edam.type.UserAttributes;
import com.swabunga.spell.engine.Configuration;
import com.trolltech.qt.core.QByteArray;
import com.trolltech.qt.core.QFile;
import com.trolltech.qt.core.QSettings;
import com.trolltech.qt.core.QSize;
import com.trolltech.qt.gui.QPalette;
import com.trolltech.qt.gui.QSystemTrayIcon;

import cx.fbn.nevernote.config.FileManager;
import cx.fbn.nevernote.config.InitializationException;
import cx.fbn.nevernote.config.StartupConfig;
import cx.fbn.nevernote.gui.ContainsAttributeFilterTable;
import cx.fbn.nevernote.gui.DateAttributeFilterTable;
import cx.fbn.nevernote.gui.SearchEdit.SearchTarget;
import cx.fbn.nevernote.gui.ShortcutKeys;
import cx.fbn.nevernote.sql.DatabaseConnection;
import cx.fbn.nevernote.sql.driver.NSqlQuery;
import cx.fbn.nevernote.utilities.ApplicationLogger;
import cx.fbn.nevernote.utilities.Pair;


//*****************************************************
//*****************************************************
//* Global constants & static functions used by 
//* multiple threads.
//*****************************************************
//*****************************************************

public class Global {
	// Set current version and the known versions.
	public static String version = "0.5";
	public static String[] validVersions = {"0.5", "0.4.1", "0.4", "0.3", "0.2", "0.1.3", "0.1.2", "0.1.1", "0.1"};
	
    public static String username = ""; 
    //public static String password = "";     
    

    // Each thread has an ID.  This is used primarily to check the status
    // of running threads.
    public static final int mainThreadId=0;
    public static final int syncThreadId=1;
    public static final int tagCounterThreadId=2;
    public static final int trashCounterThreadId=3;   // This should always be the highest thread ID
    public static final int indexThreadId=4;   	// Thread for indexing words
    public static final int saveThreadId=5;   	// Thread used for processing data to saving content
    public static final int notebookCounterThreadId=6;   // Notebook Thread
    public static final int indexThread03Id=7;   // unused
    public static final int indexThread04Id=8;   // unused
    public static final int dbThreadId=9;   // This should always be the highest thread ID
    public static final int threadCount = 10;
    
    
    // These variables deal with where the list of notes appears
    // They will either be vertical (View_List_Narrow) or will be
    // on top of the note (View_List_Wide).  It also has the size of
    // thumbnails displayed in each view
    public static int View_List_Wide = 1;
    public static int View_List_Narrow = 2;
    public static QSize smallThumbnailSize = new QSize(100,75);
    public static QSize largeThumbnailSize = new QSize(300,225);

    // This is used to keep a running list of passwords that the user
    // wants us to remember.
    public static HashMap<String,Pair<String,String>> passwordSafe = new HashMap<String, Pair<String,String>>();
    public static List<Pair<String,String>> passwordRemember = new ArrayList<Pair<String,String>>();
    
    
    //public static String currentNotebookGuid;
    
    // These deal with Evernote user settings
    public static User user; 
    public static long authTimeRemaining;
    public static long authRefreshTime;
    public static long failedRefreshes = 0; 
    public static String userStoreUrl;
    public static String noteStoreUrl;
    public static String noteStoreUrlBase;

    // When we want to shut down we set this to true to short
    // circut other threads
    public static boolean keepRunning;
        
    // In the note list, these are the column numbers
    // so I don't need to hard code numbers.
    public static int noteTableCreationPosition = 0;
    public static int noteTableTitlePosition = 1;
    public static int noteTableTagPosition = 2;
    public static int noteTableNotebookPosition = 3;
    public static int noteTableChangedPosition = 4;
    public static int noteTableGuidPosition = 5;
    public static int noteTableAuthorPosition = 6;
    public static int noteTableSourceUrlPosition = 7;
    public static int noteTableSubjectDatePosition = 8;
    public static int noteTableSynchronizedPosition = 9;
    public static int noteTableThumbnailPosition = 10;
    public static int noteTablePinnedPosition = 11;
    public static int noteTableColumnCount = 12;
    public static Integer cryptCounter = 0;
    
    //public static int minimumWordCount = 2;
    
    // Regular expression to parse text with when indexing
//    private static String wordRegex;
    
    // Experimental fixes.  Set via Edit/Preferences/Debugging
    public static boolean enableCarriageReturnFix = false;
    public static boolean enableHTMLEntitiesFix = false;
    
    // Used to set & retrieve ini & Windows registry settings
    public static QSettings	settings;     // Set & get ini settings
    public static boolean isConnected;    // Are we connected to Evernote
    public static boolean showDeleted = false;   // Show deleted notes?
    public static boolean disableUploads = false;  // Should we disable uploads (used in testing features)
	public static int messageLevel;   // The level of messages to write to the log files
	public static String tagDelimeter = ",";   // This is used to separate out tag names when entering above note
	public static String attachmentNameDelimeter = "------";  // Used to separate out attachment names in the res directory
	
	
	//* Database fields
	public static String	databaseName = new String("NeverNote");  // database name.  used for multiple databases to separate settings.
	public static String	indexDatabaseName = new String("Index"); // searchable words database
	public static String	resourceDatabaseName = new String("Resources");  // attachments database
	public static String behaviorDatabaseName = new String("Behavior"); // 操作履歴データベース	
	
	public static DateAttributeFilterTable createdSinceFilter;
	public static DateAttributeFilterTable createdBeforeFilter;
	public static DateAttributeFilterTable changedSinceFilter;
	public static DateAttributeFilterTable changedBeforeFilter;
	public static ContainsAttributeFilterTable containsFilter;
	
	// Log file used for debugging
	public static ApplicationLogger    logger;
	//PrintStream stdoutStream;
	
	// Application key shortcuts & appearance
	public static QPalette 				originalPalette;
	public static ShortcutKeys			shortcutKeys;
	
	public static boolean				disableViewing;  // used to disable the editor
	
	// When saving a note, this is a list of things we strip out because Evernote hates them
	public static List<String>				invalidElements = new ArrayList<String>();
	public static HashMap<String, ArrayList<String>> 	invalidAttributes = new HashMap<String, ArrayList<String>>();
	
	public static boolean mimicEvernoteInterface; // Try to mimic Evernote or allow multiple notebook selection
	public static HashMap<String,String> resourceMap;   // List of attachments for a note.
	public static String cipherPassword = "";    // If the database is encrypted, this stores the password
	public static String databaseCache = "16384";  // Default DB cache size
	
	// These are used for performance testing
	static Calendar startTraceTime;   
	static Calendar intervalTraceTime;
	
	static boolean syncOnly;
	
	private static FileManager fileManager;  // Used to access files & directories
	
    // Do initial setup 
    public static void setup(StartupConfig startupConfig) throws InitializationException  {
    	String settingFileName = new String("NeighborNote.ini");
    	
    	// バージョン0.1.2以下で作成された古い設定ファイルを見つけたら、ホームディレクトリに移動させる。
    	String oldSettingPath = new QSettings(settingFileName, QSettings.Format.IniFormat).fileName();
    	File homeDir = new File(FileManager.toPlatformPathSeparator(startupConfig.getHomeDirPath()));
    	String homePath = FileManager.slashTerminatePath(homeDir.getPath());
    	if (QFile.exists(oldSettingPath)) {
    		QFile file = new QFile(oldSettingPath);
    		file.copy(homePath + settingFileName);
    		file.remove();
    	}
    	
        settings = new QSettings(homePath + settingFileName, QSettings.Format.IniFormat);
        
        disableViewing = startupConfig.getDisableViewing();
        syncOnly = startupConfig.isSyncOnly();

        fileManager = new FileManager(startupConfig.getHomeDirPath(), startupConfig.getProgramDirPath());


		getServer();  // Setup URL to connect to
		
		// Get regular expressions used to parse out words
//		settings.beginGroup("General");
//		String regex = (String) settings.value("regex", "[,\\s]+");
//		setWordRegex(regex);
//		settings.endGroup();
		
		//Setup debugging information
		settings.beginGroup("Debug");
		String msglevel = (String) settings.value("messageLevel", "Low");
		settings.endGroup();
		
		
		//messageLevel = 1;
		setMessageLevel(msglevel);
		keepRunning = true;  // Make sure child threads stay running
		disableUploads = disableUploads();  // Should we upload anything?  Normally false.
		//disableUploads = true;  //***** DELETE THIS LINE *******
		enableCarriageReturnFix = enableCarriageReturnFix();  // Enable test fix?
		enableHTMLEntitiesFix = enableHtmlEntitiesFix();  // Enable test fix?
		
		logger = new ApplicationLogger("global.log");  // Setup log for this class 
		shortcutKeys = new ShortcutKeys();  // Setup keyboard shortcuts.
		mimicEvernoteInterface = getMimicEvernoteInterface();  // Should we mimic Evernote's notebook behavior
		resourceMap = new HashMap<String,String>();  // Setup resource map used to store attachments when editing
			
		databaseCache = getDatabaseCacheSize();	 // Set database cache size	
		
		Global.username = getUserInformation().getUsername();
    }

    // Get/Set word parsing regular expression
//    public static String getWordRegex() {
//    	return wordRegex;
//    }
//    public static void setWordRegex(String r) {
//    	wordRegex = r;
//    }

   // Set the debug message level
   public static void setMessageLevel(String msglevel) {
    	if (msglevel.equalsIgnoreCase("low")) 
			messageLevel = 1;
		if (msglevel.equalsIgnoreCase("medium")) 
			messageLevel = 2;
		if (msglevel.equalsIgnoreCase("high")) 
				messageLevel = 3;
		if (msglevel.equalsIgnoreCase("extreme")) 
					messageLevel = 4;
		settings.beginGroup("Debug");
		settings.setValue("messageLevel", msglevel);
		settings.endGroup();    	
    }

   //****************************************************
   //****************************************************
   //** Save user account information from Evernote
   //****************************************************
   //****************************************************
    public static void saveUserInformation(User user) {
    	settings.beginGroup("User");
		settings.setValue("id", user.getId());
		settings.setValue("username", user.getUsername());
		settings.setValue("email", user.getEmail());
		settings.setValue("name", user.getName());
		settings.setValue("timezone", user.getTimezone());
		settings.setValue("privilege", user.getPrivilege().getValue());
		settings.setValue("created", user.getCreated());
		settings.setValue("updated", user.getUpdated());
		settings.setValue("deleted", user.getDeleted());
		settings.setValue("shard", user.getShardId());
		settings.endGroup();
		isPremium();
		if (user.getAttributes()!=null)
			saveUserAttributes(user.getAttributes());
		if (user.getAccounting()!=null)
			saveUserAccounting(user.getAccounting());

    }
    public static User getUserInformation() {
    	User user = new User();
    	settings.beginGroup("User");
    	try {	
    		user.setId((Integer)settings.value("id", 0));    		
    	} catch  (java.lang.ClassCastException e) {
    		user.setId(new Integer((String)settings.value("id", "0")));
    	}
		String username = (String)settings.value("username", "");
		String email = (String)settings.value("email", "");
		String name = (String)settings.value("name", "");
		String timezone = (String)settings.value("timezone", "");
		Integer privilege = 0;
		try {	
			privilege = new Integer((String)settings.value("privilege", "0"));			
		} catch (java.lang.ClassCastException e) {
			privilege = (Integer)settings.value("privilege", 0);
		}

		try {	
			String date = (String)settings.value("created", "0");
			user.setCreated(new Long(date));
			date = (String)settings.value("updated", "0");
			user.setUpdated(new Long(date));
			date = (String)settings.value("deleted", "0");
			user.setDeleted(new Long(date));
		} catch (java.lang.ClassCastException e) {
			Long date = (Long)settings.value("created", 0);
			user.setCreated(date);
			date = (Long)settings.value("updated", 0);
			user.setUpdated(date);
			date = (Long)settings.value("deleted", 0);
			user.setDeleted(date);
		}

		String shard = (String)settings.value("shard", "");
    	settings.endGroup();
    	
    	user.setUsername(username);
    	user.setEmail(email);
    	user.setName(name);
    	user.setTimezone(timezone);
    	PrivilegeLevel userLevel = PrivilegeLevel.findByValue(privilege);
    	user.setPrivilege(userLevel);
    	user.setShardId(shard);
    	return user;
    }
    
    public static void saveUserAttributes(UserAttributes attrib) {
    	settings.beginGroup("UserAttributes");
		settings.setValue("defaultLocationName", attrib.getDefaultLocationName());
		settings.setValue("defaultLatitude", attrib.getDefaultLocationName());
		settings.setValue("defaultLongitude", attrib.getDefaultLocationName());
		settings.setValue("incomingEmailAddress", attrib.getIncomingEmailAddress());
		settings.endGroup();
    }
    public static UserAttributes getUserAttributes() {
    	settings.beginGroup("UserAttributes");
    	UserAttributes attrib = new UserAttributes();
		attrib.setDefaultLocationName((String)settings.value("defaultLocationName",""));
		attrib.setDefaultLatitudeIsSet(false);
		attrib.setDefaultLongitudeIsSet(false);
		attrib.setIncomingEmailAddress((String)settings.value("incomingEmailAddress", ""));
		settings.endGroup();
		return attrib;
    }
    public static void saveUserAccounting(Accounting acc) {
    	settings.beginGroup("UserAccounting");
		settings.setValue("uploadLimit", acc.getUploadLimit());
		settings.setValue("uploadLimitEnd", acc.getUploadLimitEnd());
		settings.setValue("uploadLimitNextMonth", acc.getUploadLimitNextMonth());
		settings.setValue("premiumServiceStart", acc.getPremiumServiceStart());
		settings.setValue("nextPaymentDue", acc.getNextPaymentDue());
		settings.setValue("uploadAmount", acc.getUpdated());
		settings.endGroup();
    }
    public static long getUploadLimitEnd() {
    	Long limit;
    	settings.beginGroup("UserAccounting");
    	
    	// Upload limit
		try {
			String val  = (String)settings.value("uploadLimitEnd", "0");
			limit = new Long(val.trim());
		} catch (Exception e) {
			try {
				limit = (Long)settings.value("uploadLimitEnd", 0);
			} catch (Exception e1) {
				limit = new Long(0);
			}
		}
	
		// return value
    	settings.endGroup();
    	return limit;
    }
    public static void saveUploadAmount(long amount) {
    	settings.beginGroup("UserAccounting");
		settings.setValue("uploadAmount", amount);
		settings.endGroup();
   }
    public static long getUploadAmount() {
		long amt=0;
		settings.beginGroup("UserAccounting");
		try {
			String num = (String)settings.value("uploadAmount", "0");
			amt = new Long(num.trim());
		} catch (Exception e) {
			try {
				amt = (Integer)settings.value("uploadAmount", 0);
			} catch (Exception e1) {
				amt = 0;
			}
		}
		settings.endGroup();
		return amt;
    }
    public static void saveEvernoteUpdateCount(long amount) {
    	settings.beginGroup("UserAccounting");
		settings.setValue("updateCount", amount);
		settings.endGroup();
    }
    public static long getEvernoteUpdateCount() {
		long amt;
		settings.beginGroup("UserAccounting");
		try {
			String num = (String)settings.value("updateCount", new Long(0).toString());
			amt = new Long(num.trim());
		} catch (java.lang.ClassCastException e) {
			amt = 0;
		}
		settings.endGroup();
		return amt;
    }
    public static boolean isPremium() {
		int level;
		settings.beginGroup("User");
		try {
			String num = (String)settings.value("privilege", "1");
			level = new Integer(num.trim());
		} catch (java.lang.ClassCastException e) {
			try {
				level = (Integer)settings.value("privilege", 1);
			} catch (Exception e1) {
				level = 1;
			}
		}
		settings.endGroup();
		PrivilegeLevel userLevel = PrivilegeLevel.findByValue(level);
		if (userLevel == PrivilegeLevel.NORMAL)
			return false;
		return true;
		
   }
    public static long getUploadLimit() {
		settings.beginGroup("UserAccounting");
		long limit;
		try {
			String num = (String)settings.value("uploadLimit", new Long(0).toString());
			limit = new Long(num.trim());
		} catch (java.lang.ClassCastException e) {
			limit = 0;
		}
		settings.endGroup();
		return limit;
    }

    
    
    //****************************************************
    //****************************************************
    //** View settings.  Used to restore settings 
    //** when starting and to control how the program
    //** behaves.
    //****************************************************
    //****************************************************
    
    //* Get/Set if we should show a tray icon
    public static boolean showTrayIcon() {
		settings.beginGroup("General");
		try {
			String max = (String) settings.value("showTrayIcon", "false");
			settings.endGroup();
			if (!max.equalsIgnoreCase("true") || !QSystemTrayIcon.isSystemTrayAvailable())
				return false;
			else
				return true;   	
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("showTrayIcon", false);
			settings.endGroup();
			return value;
		}
    }
    public static void setShowTrayIcon(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("showTrayIcon", "true");
		else
			settings.setValue("showTrayIcon", "false");
		settings.endGroup();
    }
    
    // Get/Set window maximized when closed last
    public static boolean wasWindowMaximized() {
    	try {
			settings.beginGroup("General");
			String max = (String) settings.value("isMaximized", "true");
			settings.endGroup();
			if (!max.equalsIgnoreCase("true"))
				return false;
			return true;   	
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("isMaximized", true);
			settings.endGroup();
			return value;
		}
    }
    public static void saveWindowMaximized(boolean isMax) {
		settings.beginGroup("General");
		if (isMax)
			settings.setValue("isMaximized", "true");
		else
			settings.setValue("isMaximized", "false");
		settings.endGroup();
    }
    
    // Get/set currently viewed note Guid
    public static String getLastViewedNoteGuid() {
		settings.beginGroup("General");
		String guid = (String) settings.value("lastViewedNote", "");
		settings.endGroup();
		return guid;   	
    }
    public static void saveCurrentNoteGuid(String guid) {
		settings.beginGroup("General");
		if (guid != null)
			settings.setValue("lastViewedNote", guid);
		else
			settings.setValue("lastViewedNote", "");
		settings.endGroup();
    }
    
    // Get/Set the note column we are sorted on and the order
    public static void setSortColumn(int i) {
    	int view = Global.getListView();
		settings.beginGroup("General");
    	if (view == Global.View_List_Wide)
    		settings.setValue("sortColumn", i);
    	else
    		settings.setValue("sortColumn-Narrow", i);
		settings.endGroup();
    }
    public static int getSortColumn() {;
    String key;
	if (Global.getListView() == Global.View_List_Wide)
		key = "sortColumn";
	else
		key = "sortColumn-Narrow";

	settings.beginGroup("General");
	int order;	
	try {
		String val  = settings.value(key, new Integer(0)).toString();
		order = new Integer(val.trim());
	} catch (Exception e) {
		try {
			order = (Integer)settings.value(key, 0);
		} catch (Exception e1) {
		    order = 0;
		}
	}
	
	settings.endGroup();
	return order;
    }
    public static void setSortOrder(int i) {
    	int view = Global.getListView();
		settings.beginGroup("General");
    	if (view == Global.View_List_Wide)
    		settings.setValue("sortOrder", i);
    	else
    		settings.setValue("sortOrder-Narrow", i);
		settings.endGroup();
    }
    public static int getSortOrder() {
    	int view = Global.getListView();
		settings.beginGroup("General");
		String key;
    	if (view == Global.View_List_Wide)
    		key = "sortOrder";
   		else
   			key = "sortOrder-Narrow";

		int order;	
		try {
			String val  = settings.value(key, new Integer(0)).toString();
			order = new Integer(val.trim());
		} catch (Exception e) {
			try {
				order = (Integer)settings.value(key, 0);
			} catch (Exception e1) {
			    order = 0;
			}
		}
		
		settings.endGroup();
		return order;
    }
    
    // Should we automatically log in to Evernote when starting?
    public static boolean automaticLogin() {
    	try {
    		settings.beginGroup("General");
    		String text = (String)settings.value("automaticLogin", "false");
    		settings.endGroup();
    		if (text.equalsIgnoreCase("true"))
    			return true;
    		else
    			return false;		
    	} catch (java.lang.ClassCastException e) {
    		Boolean value = (Boolean) settings.value("automaticLogin", false);
    		settings.endGroup();
    		return value;
    	}
    }
    public static void setAutomaticLogin(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("automaticLogin", "true");
		else
			settings.setValue("automaticLogin", "false");
		settings.endGroup();
    }

    // Get/set the Evernote server Url.  
    public static void setServer(String server) {
		settings.beginGroup("General");
		settings.setValue("server", server);
		settings.endGroup();    	
    }
    public static String getServer() {
		settings.beginGroup("General");
		String text = (String)settings.value("server", "www.evernote.com");
		if (text.equals("www.evernote.com")) {
			userStoreUrl = "https://www.evernote.com/edam/user";
		    noteStoreUrlBase = "www.evernote.com/edam/note/";	
		} else {
			userStoreUrl = "https://sandbox.evernote.com/edam/user";
			noteStoreUrlBase = "sandbox.evernote.com/edam/note/";
		}
		settings.endGroup();
//		if (isPremium())
			noteStoreUrlBase = "https://" + noteStoreUrlBase;
//		else
//			noteStoreUrlBase = "http://" + noteStoreUrlBase;
		return text;
    }

    // Get/Set if we should disable uploads to Evernote
    public static boolean disableUploads() {
    	settings.beginGroup("General");
    	try {
    		String text = (String)settings.value("disableUploads", "false");
    		settings.endGroup();
    		if (text.equalsIgnoreCase("true"))
    			return true;
    		else
    			return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("disableUploads", false);
			settings.endGroup();
			return value;
		}
    }
    public static void setDisableUploads(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("disableUploads", "true");
		else
			settings.setValue("disableUploads", "false");
		settings.endGroup();
		disableUploads = val;
    }
 
    // Should we view PDF documents inline?
    public static boolean pdfPreview() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("pdfPreview", "true");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("pdfPreview", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setPdfPreview(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("pdfPreview", "true");
		else
			settings.setValue("pdfPreview", "false");
		settings.endGroup();
    }
    
    // When creating a new note, should it inherit tags that are currently selected?
    public static boolean newNoteWithSelectedTags() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("newNoteWithSelectedTags", "false");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("newNoteWithSelectedTags", false);
			settings.endGroup();
			return value;
		}
    }
    public static void setNewNoteWithSelectedTags(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("newNoteWithSelectedTags", "true");
		else
			settings.setValue("newNoteWithSelectedTags", "false");
		settings.endGroup();
    }
    
    // Minimum weight for text OCRed from Evernote. Anything below this
    // Won't be shown to the user when they search
    public static void setRecognitionWeight(int len) {
		settings.beginGroup("General");
		settings.setValue("recognitionWeight", len);
		settings.endGroup();    	
    }
    public static int getRecognitionWeight() {
		settings.beginGroup("General");
		Integer len;
		try {
			len = (Integer)settings.value("recognitionWeight", 30);
		} catch (Exception e) {
			len = 80;
		}
		settings.endGroup();
		return len;
    }
    
    // get/set current debug message level
    public static String getMessageLevel() {
		settings.beginGroup("Debug");
		String text = (String)settings.value("messageLevel", "Low");
		settings.endGroup();
		setMessageLevel(text);
		return text;
    }
    public static void setDateFormat(String format) {
		settings.beginGroup("General");
		settings.setValue("dateFormat", format);
		settings.endGroup();    	
    }
    
    // Get/Set user date/time formats
    public static String getDateFormat() {
		settings.beginGroup("General");
		String text = (String)settings.value("dateFormat", "MM/dd/yyyy");
		settings.endGroup();
		return text;
    }
    public static void setTimeFormat(String format) {
		settings.beginGroup("General");
		settings.setValue("timeFormat", format);
		settings.endGroup();    	
    }
    public static String getTimeFormat() {
		settings.beginGroup("General");
		String text = (String)settings.value("timeFormat", "HH:mm:ss");
		settings.endGroup();
		return text;
    }
    
    // How often should we sync with Evernote?
    public static String getSyncInterval() {
		settings.beginGroup("General");
		String text = (String)settings.value("syncInterval", "15 minutes");
		settings.endGroup();
		return text;    	
    }
    public static void setSyncInterval(String format) {
		settings.beginGroup("General");
		settings.setValue("syncInterval", format);
		settings.endGroup();    	
    }
    
    // Get/Set the width of columns and their position for the 
    // next start.
    public static void setColumnWidth(String col, int width) {
    	if (Global.getListView() == Global.View_List_Wide)
    		settings.beginGroup("ColumnWidths");
    	else 
    		settings.beginGroup("ColumnWidths-Narrow");
   		settings.setValue(col, width);
   		settings.endGroup();
   	}
    public static int getColumnWidth(String col) {
    	int view = Global.getListView();
    	if (view == Global.View_List_Wide)
    		settings.beginGroup("ColumnWidths");
    	else
    		settings.beginGroup("ColumnWidths-Narrow");
		Integer width;
		try {
			String val  = (String)settings.value(col, "0");
			width = new Integer(val.trim());
		} catch (Exception e) {
			try {
				width = (Integer)settings.value(col, 0);
			} catch (Exception e1) {
				width = 0;
			}
		}
		settings.endGroup();
		return width;
    }
    public static void setColumnPosition(String col, int width) {
    	if (Global.getListView() == Global.View_List_Wide)
    		settings.beginGroup("ColumnPosition");
    	else
    		settings.beginGroup("ColumnPosition-Narrow");
		settings.setValue(col, width);
		settings.endGroup();
    }
    public static int getColumnPosition(String col) {
    	if (Global.getListView() == Global.View_List_Wide)
    		settings.beginGroup("ColumnPosition");
    	else
    		settings.beginGroup("ColumnPosition-Narrow");
		Integer width;
		try {
			String val  = (String)settings.value(col, "-1");
			width = new Integer(val.trim());
		} catch (Exception e) {
			try {
				width = (Integer)settings.value(col, 0);
			} catch (Exception e1) {
				width = 0;
			}
		}
		settings.endGroup();
		return width;
    }
    
    // Ping the user when they try to delete or just do it.
    public static boolean verifyDelete() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("verifyDelete", "true");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("verifyDelete", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setVerifyDelete(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("verifyDelete", "true");
		else
			settings.setValue("verifyDelete", "false");
		settings.endGroup();
    }
    
    // Should it start minimized?
    public static boolean startMinimized() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("startMinimized", "false");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("startMinimized", false);
			settings.endGroup();
			return value;
		}
    }
    public static void setStartMinimized(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("startMinimized", "true");
		else
			settings.setValue("startMinimized", "false");
		settings.endGroup();
    }
    
    // Should we upload the content of any deleted notes
    public static boolean synchronizeDeletedContent() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("syncDeletedContent", "false");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("syncDeletedContent", false);
			settings.endGroup();
			return value;
		}
    }	
    public static void setSynchronizeDeletedContent(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("syncDeletedContent", "true");
		else
			settings.setValue("syncDeletedContent", "false");
		settings.endGroup();
    }
    
    // Is a section of the window visible?  Used to hide things people don't
    // want to see.
    public static boolean isWindowVisible(String window) {
		settings.beginGroup("WindowsVisible");
		try {
			String defaultValue = "true";
			if (window.equalsIgnoreCase("noteInformation"))
				defaultValue = "false";
			String text = (String)settings.value(window, defaultValue);
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
		else
			return false;		
		} catch (java.lang.ClassCastException e) {
			boolean defaultValue = true;
			if (window.equalsIgnoreCase("noteInformation"))
				defaultValue = false;
			Boolean value = (Boolean) settings.value("showTrayIcon", defaultValue);
			settings.endGroup();
			return value;
		}
    }
    public static void saveWindowVisible(String window, boolean val) {
		settings.beginGroup("WindowsVisible");
		if (val)
			settings.setValue(window, "true");
		else
			settings.setValue(window, "false");
		settings.endGroup();
    }
    
    // Is a list in the column in the note list visible?  
    public static boolean isColumnVisible(String window) {
    	String defaultValue = "true";
    	int view = Global.getListView();
    	if (Global.getListView() == Global.View_List_Wide)
    		settings.beginGroup("ColumnsVisible");
    	else
    		settings.beginGroup("ColumnsVisible-Narrow"); 
		if (window.equalsIgnoreCase("thumbnail") && view == Global.View_List_Wide)
			defaultValue = "false";
		if (window.equalsIgnoreCase("thumbnail"))
			defaultValue = "false";
		if (window.equalsIgnoreCase("Guid"))
			defaultValue = "false";
		try {
			String text = (String)settings.value(window, defaultValue);
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			boolean defBool = false;
			if (window.equalsIgnoreCase("true"))
				defBool = true;
			else
				defBool = false;
			Boolean value = (Boolean) settings.value(window, defBool);
			settings.endGroup();
			return value;
		}
    }
    public static void saveColumnVisible(String column, boolean val) {
    	if (Global.getListView() == Global.View_List_Wide)
    		settings.beginGroup("ColumnsVisible");
    	else
    		settings.beginGroup("ColumnsVisible-Narrow");    		
		if (val)
			settings.setValue(column, "true");
		else
			settings.setValue(column, "false");
		settings.endGroup();
    }
    
    // Is a particular editor button visible?
    public static boolean isEditorButtonVisible(String window) {
		settings.beginGroup("EditorButtonsVisible");
		try {
			String text = (String)settings.value(window, "true");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value(window, true);
			settings.endGroup();
			return value;
		}
    }
    public static void saveEditorButtonsVisible(String column, boolean val) {
		settings.beginGroup("EditorButtonsVisible");
		if (val)
			settings.setValue(column, "true");
		else
			settings.setValue(column, "false");
		settings.endGroup();
    }
    
    // Should the test fixes be enabled
    public static boolean enableCarriageReturnFix() {
    	try {
    		settings.beginGroup("Debug");
    		String text = (String)settings.value("enableCarriageReturnFix", "false");
    		settings.endGroup();
    		if (text.equalsIgnoreCase("true"))
    			return true;
    		else
    			return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("enableCarriageReturnFix", false);
			settings.endGroup();
			return value;
		}
    }
    public static void saveCarriageReturnFix(boolean val) {
		settings.beginGroup("Debug");
		if (val)
			settings.setValue("enableCarriageReturnFix", "true");
		else
			settings.setValue("enableCarriageReturnFix", "false");
		settings.endGroup();
    }
    public static boolean enableHtmlEntitiesFix() {
    	try {
    		settings.beginGroup("Debug");
    		String text = (String)settings.value("enableHtmlEntitiesFix", "false");
    		settings.endGroup();
    		if (text.equalsIgnoreCase("true"))
    			return true;
    		else
    			return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("enableHtmlEntitiesFix", false);
			settings.endGroup();
			return value;
		}
    }
    public static void saveHtmlEntitiesFix(boolean val) {
		settings.beginGroup("Debug");
		if (val)
			settings.setValue("enableHtmlEntitiesFix", "true");
		else
			settings.setValue("enableHtmlEntitiesFix", "false");
		settings.endGroup();
    }

//    public static void setIndexThreads(int val) {
//		settings.beginGroup("General");
//		settings.setValue("indexThreads", val);
//		settings.endGroup();
//   }
//    public static int getIndexThreads() {
//		settings.beginGroup("General");
//		Integer threads;
//		try {
//			String val  = (String)settings.value("indexThreads", "1");
//			threads = new Integer(val.trim());
//		} catch (Exception e) {
//			try {
//				threads = (Integer)settings.value("indexThreads", 1);
//			} catch (Exception e1) {
//				threads = 1;
//			}
//		}
//		settings.endGroup();
//		threads = 1;
//		return threads;
    
    // Get/Set text zoom factor
//   }
    public static void setZoomFactor(double val) {
		settings.beginGroup("General");
		settings.setValue("zoomFactor", val);
		settings.endGroup();
    }
    public static double getZoomFactor() {
		settings.beginGroup("General");
		Double threads;
		try {
			String val  = (String)settings.value("zoomFactor", "1.0");
			threads = new Double(val.trim());
		} catch (Exception e) {
			try {
				threads = (Double)settings.value("zoomFactor", 1.0);
			} catch (Exception e1) {
				threads = new Double(1);
			}
		}
		settings.endGroup();
		return threads;
    }
    public static void setTextSizeMultiplier(double val) {
		settings.beginGroup("General");
		settings.setValue("textMultiplier", val);
		settings.endGroup();
    }
    public static double getTextSizeMultiplier() {
		settings.beginGroup("General");
		Double threads;
		try {
			String val  = (String)settings.value("textMultiplier", "1");
			threads = new Double(val.trim());
		} catch (Exception e) {
			try {
				threads = (Double)settings.value("textMultiplier", 1);
			} catch (Exception e1) {
				threads = new Double(1);
			}
		}
		settings.endGroup();
		return threads;
    }
    
    
    // Should we mimic Evernote and restrict the notebooks selected?
    public static boolean getMimicEvernoteInterface() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("mimicEvernoteInterface", "true");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("mimicEvernoteInterface", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setMimicEvernoteInterface(boolean value) {
    	settings.beginGroup("General");
    	if (value)
    		settings.setValue("mimicEvernoteInterface", "true");
    	else
    		settings.setValue("mimicEvernoteInterface", "false"); 
    	settings.endGroup();
    }
    
    
    // Synchronize with Evernote when closing?
    public static boolean synchronizeOnClose() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("synchronizeOnClose", "false");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("synchronizeOnClose", false);
			settings.endGroup();
			return value;
		}
    }
    public static void setSynchronizeOnClose(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("synchronizeOnClose", "true");
		else
			settings.setValue("synchronizeOnClose", "false");
		settings.endGroup();
    }

    // Get/set the database version.  Not really used any more, but kept
    // for compatibility.
    public static void setDatabaseVersion(String version) {
		settings.beginGroup("General");
		settings.setValue("databaseVersion", version);
		settings.endGroup();
    }
    public static String getDatabaseVersion() {
		settings.beginGroup("General");
		String val  = (String)settings.value("databaseVersion", "0.70");
		settings.endGroup();
		return val;
    }

    // Get the URL (full path) of the main database
    public static String getDatabaseUrl() {
		settings.beginGroup("General");
		String val  = (String)settings.value("DatabaseURL", "");
		settings.endGroup();
		if (val.equals(""))
			val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.databaseName);
		return val;
    }
    
    // get the url (full path) of the searchable word database
    public static String getIndexDatabaseUrl() {
		settings.beginGroup("General");
		String val  = (String)settings.value("IndexDatabaseURL", "");
		settings.endGroup();
		if (val.equals(""))
			val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.indexDatabaseName);
		return val;
    }
    
    // Get the url (full path) of the attachment database
    public static String getResourceDatabaseUrl() {
		settings.beginGroup("General");
		String val  = (String)settings.value("ResourceDatabaseURL", "");
		settings.endGroup();
		if (val.equals(""))
			val = "jdbc:h2:"+Global.getFileManager().getDbDirPath(Global.resourceDatabaseName);
		return val;
    }
    
	// 操作履歴データベースのURL（フルパス）をゲット
	public static String getBehaviorDatabaseUrl() {
		settings.beginGroup("General");
		String val = (String) settings.value("BehaviorDatabaseURL", "");
		settings.endGroup();
		if (val.equals(""))
			val = "jdbc:h2:"
					+ Global.getFileManager().getDbDirPath(
							Global.behaviorDatabaseName);
		return val;
	}
	
    public static void setDatabaseUrl(String value) {
		settings.beginGroup("General");
		settings.setValue("DatabaseURL", value);
		settings.endGroup();
    }
    public static void setIndexDatabaseUrl(String value) {
		settings.beginGroup("General");
		settings.setValue("IndexDatabaseURL", value);
		settings.endGroup();
    }
    public static void setResourceDatabaseUrl(String value) {
		settings.beginGroup("General");
		settings.setValue("ResourceDatabaseURL", value);
		settings.endGroup();
    }
    
	public static void setBehaviorDatabaseUrl(String value) {
		settings.beginGroup("General");
		settings.setValue("BehaviorDatabaseURL", value);
		settings.endGroup();
	}
	
    public static String getDatabaseUserid() {
		settings.beginGroup("General");
		String val  = (String)settings.value("databaseUserid", "");
		settings.endGroup();
		return val;
    }
    public static String getDatabaseUserPassword() {
		settings.beginGroup("General");
		String val  = (String)settings.value("databaseUserPassword", "");
		settings.endGroup();
		return val;
    }
    
    // get/Set the style sheet and the palette to control the look & feel
    public static void setStyle(String style) {
		settings.beginGroup("General");
		settings.setValue("style", style);
		settings.endGroup();
    }
    public static String getStyle() {
		settings.beginGroup("General");
		String val  = (String)settings.value("style", "Cleanlooks");
		settings.endGroup();
		return val;
    }
    public static boolean useStandardPalette() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("standardPalette", "true");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("standardPalette", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setStandardPalette(boolean val) {
		settings.beginGroup("General");
		if (val)
			settings.setValue("standardPalette", "true");
		else
			settings.setValue("standardPalette", "false");
		settings.endGroup();
    }
    
    // Set the amount of time to wait between indexing
    // Get/Set interval when the index thread wakes up.
    public static void setIndexThreadSleepInterval(int sleep) {
		settings.beginGroup("General");
		settings.setValue("IndexThreadSleepInterval", sleep);
		settings.endGroup();
    }
    public static int getIndexThreadSleepInterval() {
		settings.beginGroup("General");
		Integer sleep;
		try {
			String val  = (String)settings.value("IndexThreadSleepInterval", "300");
			sleep = new Integer(val.trim());
		} catch (Exception e) {
			try {
				sleep = (Integer)settings.value("IndexThreadSleepInterval", 0);
			} catch (Exception e1) {
				sleep = 300;
			}
		}
		settings.endGroup();
		return sleep;
    }
    
    
    // Get/Set a window state for later restoring
    public static void saveState(String name, QByteArray state) {
    	int view = Global.getListView();
    	if (view == Global.View_List_Narrow)
    		name = name +"Narrow";
		settings.beginGroup("SaveState");
		settings.setValue(name, state);
		settings.endGroup();
    }
    
    public static QByteArray restoreState(String name) {
    	int view = Global.getListView();
    	if (view == Global.View_List_Narrow)
    		name = name +"Narrow";
		settings.beginGroup("SaveState");
		QByteArray state = (QByteArray)settings.value(name);
		settings.endGroup();
		return state;
    }
    public static void saveGeometry(String name, QByteArray state) {
    	int view = Global.getListView();
    	if (view == Global.View_List_Narrow)
    		settings.beginGroup("SaveGeometryNarrow");
    	else
    		settings.beginGroup("SaveGeometry");
		settings.setValue(name, state);
		settings.endGroup();
    }
    
    public static QByteArray restoreGeometry(String name) {
    	int view = Global.getListView();
    	if (view == Global.View_List_Narrow)
    		settings.beginGroup("SaveGeometryNarrow");
    	else
    		settings.beginGroup("SaveGeometry");
		QByteArray state = (QByteArray)settings.value(name);
		settings.endGroup();
		return state;
    }
    
    
    // Set how often to do an automatic save
    public static void setAutoSaveInterval(int interval) {
		settings.beginGroup("General");
		settings.setValue("autoSaveInterval", interval);
		settings.endGroup();
    }
    public static int getAutoSaveInterval() {
		settings.beginGroup("General");
		Integer value;
		try {
			String val  = (String)settings.value("autoSaveInterval", "5");
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("autoSaveInterval", 5);
			} catch (Exception e1) {
				value = 5;
			}
		}
		settings.endGroup();
		return value;
    }
     
    // Add an invalid attribute & element to the database so we don't bother parsing it in the future
    // These values we automatically remove from any note.
    // Add invalid attributes
    public static void addInvalidAttribute(String element, String attribute) {
    	
		List<String> attributes = invalidAttributes.get(element);
		if (attributes != null) {
			for (int i=0; i<attributes.size(); i++)
				if (attribute.equalsIgnoreCase(attributes.get(i))) {
					return;
			}
    	}
    	
    	ArrayList<String> attributeList;
    	if (!invalidAttributes.containsKey(element)) {
    		attributeList = new ArrayList<String>();
    		attributeList.add(attribute);
    		invalidAttributes.put(element, attributeList);
    	}
    	else {
    		attributeList = invalidAttributes.get(element);
    		attributeList.add(attribute);
    		invalidAttributes.put(element,attributeList);
    	}
    }
   
    // Add invalid attributes
    public static void addInvalidElement(String element) {
		for (int i=0; i<invalidElements.size(); i++) {
			if (element.equalsIgnoreCase(invalidElements.get(i)))
				return;
		}
    	invalidElements.add(element);
    }
    
    // Get/Set proxy information
    // Proxy settings
    public static String getProxyValue(String key) {
		settings.beginGroup("Proxy");
		String val  = (String)settings.value(key, "");
		settings.endGroup();
		return val;
    }
    public static void setProxyValue(String key, String value) {
		settings.beginGroup("Proxy");
		settings.setValue(key, value);
		settings.endGroup();
    }
    
    // Change a byte array to a hex string
    // Convert a byte array to a hex string
	public static String byteArrayToHexString(byte data[]) {
		StringBuffer buf = new StringBuffer();
	    for (byte element : data) {
	    	int halfbyte = (element >>> 4) & 0x0F;
	        int two_halfs = 0;
	        do {
		       	if ((0 <= halfbyte) && (halfbyte <= 9))
		               buf.append((char) ('0' + halfbyte));
		           else
		           	buf.append((char) ('a' + (halfbyte - 10)));
		       	halfbyte = element & 0x0F;
	        } while(two_halfs++ < 1);
	    }
	    return buf.toString();		
	}

    
	// Get/Set spelling settings
	public static boolean getSpellSetting(String value) {
		settings.beginGroup("Spell");
		String text = (String)settings.value(value, "");
		settings.endGroup();
		if (text.equalsIgnoreCase("true"))
			return true;
		if (text.equalsIgnoreCase("false"))
			return false;
		if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREDIGITWORDS))
			return true;
		if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREINTERNETADDRESSES))
			return true;
		if (value.equalsIgnoreCase(Configuration.SPELL_IGNOREUPPERCASE))
			return true;
		if (value.equalsIgnoreCase(Configuration.SPELL_IGNORESENTENCECAPITALIZATION))
			return true;
		return false;
    }
    public static void setSpellSetting(String setting, boolean val) {
		settings.beginGroup("Spell");
		if (val)
			settings.setValue(setting, "true");
		else
			settings.setValue(setting, "false");
		settings.endGroup();
    }
	
	// Get/Set how we should display tags (color them, hide unused, or do nothing)
	// What to do with inactive tags?
	public static String tagBehavior() {
		settings.beginGroup("General");
		String text = (String)settings.value("tagBehavior", "DoNothing");
		settings.endGroup();
		return text;
	}
	// What to do with inactive tags?
	public static void setTagBehavior(String value) {
		settings.beginGroup("General");
		settings.setValue("tagBehavior", value);
		settings.endGroup();
	}

    
	// Should the toolbar be visible?
	public static boolean isToolbarButtonVisible(String window, Boolean val) {
		settings.beginGroup("ToolbarButtonsVisible");
		try {
			String text = (String)settings.value(window, val.toString());
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;	
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value(window, val);
			settings.endGroup();
			return value;
		}
    }
    public static void saveToolbarButtonsVisible(String column, boolean val) {
		settings.beginGroup("ToolbarButtonsVisible");
		if (val)
			settings.setValue(column, "true");
		else
			settings.setValue(column, "false");
		settings.endGroup();
    }
	
    // Are thumbnails enabled?
    
    public static boolean enableThumbnails() {
		settings.beginGroup("Debug");
		try {
			String text = (String)settings.value("thumbnails", "true");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("thumbnails", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setEnableThumbnails(boolean val) {
		settings.beginGroup("Debug");
		if (val)
			settings.setValue("thumbnails", "true");
		else
			settings.setValue("thumbnails", "false");
		settings.endGroup();
    }
	
    // Trace used for performance tuning.  Not normally used in production.
	// Print date/time.  Used mainly for performance tracing
	public static void trace(boolean resetInterval) {
		String fmt = "MM/dd/yy HH:mm:ss.SSSSSS";
		String dateTimeFormat = new String(fmt);
		SimpleDateFormat simple = new SimpleDateFormat(dateTimeFormat);
		Calendar cal = Calendar.getInstance();
		if (intervalTraceTime == null) 
			intervalTraceTime = Calendar.getInstance();
		if (startTraceTime == null)
			startTraceTime = Calendar.getInstance();
		
		float interval = (cal.getTimeInMillis() - intervalTraceTime.getTimeInMillis());
		float total = (cal.getTimeInMillis() - startTraceTime.getTimeInMillis());
		
//		if (interval > 00.0) {
			StackTraceElement[] exceptions = Thread.currentThread().getStackTrace();
			System.out.println("------------------------------------------");

			System.out.println("Date/Time " +simple.format(cal.getTime()));
			System.out.format("Interval Time: %-10.6f%n", interval);
			System.out.format("Total Time: %-10.6f%n", total);
			for (int i=2; i<5 && i<exceptions.length; i++) {
				System.out.println(exceptions[i]);
			}
//		}
		if (resetInterval)
			intervalTraceTime = cal;
	}
	public static void traceReset() {
		intervalTraceTime = null;
		startTraceTime = null;
	}

    
	// Get the FileManager class to manage local files & directories
	public static FileManager getFileManager() {
        return fileManager;
    }
	
	// Should the note editor be disabled?
    public static boolean getDisableViewing() {
        return disableViewing;
    }

    //**********************
    //* Thumbnail zoom level
    //**********************
    public static int calculateThumbnailZoom(String content) {
    	int zoom = 1;
		if (content.indexOf("application/pdf") == -1) {
			if (content.indexOf("image/") == -1) {
				String text =  StringEscapeUtils.unescapeHtml4(content.replaceAll("\\<.*?\\>", ""));
				zoom = 2;
				if (text.length() < 500) 
					zoom = 2;
				if (text.length() < 250)
					zoom = 3;
				if (text.length() < 100)
					zoom = 4;
				if (text.length() < 50)
					zoom = 5;
				if (text.length() < 10)
					zoom = 6;
			}
		}
		return zoom;
    }
    
    //**********************
    //* List View settings 
    //**********************
    public static void setListView(int view) {
		settings.beginGroup("General");
		settings.setValue("listView", view);
		settings.endGroup();
    }
    public static int getListView() {
		settings.beginGroup("General");
		Integer value;
		try {
			String val  = (String)settings.value("listView", View_List_Wide);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("listView", View_List_Wide);
			} catch (Exception e1) {
				value = View_List_Wide;
			}
		}
		settings.endGroup();
		return value;
    }

    
    
    //*******************
    // Font Settings
    //*******************
    public static boolean overrideDefaultFont() {
		settings.beginGroup("Font");
		try {
			String text = (String)settings.value("overrideFont", "false");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;	
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("overrideFont", false);
			settings.endGroup();
			return value;
		}

    }
    
    //****************************************************
    // Get/Set the default font settings for a new note
    //****************************************************
    public static void setOverrideDefaultFont(boolean value) {
		settings.beginGroup("Font");
		settings.setValue("overrideFont", value);
		settings.endGroup();	
    }
    public static String getDefaultFont() {
		settings.beginGroup("Font");
		String val  = (String)settings.value("font", "");
		settings.endGroup();
		return val;
    }
    public static void setDefaultFont(String value) {
		settings.beginGroup("Font");
		settings.setValue("font", value);
		settings.endGroup();
    }
    public static String getDefaultFontSize() {
		settings.beginGroup("Font");
		String val  = (String)settings.value("fontSize", "");
		settings.endGroup();
		return val;
    }
    public static void setDefaultFontSize(String value) {
		settings.beginGroup("Font");
		settings.setValue("fontSize", value);
		settings.endGroup();
    }
    
    
    //*******************************************
    // Override the close & minimize instead.
    //*******************************************
    public static boolean minimizeOnClose() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("minimizeOnClose", "false");
			settings.endGroup();
			if (text.equalsIgnoreCase("true") && QSystemTrayIcon.isSystemTrayAvailable())
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("minimizeOnClose", false);
			settings.endGroup();
			return value;
		}
    }
    public static void setMinimizeOnClose(boolean value) {
		settings.beginGroup("General");
		settings.setValue("minimizeOnClose", value);
		settings.endGroup();	
    }

    //*********************************
    // Check version information
    //*********************************
    public static boolean checkVersionUpgrade() {
		settings.beginGroup("Upgrade");
		try {
			String text = (String)settings.value("checkForUpdates", "true");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("checkForUpdates", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setCheckVersionUpgrade(boolean value) {
		settings.beginGroup("Upgrade");
		settings.setValue("checkForUpdates", value);
		settings.endGroup();	
    }
    public static String getUpdatesAvailableUrl() {
		settings.beginGroup("Upgrade");
		String text = (String)settings.value("avialableUrl", "http://puma.cis.ibaraki.ac.jp/products/neighbornote/develop/versions.txt");
		settings.endGroup();	
		return text;
    }
    public static String getUpdateAnnounceUrl() {
		settings.beginGroup("Upgrade");
		String text = (String)settings.value("announceUrl", "http://puma.cis.ibaraki.ac.jp/products/neighbornote/develop/upgrade.html");
		settings.endGroup();	
		return text;
    }
    public static String getUpdateDownloadUrl() {
		settings.beginGroup("Upgrade");
		String text = (String)settings.value("downloadUrl", "http://puma.cis.ibaraki.ac.jp/products/neighbornote/download.html");
		settings.endGroup();	
		return text;
    }
    
    //*******************
    // Index settings
    //*******************
    // Set/Get if we should index the text of a note
    public static boolean indexNoteBody() {
		settings.beginGroup("Index");
		try {
			String value = (String)settings.value("indexNoteBody", "true");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("indexNoteBody", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setIndexNoteTitle(boolean value) {
		settings.beginGroup("Index");
		settings.setValue("indexNoteTitle", value);
		settings.endGroup();	
    }
    // Set/Get if we should index the title of a note
    public static boolean indexNoteTitle() {
		settings.beginGroup("Index");
		try {
			String value = (String)settings.value("indexNoteTitle", "true");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("indexNoteTitle", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setIndexNoteBody(boolean value) {
		settings.beginGroup("Index");
		settings.setValue("indexNoteBody", value);
		settings.endGroup();	
    }
    // Set/Get if we should index any attachments
    public static boolean indexAttachmentsLocally() {
		settings.beginGroup("Index");
		try {
			String value = (String)settings.value("indexAttachmentsLocally", "true");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("indexAttachmentsLocally", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setIndexImageRecognition(boolean value) {
		settings.beginGroup("Index");
		settings.setValue("indexImageRecognition", value);
		settings.endGroup();	
    }
    public static boolean indexImageRecognition() {
		settings.beginGroup("Index");
		try {
			String value = (String)settings.value("indexImageRecognition", "true");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("indexImageRecognition", true);
			settings.endGroup();
			return value;
		}
    }
    public static void setIndexAttachmentsLocally(boolean value) {
		settings.beginGroup("Index");
		settings.setValue("indexAttachmentsLocally", value);
		settings.endGroup();	
    }
    // Get/Set characters that shouldn't be removed from a word
//    public static String getSpecialIndexCharacters() {
//		settings.beginGroup("Index");
//		String text = (String)settings.value("specialCharacters", "");
//		settings.endGroup();	
//		return text;
//    }
//    public static void setSpecialIndexCharacters(String value) {
//		settings.beginGroup("Index");
//		settings.setValue("specialCharacters", value);
//		settings.endGroup();	
//		databaseCache = value;
//    }
    
    //*****************************************************************************
    // Control how tag selection behaves (should they be "and" or "or" selections
    //*****************************************************************************
    public static boolean anyTagSelectionMatch() {
		settings.beginGroup("General");
		try {
			String value = (String)settings.value("anyTagSelectionMatch", "false");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("anyTagSelectionMatch", false);
			settings.endGroup();
			return value;
		}
    }
    public static void setAnyTagSelectionMatch(boolean value) {
		settings.beginGroup("General");
		settings.setValue("anyTagSelectionMatch", value);
		settings.endGroup();	
    }

    //*****************************************************************************
    // Control if a user receives a warning when trying to create a note-to-note link
    // when the DB is not synchronized.
    //*****************************************************************************
    public static boolean bypassSynchronizationWarning() {
		settings.beginGroup("User");
		try {
			String value = (String)settings.value("bypassSynchronizationWarning", "false");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("bypassSynchronizationWarning", false);
			settings.endGroup();
			return value;
		}
    }
    public static void setBypassSynchronizationWarning(boolean value) {
		settings.beginGroup("User");
		settings.setValue("bypassSynchronizationWarning", value);
		settings.endGroup();	
    }

    
    //***********************
    //* Database cache size
    //***********************
    public static String getDatabaseCacheSize() {
		settings.beginGroup("Debug");
		String text = (String)settings.value("databaseCache", "16384");
		settings.endGroup();	
		return text;
    }
    public static void setDatabaseCache(String value) {
		settings.beginGroup("Debug");
		settings.setValue("databaseCache", value);
		settings.endGroup();	
		databaseCache = value;
    }

    
    // This is used to copy a class since Java's normal deep copy is wacked
    public static Object deepCopy(Object oldObj) 
    {
       ObjectOutputStream oos = null;
       ObjectInputStream ois = null;
       try
       {
          ByteArrayOutputStream bos = 
                new ByteArrayOutputStream(); // A
          oos = new ObjectOutputStream(bos); // B
          // serialize and pass the object
          oos.writeObject(oldObj);   // C
          oos.flush();               // D
          ByteArrayInputStream bin = 
                new ByteArrayInputStream(bos.toByteArray()); // E
          ois = new ObjectInputStream(bin);                  // F
          // return the new object
          return ois.readObject(); // G
       }
       catch(Exception e)
       {
          Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e);
       }
          try {
			oos.close();
	        ois.close();
		} catch (IOException e) {
			Global.logger.log(logger.LOW, "Exception in ObjectCloner = " + e);
			e.printStackTrace();
		}

		return null;
    }

    // If we should automatically select the children of any tag
    public static boolean includeTagChildren() {
		settings.beginGroup("General");
		try {
			String value = (String)settings.value("includeTagChildren", "false");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("includeTagChildren", false);
			settings.endGroup();
			return value;
		}

    }
    public static void setIncludeTagChildren(boolean value) {
		settings.beginGroup("General");
		settings.setValue("includeTagChildren", value);
		settings.endGroup();	
    }
    
    // If we should automatically wildcard searches
//    public static boolean automaticWildcardSearches() {
//		settings.beginGroup("General");
//		try {
//			String value = (String)settings.value("automaticWildcard", "false");
//			settings.endGroup();
//			if (value.equals("true"))
//				return true;
//			else
//				return false;
//		} catch (java.lang.ClassCastException e) {
//			Boolean value = (Boolean) settings.value("automaticWildcard", false);
//			settings.endGroup();
//			return value;
//		}
//
//    }
//    public static void setAutomaticWildcardSearches(boolean value) {
//		settings.beginGroup("General");
//		settings.setValue("automaticWildcard", value);
//		settings.endGroup();	
//    }

    // If we should automatically select the children of any tag
    public static boolean displayRightToLeft() {
		settings.beginGroup("General");
		try {
			String value = (String)settings.value("displayRightToLeft", "false");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("displayRightToLeft", false);
			settings.endGroup();
			return value;
		}

    }
    public static void setDisplayRightToLeft(boolean value) {
		settings.beginGroup("General");
		settings.setValue("displayRightToLeft", value);
		settings.endGroup();	
    }


    //***********************
    //* Startup Notebook
    //***********************
    public static String getStartupNotebook() {
		settings.beginGroup("General");
		String text = (String)settings.value("startupNotebook", "");
		settings.endGroup();	
		return text;
    }
    public static void setStartupNotebook(String value) {
		settings.beginGroup("General");
		settings.setValue("startupNotebook", value);
		settings.endGroup();	
		databaseCache = value;
    }
    
    // 複数ノート同時閲覧操作に対する重み付け
    public static void setBrowseWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("browseWeight", weight);
		settings.endGroup();    	
    }
    public static int getBrowseWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("browseWeight", 1);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("browseWeight", 1);
			} catch (Exception e1) {
				value = 1;
			}
		}
		settings.endGroup();
		return value;
    }
    
    // ノート内容のコピー＆ペースト操作に対する重み付け
    public static void setCopyPasteWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("copyPasteWeight", weight);
		settings.endGroup();    	
    }
    public static int getCopyPasteWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("copyPasteWeight", 3);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("copyPasteWeight", 3);
			} catch (Exception e1) {
				value = 3;
			}
		}
		settings.endGroup();
		return value;
    }
    
    // 新規ノート追加操作に対する重み付け
    public static void setAddNewNoteWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("addNewNoteWeight", weight);
		settings.endGroup();    	
    }
	public static int getAddNewNoteWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("addNewNoteWeight", 3);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("addNewNoteWeight", 3);
			} catch (Exception e1) {
				value = 1;
			}
		}
		settings.endGroup();
		return value;
	}
	
	// 連想ノートクリック操作に対する重み付け
    public static void setRensoItemClickWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("rensoItemClickWeight", weight);
		settings.endGroup();    	
    }
	public static int getRensoItemClickWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("rensoItemClickWeight", 10);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("rensoItemClickWeight", 10);
			} catch (Exception e1) {
				value = 10;
			}
		}
		settings.endGroup();
		return value;
	}
	
	// タグ付け操作に対する重み付け
    public static void setSameTagWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("sameTagWeight", weight);
		settings.endGroup();    	
    }
	public static int getSameTagWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("sameTagWeight", 2);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("sameTagWeight", 2);
			} catch (Exception e1) {
				value = 2;
			}
		}
		settings.endGroup();
		return value;
	}
	
	// ノートブック変更操作に対する重み付け
    public static void setSameNotebookWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("sameNotebookWeight", weight);
		settings.endGroup();    	
    }
	public static int getSameNotebookWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("sameNotebookWeight", 2);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("sameNotebookWeight", 2);
			} catch (Exception e1) {
				value = 2;
			}
		}
		settings.endGroup();
		return value;
	}
	
	// Evernote関連ノート機能統合に対する重み付け
	public static void setENRelatedNotesWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("enRelatedNotesWeight", weight);
		settings.endGroup();
	}
	public static int getENRelatedNotesWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val = (String)settings.value("enRelatedNotesWeight", 5);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("enRelatedNotesWeight", 5);
			} catch (Exception e1) {
				value = 10;
			}
		}
		settings.endGroup();
		return value;
	}
    
    //*******************
    // ノートのマージ・複製の関連ノートリストへの適用
    //*******************
    public static void setMergeRensoNote(boolean value) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("mergeRensoNoteList", value);
		settings.endGroup();	
    }
    
    public static boolean getMergeRensoNote() {
		settings.beginGroup("RensoNoteList");
		try {
			String value = (String)settings.value("mergeRensoNoteList", "true");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("mergeRensoNoteList", true);
			settings.endGroup();
			return value;
		}
    }
    
    public static void setDuplicateRensoNote(boolean value) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("duplicateRensoNoteList", value);
		settings.endGroup();	
    }
    
    public static boolean getDuplicateRensoNote() {
		settings.beginGroup("RensoNoteList");
		try {
			String value = (String)settings.value("duplicateRensoNoteList", "true");
			settings.endGroup();
			if (value.equals("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("duplicateRensoNoteList", true);
			settings.endGroup();
			return value;
		}
    }
    
    // 連想ノートリストからノートを除外するときに確認メッセージを表示するかどうか
    public static boolean verifyExclude() {
		settings.beginGroup("RensoNoteList");
		try {
			String text = (String)settings.value("verifyExclude", "true");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("verifyExclude", true);
			settings.endGroup();
			return value;
		}
    }
    
    public static void setVerifyExclude(boolean val) {
		settings.beginGroup("RensoNoteList");
		if (val)
			settings.setValue("verifyExclude", "true");
		else
			settings.setValue("verifyExclude", "false");
		settings.endGroup();
    }
    
	// 連想ノートリスト最大表示アイテム数
    public static void setRensoListItemMaximum(int maximum) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("rensoListMaximum", maximum);
		settings.endGroup();    	
    }
	public static int getRensoListItemMaximum() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("rensoListMaximum", 10);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("rensoListMaximum", 10);
			} catch (Exception e1) {
				value = 10;
			}
		}
		settings.endGroup();
		return value;
	}
	
	// タグを排除してプレーンテキストを抽出
	public static String extractPlainText(String sourceText) {
		String plainText = sourceText.replaceAll("<.+?>", "");	// タグを除去
		plainText = plainText.replaceAll("\\s{2,}", " ");		// 2個以上の空白文字を1文字の空白に変換
		String kaigyo = System.getProperty("line.separator");
		plainText = plainText.replaceAll(kaigyo, "");			// 改行を除去
//		plainText = plainText.replaceAll("&lt;.+?&gt;", "");	// &lt;で始まり&gt;で終わる文字列を除去
		
		// HTML特殊文字のサニタイジングを解除
		plainText = plainText.replaceAll("&#39;", "'");
		plainText = plainText.replaceAll("&quot;", "\"");
		plainText = plainText.replaceAll("&gt;", ">");
		plainText = plainText.replaceAll("&lt;", "<");
		plainText = plainText.replaceAll("&amp;", "&");
		
		plainText = plainText.replaceAll("&.+?;", "");			// その他HTML特殊文字があれば除去
		
		return plainText;
	}
	
	// 全文検索機能の対象となるテーブルとカラムを再構築
	public static boolean rebuildFullTextNoteTarget(DatabaseConnection dbConn) {
		NSqlQuery nQuery = new NSqlQuery(dbConn.getConnection());
		StringBuilder noteTableTarget = new StringBuilder();
		boolean success = true;
		
		if (Global.indexNoteBody()) {
			noteTableTarget.append("CONTENTTEXT");
		}
		if (Global.indexNoteTitle()) {
			if (noteTableTarget.length() > 0) {
				noteTableTarget.append(", ");
			}
			noteTableTarget.append("TITLE");
		}
		
		if (noteTableTarget.length() > 0) {
			nQuery.prepare("CALL FTL_CREATE_INDEX('PUBLIC', 'NOTE', :column);");
			nQuery.bindValue(":column", noteTableTarget.toString());
			if (!nQuery.exec()) {
				success = false;
			}
		}
		
		return success;
	}
	
	public static boolean rebuildFullTextResourceTarget(DatabaseConnection dbConn) {
		NSqlQuery rQuery = new NSqlQuery(dbConn.getResourceConnection());
		StringBuilder resourceTableTarget = new StringBuilder();
		boolean success = true;
		
		if (Global.indexAttachmentsLocally()) {
			resourceTableTarget.append("RESOURCETEXT");
		}
		
		if (resourceTableTarget.length() > 0) {
			rQuery.prepare("CALL FTL_CREATE_INDEX('PUBLIC', 'NOTERESOURCES', :column);");
			rQuery.bindValue(":column", resourceTableTarget.toString());
			if (!rQuery.exec()) {
				success = false;
			}
		}
		
		return success;
	}
	
    // 操作ログを取らないモードのボタン状態
    public static boolean isHaltLogButton() {
		settings.beginGroup("RensoNoteList");
		try {
			String text = (String)settings.value("haltOperationLog", "false");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("haltOperationLog", true);
			settings.endGroup();
			return value;
		}
    }
    public static void saveHaltLogButton(boolean val) {
		settings.beginGroup("RensoNoteList");
		if (val)
			settings.setValue("haltOperationLog", "true");
		else
			settings.setValue("haltOperationLog", "false");
		settings.endGroup();
    }
    
    // 連想ノートリストの重み付けモードの状態
    public static String rensoWeightingSelect() {
		settings.beginGroup("RensoNoteList");
		String text = (String)settings.value("rensoWeightingSelect", "Standard");
		settings.endGroup();
		return text;
    }
    public static void saveRensoWeightingSelect(String val) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("rensoWeightingSelect", val);
		settings.endGroup();
    }
    
    // ordinal から指定した Enum の要素に変換する汎用関数
	public static <E extends Enum<E>> E fromOrdinal(Class<E> enumClass, int ordinal) {
	    E[] enumArray = enumClass.getEnumConstants();
	    return enumArray[ordinal];
	}
	
	// 連想ノートリスト重み付けモード：カスタムの設定値（同時閲覧）
    public static int customBrowseWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("customBrowseWeight", 1);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("customBrowseWeight", 1);
			} catch (Exception e1) {
				value = 1;
			}
		}
		settings.endGroup();
		return value;
    }
	public static void saveCustomBrowseWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("customBrowseWeight", weight);
		settings.endGroup();
	}
	// 連想ノートリスト重み付けモード：カスタムの設定値（コピー＆ペースト）
    public static int customCopyPasteWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("customCopyPasteWeight", 3);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("customCopyPasteWeight", 3);
			} catch (Exception e1) {
				value = 3;
			}
		}
		settings.endGroup();
		return value;
    }
	public static void saveCustomCopyPasteWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("customCopyPasteWeight", weight);
		settings.endGroup();
	}
	// 連想ノートリスト重み付けモード：カスタムの設定値（新規ノート追加）
    public static int customAddNewNoteWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("customAddNewNoteWeight", 3);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("customAddNewNoteWeight", 3);
			} catch (Exception e1) {
				value = 3;
			}
		}
		settings.endGroup();
		return value;
    }
	public static void saveCustomAddNewNoteWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("customAddNewNoteWeight", weight);
		settings.endGroup();
	}
	// 連想ノートリスト重み付けモード：カスタムの設定値（連想ノートクリック）
    public static int customRensoItemClickWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("customRensoItemClickWeight", 10);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("customRensoItemClickWeight", 10);
			} catch (Exception e1) {
				value = 10;
			}
		}
		settings.endGroup();
		return value;
    }
	public static void saveCustomRensoItemClickWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("customRensoItemClickWeight", weight);
		settings.endGroup();
	}
	// 連想ノートリスト重み付けモード：カスタムの設定値（同じタグ）
    public static int customSameTagWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("customSameTagWeight", 2);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("customSameTagWeight", 2);
			} catch (Exception e1) {
				value = 2;
			}
		}
		settings.endGroup();
		return value;
    }
	public static void saveCustomSameTagWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("customSameTagWeight", weight);
		settings.endGroup();
	}
	// 連想ノートリスト重み付けモード：カスタムの設定値（同じノートブック）
    public static int customSameNotebookWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("customSameNotebookWeight", 2);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("customSameNotebookWeight", 2);
			} catch (Exception e1) {
				value = 2;
			}
		}
		settings.endGroup();
		return value;
    }
	public static void saveCustomSameNotebookWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("customSameNotebookWeight", weight);
		settings.endGroup();
	}
	// 連想ノートリスト重み付けモード：カスタムの設定値(Evernote関連ノート）
    public static int customENRelatedNotesWeight() {
		settings.beginGroup("RensoNoteList");
		Integer value;
		try {
			String val  = (String)settings.value("customENRelatedNotesWeight", 5);
			value = new Integer(val.trim());
		} catch (Exception e) {
			try {
				value = (Integer)settings.value("customENRelatedNotesWeight", 5);
			} catch (Exception e1) {
				value = 5;
			}
		}
		settings.endGroup();
		return value;
    }
	public static void saveCustomENRelatedNotesWeight(int weight) {
		settings.beginGroup("RensoNoteList");
		settings.setValue("customENRelatedNotesWeight", weight);
		settings.endGroup();
	}

	// ツールバーの「新規」ボタンを押した時、新規ノートをタブで開くかどうか
	public static boolean toolBarNewAction() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("toolBarNewAction", "true");
			settings.endGroup();
			if (text.equalsIgnoreCase("true"))
				return true;
			else
				return false;
		} catch (java.lang.ClassCastException e) {
			Boolean value = (Boolean) settings.value("toolBarNewAction", true);
			settings.endGroup();
			return value;
		}
	}
	public static void setToolBarNewAction(boolean value) {
		settings.beginGroup("General");
		settings.setValue("toolBarNewAction", value);
		settings.endGroup();	
	}
	
	// 全文検索の範囲
	public static SearchTarget searchTarget() {
		settings.beginGroup("General");
		try {
			String text = (String)settings.value("searchTarget", "0");
			settings.endGroup();
			int ordinal = Integer.parseInt(text);
			SearchTarget target = fromOrdinal(SearchTarget.class, ordinal);
			return target;
		} catch (java.lang.ClassCastException e) {
			int value = (Integer) settings.value("searchTarget", 0);
			settings.endGroup();;
			SearchTarget target = fromOrdinal(SearchTarget.class, value);
			return target;
		}
	}
	
	public static void setSearchTarget(SearchTarget target) {
		settings.beginGroup("General");
		settings.setValue("searchTarget", target.ordinal());
		settings.endGroup();
	}
}

