/*
 * Created on 2004-09-03
 *
 * Part of the Symbian development plug-in for Eclipse
 * Copyright (C) Mikołaj Zalewski, 2004
 */
package pl.zalewski.mikolaj.symbdev.skins;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.TreeMap;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.osgi.framework.Bundle;

import pl.zalewski.mikolaj.symbdev.SymbdevPlugin;

/**
 * Manages the skins applied to the emulators
 * 
 * @author mikolaj
 */
public class SkinManager {

    public static final String EXTENSION_POINT=SymbdevPlugin.getUniqueIdentifier()+".EmulatorSkin"; 
    public static final String PATH_ATTRIBUTE="path"; 
    public static final String ID_ATTRIBUTE="id"; 
    
    /**
     * Default contructor
     */
    protected SkinManager() {
        super();
        fSkins=new TreeMap();
        
      	IExtensionRegistry registry = Platform.getExtensionRegistry();
        IExtensionPoint extensionPoint =
          registry.getExtensionPoint(EXTENSION_POINT);
        IConfigurationElement[] members =
          extensionPoint.getConfigurationElements();
        
        for (int m = 0; m < members.length; m++) {
        	IConfigurationElement member=members[m];
            String pluginLabel=member.getDeclaringExtension().getNamespace();
            String path=member.getAttribute(PATH_ATTRIBUTE);            
            String id=member.getAttribute(ID_ATTRIBUTE);            
            
            if (path==null || id==null)
            {
                SymbdevPlugin.getDefault().getLog().log(
                        new Status(IStatus.WARNING, SymbdevPlugin.getUniqueIdentifier(),
                                SymbdevPlugin.WARNING_SKIN, "No path or id in extenstion point",
                                null));
                continue;
            }
            
            
            
            Bundle b=Platform.getBundle(pluginLabel);
            try {
                Path localPath=SymbdevPlugin.getFile(b, path);
                SkinEntry entry=new SkinEntry();
                entry.id=id;
                entry.fName=null;
                entry.rootPath=localPath;
                fSkins.put(entry.id, entry);
            } catch (IOException e) {
                SymbdevPlugin.getDefault().getLog().log(
                        new Status(IStatus.WARNING, SymbdevPlugin.getUniqueIdentifier(),
                                SymbdevPlugin.WARNING_SKIN, "No path or id in extenstion point", e));
                continue;
            }
        }        
    }

    /**
     * Sets the changes to epoc.ini to apply a skin
     * @param file The skin.xml file
     * @param skinRoot The root directory of that skin
     * @param rootDir The root dir of the Symbian SDK
     * @param rewriter The rewriter to which the rules will applied
     */
    static public void applySkin(IPath skinRoot, IPath sdkDir, int symbianVersion, EpocIniRewriter rewriter)
    	throws CoreException
    {
    	try {
    	    File file=new File(skinRoot.append("skin.xml").toString());
    		SAXParser parser=SAXParserFactory.newInstance().newSAXParser();
    		parser.parse(file, new SkinXmlApplier(rewriter, skinRoot, sdkDir, symbianVersion));
    	}
    	catch (Exception e)
    	{
    	    Status s=new Status(IStatus.ERROR, SymbdevPlugin.getUniqueIdentifier(),
    	            SymbdevPlugin.ERROR_EPOC_SKIN, "Error loading skin: "+e.getMessage(), e);
    	    throw new CoreException(s);
    	}        
    }
    
    static public SkinManager getDefault()
    {
        if (fDefault==null)
        {
            fDefault=new SkinManager();
        }
        
        return fDefault;
    }
    
    /**
     * Get all the avaible skins
     * @return The avaible skins
     */
    public Iterator getEntries()
    {
        return fSkins.values().iterator();
    }
    
    public SkinEntry getEntry(String id)
    {
        if (id==null)
            return SkinEntry.getDefault();
        SkinEntry entry=(SkinEntry)fSkins.get(id);
        if (entry==null) return SkinEntry.getDefault();
          	else return entry; 
    }
    
    TreeMap fSkins;
    protected static SkinManager fDefault;
}
