//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation and others.
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// which accompanies this distribution, and is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// Contributors:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.library.services;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.persistence.MultiFileResourceSetImpl;
import org.eclipse.epf.uma.MethodElement;


public class FileNameCache {
	
	private static FileNameCache instance = new FileNameCache();
	private Map aMap = new HashMap();
	private Set aSet = new HashSet();
	private Map gMap = new HashMap();

	/**
	 * Returns the shared instance.
	 */
	public static FileNameCache getInstance() {
		return instance;
	}

	/**
	 * Private constructor to prevent this class from being instantiated.
	 */
	private FileNameCache() {
	}
	
	public void clear() {
		aMap.clear();
		aSet.clear();
		gMap.clear();
	}
	
	/**
	 * get the file name with the given prefix and extension
	 * @param element MethodElement
	 * @param namePrefix String prefix for the name
	 * @param nameSuffix String suffix for the name
	 * @param ext String file extension, for example, ".html"
	 * @return String
	 */	 
	public String getFileName(MethodElement element, String namePrefix,
			String nameSuffix, String ext) {
		
		String existingElementName = null;
		StringBuffer buffer = new StringBuffer();
		if (namePrefix != null) {
			buffer.append(namePrefix);
		}
		
		if (element.getName() == "")
			return "0" + ext; //$NON-NLS-1$
		
		if (!gMap.isEmpty()) {
			existingElementName =  (String) gMap.get(element.getGuid());
		}
		// Browsing: Browsing CP with special chars failed with
		// blank pages and Script Error need to make a valid file name
		buffer.append((existingElementName != null) ? existingElementName : StrUtil.removeSpecialCharacters(element.getName()));
		if (nameSuffix != null) {
			buffer.append(nameSuffix);
		}

		if (ext != null) {
			if (ext.indexOf(".") < 0) //$NON-NLS-1$
			{
				ext = "." + ext; //$NON-NLS-1$
			}
			buffer.append(ext);
		}

		ElementFile a = new ElementFile(element.getGuid(), buffer.toString());
		
		if (a != null && aSet.add(a)) {
			int extDot = a.getFileName().lastIndexOf(".");
			aMap.put((extDot < 0) ? a.getFileName() : a.getFileName().substring(0, extDot), element.getGuid());			 
			gMap.put(element.getGuid(), (extDot < 0) ? a.getFileName() : a.getFileName().substring(0, extDot));
		}

		return a.getFileName(); 
	}
	
	public String getFileName(MethodElement element) {
		
		StringBuffer buffer = new StringBuffer(StrUtil.removeSpecialCharacters(element.getName()));
		
		ElementFile a = new ElementFile(element.getGuid(), buffer.toString());
		
		if (a != null && aSet.add(a)) {
			aMap.put(a.getFileName(), element.getGuid());
//			gMap.put(element.getGuid(), a.getFileName());
		}

		return a.getFileName(); 
	}
	
	public String getFileName(String guid) {
		
		if (!gMap.isEmpty()) {
			return (String) gMap.get(guid);
		}
		return null; 
	}

	/**
	 * get the guid from the file name, assuming the file name is generated from an element, 
	 * return null if not found.
	 * @param fileName String
	 * @return String
	 */
	public String getGuidFromFileName(String fileName) {
		if (fileName == null) {
			return null;
		}			
		
		String guid = null;
		
		int idx = fileName.lastIndexOf("/");
		int lastIdx = fileName.lastIndexOf(".");

		if (idx > -1) {
			guid = (String) aMap.get((lastIdx > -1 && idx < lastIdx) ? 
					fileName.substring(idx+1, lastIdx) : (idx < fileName.length()) ? 
							fileName.substring(idx+1) : null);
		} else {
			guid = (String) aMap.get((lastIdx > -1) ? fileName.substring(0, lastIdx) : fileName);
		}
		if (guid == null)	return null;		
	
		// turn off error reporting and see if guid exists in library
		boolean oldReport_Error = MultiFileResourceSetImpl.REPORT_ERROR;
		MultiFileResourceSetImpl.REPORT_ERROR = false;
		MethodElement e = LibraryService.getInstance().getCurrentLibraryManager()
				.getMethodElement(guid);
		MultiFileResourceSetImpl.REPORT_ERROR = oldReport_Error;
		if (e == null)
			return null;

		return guid;
	}
}
