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

import java.io.IOException;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;

import pl.zalewski.mikolaj.symbdev.SymbdevPlugin;
import pl.zalewski.mikolaj.symbdev.SymbianCommandHelper;
import pl.zalewski.mikolaj.symbdev.SymbianPrjNature;
import pl.zalewski.mikolaj.symbdev.SymbianSDKEntry;
import pl.zalewski.mikolaj.symbdev.properties.ProjectProperties;
import pl.zalewski.mikolaj.symbdev.skins.EpocIniRewriter;
import pl.zalewski.mikolaj.symbdev.skins.SkinEntry;
import pl.zalewski.mikolaj.symbdev.skins.SkinManager;

/**
 * @author mikolaj
 *
 * This class is resposible for launching the EPOC emulator
 */
public class SymbianLaunchConfigurationDelegate extends
        LaunchConfigurationDelegate {

    final public static String ATTR_PROJECT=SymbdevPlugin.getUniqueIdentifier()+".PROJECT_NAME"; 
    final public static String ATTR_SKIN_ID=SymbdevPlugin.getUniqueIdentifier()+".SKIN_ID";
    final public static String EPOC_CUSTOM_MACHINE="epoc.eclipse";
    
    /**
     * 
     */
    public SymbianLaunchConfigurationDelegate() {
        super();
    }

    /* (non-Javadoc)
     * @see org.eclipse.debug.core.model.ILaunchConfigurationDelegate#launch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String, org.eclipse.debug.core.ILaunch, org.eclipse.core.runtime.IProgressMonitor)
     */
    public void launch(ILaunchConfiguration configuration, String mode,
            ILaunch launch, IProgressMonitor monitor) throws CoreException {
        IProject project=getProject(configuration);
        SymbianSDKEntry sdkEntry=ProjectProperties.getSymbianSDK(project);
        String epocRoot=sdkEntry.epocRoot;
        
        String skinId=getEmulatorSkinId(configuration);
        SkinEntry entry=SkinManager.getDefault().getEntry(skinId);

        boolean customEpocIni=false;
	    EpocIniRewriter rewriter=EpocIniRewriter.createStdRewriter(epocRoot);
	    
	    if (entry.getId()!=null)
	    {
	        customEpocIni=true;
	        SkinManager.applySkin(entry.rootPath, new Path(epocRoot), sdkEntry.getSymbianVersion(), rewriter);
	    }
	    
	    try
	    {
	        if (customEpocIni)
	            rewriter.rewrite();
	    }
	    catch (IOException e)
	    {
	        throw new CoreException(new Status(IStatus.ERROR,
	                SymbdevPlugin.getUniqueIdentifier(), SymbdevPlugin.ERROR_EPOC_INI_REWRITE,
	                "Error rewriting epoc32\\data\\epoc.ini to epoc32\\data\\"+EPOC_CUSTOM_MACHINE+".ini", e));	        
	    }
        
        launchEmulator(project, customEpocIni);
    }

    /* (non-Javadoc)
     * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getBuildOrder(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String)
     */
    protected IProject[] getBuildOrder(ILaunchConfiguration configuration,
            String mode) throws CoreException {
        return new IProject[]{ getProject(configuration) };
    }
    
    /* (non-Javadoc)
     * @see org.eclipse.debug.core.model.LaunchConfigurationDelegate#getProjectsForProblemSearch(org.eclipse.debug.core.ILaunchConfiguration, java.lang.String)
     */
    protected IProject[] getProjectsForProblemSearch(
            ILaunchConfiguration configuration, String mode)
            throws CoreException {
        return new IProject[]{ getProject(configuration) };
    }
    
    public void launchEmulator(IProject project, boolean customEpocIni)
    	throws CoreException
    {
        if (!project.hasNature(SymbianPrjNature.NATURE_ID))
            throw new CoreException(new Status(IStatus.ERROR, SymbdevPlugin.getUniqueIdentifier(),
                    SymbdevPlugin.ERROR_LAUNCH_BAD_PROJECT, "The current project is not a Symbian project", null));
        
        String[] env=SymbianCommandHelper.buildEnvironment(project);
        String[] args=new String[customEpocIni?6:4];
        
        args[0]=SymbianCommandHelper.getOSShell();
        args[1]="/c";
        args[2]="start";
        args[3]=new Path(ProjectProperties.getSymbianSDK(project).epocRoot)
        				.append("epoc32/release").append(ProjectProperties.getWin32Tool(project).target)
        				.append(ProjectProperties.getABLDBuild(project)).append("epoc.exe").toOSString();
        
        if (customEpocIni)
        {
            args[4]="-M"+EPOC_CUSTOM_MACHINE;
            args[5]="--";
        }
        
        try {
            Process p=Runtime.getRuntime().exec(args, env);
        }
        catch (IOException e)
        {
            throw new CoreException(new Status(IStatus.ERROR, SymbdevPlugin.getUniqueIdentifier(),
                    SymbdevPlugin.ERROR_LAUNCH_EXEC, "Error while launching the emulator", null));            
        }
    }
    
	public static String getProjectName(ILaunchConfiguration configuration) throws CoreException {
		return configuration.getAttribute(ATTR_PROJECT, (String)null);
	}	
	
	public static IProject getProject(ILaunchConfiguration configuration) throws CoreException
	{
	    String projectName=getProjectName(configuration);
		return getSymbianProjectByName(projectName);
	}
	
	public static void setProjectName(ILaunchConfigurationWorkingCopy conf, String name)
	{
		conf.setAttribute(ATTR_PROJECT, name);	    
	}
	
	public static String getEmulatorSkinId(ILaunchConfiguration configuration) throws CoreException
	{
		return configuration.getAttribute(ATTR_SKIN_ID, (String)null);
	}

	public static void setEmulatorSkinId(ILaunchConfigurationWorkingCopy conf, String id)
	{
		conf.setAttribute(ATTR_SKIN_ID, id);	    
	}
	
	public static IProject getSymbianProjectByName(String projectName)
	{
		if (projectName != null) {
			projectName = projectName.trim();
			if (projectName.length() > 0) {
				return ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
			}
		}
		return null;	    
	}
}
