/**
 *  RELOAD TOOLS
 *
 *  Copyright (c) 2003 Oleg Liber, Bill Olivier, Phillip Beauvoir
 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy
 *  of this software and associated documentation files (the "Software"), to deal
 *  in the Software without restriction, including without limitation the rights
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *  copies of the Software, and to permit persons to whom the Software is
 *  furnished to do so, subject to the following conditions:
 *
 *  The above copyright notice and this permission notice shall be included in
 *  all copies or substantial portions of the Software.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 *  Project Management Contact:
 *
 *  Oleg Liber
 *  Bolton Institute of Higher Education
 *  Deane Road
 *  Bolton BL3 5AB
 *  UK
 *
 *  e-mail:   o.liber@bolton.ac.uk
 *
 *
 *  Technical Contact:
 *
 *  Phillip Beauvoir
 *  e-mail:   p.beauvoir@bolton.ac.uk
 *
 *  Web:      http://www.reload.ac.uk
 *
 */

package uk.ac.reload.editor.prefs;

import java.io.File;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.Vector;

import uk.ac.reload.diva.prefs.UserPrefs;
import uk.ac.reload.editor.EditorHandler;
import uk.ac.reload.editor.properties.EditorProperties;
import uk.ac.reload.editor.upload.repository.cesga.RepositoryConstantsCesga;
import uk.ac.reload.editor.upload.repository.osami.RepositoryConstantsOsami;
import uk.ac.reload.editor.upload.repository.suma.RepositoryConstantsSuma;

/**
 * The User Prefs file.  Implementers will have to fulfil the abstract methods
 *
 * @author Phillip Beauvoir
 * @version $Id: EditorPrefs.java,v 1.6 2004/11/12 19:08:09 phillipus Exp $
 */
public class EditorPrefs extends UserPrefs {

    /**
     * The Prefs Filename
     */
    public static final String USER_PREFS_FILENAME = "reload_prefs.xml";

    /**
     * The Prefs root element name
     */
    public static final String USER_PREFS_ELEMENTNAME = "reload_prefs";

    /**
     * Our singleton User Prefs
     */
    private static EditorPrefs _userPrefs = new EditorPrefs();

    // ======================== GENERAL KEYS ===================================

    // The default Open folder
    public static final String GENERAL_PREFS_DEFAULT_FOLDER = "default_folder";

    // Look and Feel
    public static final String GENERAL_PREFS_LF = "look_and_feel";
    
    // Recent File History
    public static final String GENERAL_HISTORY = "history";
    
    // Check prefs - starts up a little faster if set to false,
    // but more error-prone if you fool with the reload prefs folder
    // default is true
    public static final String GENERAL_CHECK_SUPPORT = "check_support";

    
    // ============================= CP KEYS ===================================

    // Hide Resources Element
    public static final String CP_HIDE_RESOURCES = "hide_resources";

    // Hide SCORMS Elements
    public static final String CP_HIDE_SCORM = "hide_scorm";

    // Only zip referenced files - doesn't work
    //public static final String CP_ZIP_REFERENCED_FILES = "zip_referenced";
    
    // Default CP Profile
    public static final String CP_DEFAULT_PROFILE = "default_cp_profile";

    /**
     * Default CP Version for CP
     */
    public static final String CP_DEFAULT_CP_VERSION = "default_cp_version";

    /**
     * Default MD Version for CP
     */
    public static final String CP_DEFAULT_MD_VERSION = "default_cp_md_version";

    /**
     * Default SCORM Profile
     */
    public static final String SCORM_DEFAULT_PROFILE = "default_scorm_profile";

    /**
     * Default Adaptive SCORM Profile
     */
    public static final String SCORMA_DEFAULT_PROFILE = "default_adaptive_scorm_profile";

    /**
     * Default CP Version for SCORM
     */
    public static final String SCORM_DEFAULT_CP_VERSION = "default_scorm_cp_version";

    /**
     * Default MD Version for SCORM
     */
    public static final String SCORM_DEFAULT_MD_VERSION = "default_scorm_md_version";
    

    // ============================= MD KEYS ===================================

    /**
     * Default MD Profile
     */
    public static final String MD_DEFAULT_PROFILE = "default_md_profile";

    /**
     * Default MD Version
     */
    public static final String MD_DEFAULT_VERSION = "default_md_version";

    /**
     * Do ask again next time
     */
    public static final String MD_DO_ASK_VERSION = "do_ask_md_version";
    
    // ======================== SCOs POOL KEYS ===================================

    // The default Open folder
    public static final String POOL_PREFS_DEFAULT_FOLDER = "default_pool_folder";
    // Search in the subfolders
    public static final String POOL_EXTENSIVE_SEARCH = "extensive_search";
    // Wheter if includes metadata .xml file when importing SCOs
    public static final String POOL_INCLUDE_METADATA = "include_metadata";

  
    // ========================== APPEARANCE KEYS =============================
    
    // (Look and Feel has been put under General)
    
    /**
     * Language
     */
    public static final String LANGUAGE = "language";
   
	/**
	 * Default Language Setting
	 */
    public static final String DEFAULT_LANGUAGE = "(default)";
	
    //TODO nombres de variables asociados al Repository Client

    // ======================== REPOSITORY CLIENT KEYS ========================

    /**
     * Default Repository
     */
    public static final String DEFAULT_REPOSITORY = "default_repository";

    //OSAMI

    /**
     * Repository Services Address for OSAmI
     */
    public static final String REPOSITORY_SERVICE_ADDRESS_OSAMI = "repository_service_address_osami";

    /**
     * Repository Service Name for OSAmI
     */
    public static final String SERVICE_NAME_OSAMI = "service_name_osami";

    /**
     * Repository Service Namespace for OSAmI
     */
    public static final String NAMESPACE_OSAMI = "namespace_osami";

    //SUMA

    /**
     * Repository Services Address for SUMA
     */
    public static final String REPOSITORY_SERVICE_ADDRESS_SUMA = "repository_service_address_suma";

    /**
     * Repository Service Name for SUMA
     */
    public static final String SERVICE_NAME_SUMA = "service_name_suma";

    /**
     * Repository Service Namespace for SUMA
     */
    public static final String NAMESPACE_SUMA = "namespace_suma";
    
    //CESGA
    
    /**
     * Repository Services Address for CESGA
     */
    public static final String REPOSITORY_SERVICE_ADDRESS_CESGA= "repository_service_address_cesga";

    /**
     * Repository Service Name for CESGA
     */
    public static final String SERVICE_NAME_CESGA = "service_name_cesga";

    /**
     * Repository Service Namespace for CESGA
     */
    public static final String NAMESPACE_CESGA = "namespace_cesga";

    //  =======================================================================

    /**
     * @return the Singleton
     */
    public static EditorPrefs getInstance() {
        return _userPrefs;
    }

    /**
     * Set some default values
     */
    protected void setDefaultValues() {
        // Hide Resource Nodes
        String value = getValue(CP_HIDE_RESOURCES);
        if(value == null) {
            putBooleanValue(CP_HIDE_RESOURCES, false);
        }

        // Hide SCORM Nodes
        value = getValue(CP_HIDE_SCORM);
        if(value == null) {
            putBooleanValue(CP_HIDE_SCORM, true);
        }

        // Only zip referenced files
        //value = getValue(CP_ZIP_REFERENCED_FILES);
        //if(value == null) {
        //    putBooleanValue(CP_ZIP_REFERENCED_FILES, false);
        //}
        
        // Check prefs at startup
        value = getValue(GENERAL_CHECK_SUPPORT);
        if(value == null) {
            putBooleanValue(GENERAL_CHECK_SUPPORT, true);
        }
        
        // Ideally we need to have all Preferences pluggable so that a registered EditorHandler
        // Take care of specific Preferences

        // Prompt for MD Version
        value = getValue(MD_DO_ASK_VERSION);
        if(value == null) {
            putBooleanValue(MD_DO_ASK_VERSION, true);
        }
        
        // Default MD Version
        value = getValue(MD_DEFAULT_VERSION);
        if(value == null) {
            putValue(MD_DEFAULT_VERSION, EditorHandler.MD_EDITORHANDLER.getDefaultVersion());
        }

        // Default CP Version
        value = getValue(CP_DEFAULT_CP_VERSION);
        if(value == null) {
            putValue(CP_DEFAULT_CP_VERSION, EditorHandler.CP_EDITORHANDLER.getDefaultVersion());
        }

        // Default CP/MD Version
        value = getValue(CP_DEFAULT_MD_VERSION);
        if(value == null) {
            putValue(CP_DEFAULT_MD_VERSION, EditorHandler.MD_EDITORHANDLER.getDefaultVersion());
        }

        // Default SCORM CP Version
        value = getValue(SCORM_DEFAULT_CP_VERSION);
        if(value == null) {
            putValue(SCORM_DEFAULT_CP_VERSION, EditorHandler.SCORM12_EDITORHANDLER.getDefaultVersion());
        }

        // Default SCORM/MD Version
        value = getValue(SCORM_DEFAULT_MD_VERSION);
        if(value == null) {
            putValue(SCORM_DEFAULT_MD_VERSION, EditorHandler.SCORM12_EDITORHANDLER.getDefaultMDVersion());
        }
        
        // Default Language
        value = getValue(LANGUAGE);
        if(value == null) {
            putValue(LANGUAGE, DEFAULT_LANGUAGE);
        }

        //TODO valores asociados al Repository Client

        value = getValue(DEFAULT_REPOSITORY);
        if (value == null) {
            putValue(DEFAULT_REPOSITORY, "Osami");
        }

        //OSAMI

        //Repository Service Address OSAmI
        value = getValue(REPOSITORY_SERVICE_ADDRESS_OSAMI);
        if (value == null) {
            putValue(REPOSITORY_SERVICE_ADDRESS_OSAMI, RepositoryConstantsOsami.RepositoryService_address);
        } else {
            RepositoryConstantsOsami.RepositoryService_address = value;
        }

        //Repository Service Name OSAmI
        value = getValue(SERVICE_NAME_OSAMI);
        if (value == null) {
            putValue(SERVICE_NAME_OSAMI, RepositoryConstantsOsami.ServiceName);
        } else {
            RepositoryConstantsOsami.ServiceName = value;
        }

        //Repository Service Namespace OSAmI
        value = getValue(NAMESPACE_OSAMI);
        if (value == null) {
            putValue(NAMESPACE_OSAMI, RepositoryConstantsOsami.namespace);
        } else {
            RepositoryConstantsOsami.namespace = value;
        }


        //SUMA

        //Repository Service Address SUMA
        value = getValue(REPOSITORY_SERVICE_ADDRESS_SUMA);
        if (value == null) {
            putValue(REPOSITORY_SERVICE_ADDRESS_SUMA, RepositoryConstantsSuma.RepositoryService_address);
        } else {
            RepositoryConstantsSuma.RepositoryService_address = value;
        }

        //Repository Service Name SUMA
        value = getValue(SERVICE_NAME_SUMA);
        if (value == null) {
            putValue(SERVICE_NAME_SUMA, RepositoryConstantsSuma.ServiceName);
        } else {
            RepositoryConstantsSuma.ServiceName = value;
        }

        //Repository Service Namespace SUMA
        value = getValue(NAMESPACE_SUMA);
        if (value == null) {
            putValue(NAMESPACE_SUMA, RepositoryConstantsSuma.namespace);
        } else {
            RepositoryConstantsSuma.namespace = value;
        }


        //CESGA

        //Repository Service Address CESGA
        value = getValue(REPOSITORY_SERVICE_ADDRESS_CESGA);
        if (value == null) {
            putValue(REPOSITORY_SERVICE_ADDRESS_CESGA, RepositoryConstantsCesga.RepositoryService_address);
        } else {
            RepositoryConstantsCesga.RepositoryService_address = value;
        }

        //Repository Service Name CESGA
        value = getValue(SERVICE_NAME_CESGA);
        if (value == null) {
            putValue(SERVICE_NAME_CESGA, RepositoryConstantsCesga.ServiceName);
        } else {
            RepositoryConstantsCesga.ServiceName = value;
        }

        //Repository Service Namespace CESGA
        value = getValue(NAMESPACE_CESGA);
        if (value == null) {
            putValue(NAMESPACE_CESGA, RepositoryConstantsCesga.namespace);
        } else {
            RepositoryConstantsCesga.namespace = value;
        }

    }

    /**
     * @return the Preferences File
     */
    public File getPrefsFile() {
        return new File(getPrefsFolder(), USER_PREFS_FILENAME);
    }

    /**
     * Location of Editor Prefs folder
     * @return the Preferences Folder
     */
    public File getPrefsFolder() {
    	File reloadHome = EditorProperties.getFileProperty("prefs.dir");
        if(reloadHome != null) reloadHome.mkdirs();
        return reloadHome;
    }

    /**
     * @return the root Element name
     */
    public String getElementRootName() {
        return USER_PREFS_ELEMENTNAME;
    }

    /**
     * @return the Recent File History as an array of Strings
     */
    public String[] getFileHistory() {
        Vector v = new Vector();

        String val = getValue(GENERAL_HISTORY);

        if(val != null) {
            StringTokenizer t = new StringTokenizer(val, ";");
            while(t.hasMoreElements()) {
                String path = t.nextToken();
                v.addElement(path);
            }
        }

        String[] vals = new String[v.size()];
        v.copyInto(vals);
        return vals;
    }

    /**
     * Add a new entry to the Recent File list, or if already present move to
     * front of list, and limit to 8 entries if need be
     */
    public void addFileToHistory(File file) {
        String val = file.getPath();
        int count = 1;

        String[] history = getFileHistory();

        for(int i = 0; i < history.length && count < 8; i++) {
            if(!history[i].equalsIgnoreCase(file.getPath())) {
                val += ";" + history[i];
                count++;
            }
        }

        putValue(GENERAL_HISTORY, val);
    }
    
	
	/**
	 * Set the System Default Locale from the Prefs
	 */
    public void setDefaultLocale() {
		String languageCode = getValue(LANGUAGE);
		if(languageCode != null && !languageCode.equals(DEFAULT_LANGUAGE)) {
		    setDefaultLocale(languageCode);
		}
    }
    
    /**
	 * Set the System Default Locale
	 * @param languageCode A language code such as "en", "en_GB", "fr", "fr_CA", "es_ES_Traditional_WIN"
	 */
    public void setDefaultLocale(String languageCode) {
		if(languageCode != null) {
		    StringTokenizer t = new StringTokenizer(languageCode, "_");
		    int tokens = t.countTokens();

		    if(tokens == 1) {
		        Locale.setDefault(new Locale(languageCode));
		    }
		    else if(tokens == 2) {
		        String language = t.nextToken();
		        String country = t.nextToken();
		        Locale.setDefault(new Locale(language, country));
		    }
		    else if(tokens >= 3) {
		        String language = t.nextToken();
		        String country = t.nextToken();
		        String variant = t.nextToken();
		        while(t.hasMoreTokens()) {
		            variant += "_" + t.nextToken();
		        }
		        Locale.setDefault(new Locale(language, country, variant));
		    }
		}
	}
}
