/*
 * Created on 2005-01-02
 *
 * Part of the Symbian development plug-in for Eclipse
 * Copyright (C) Mikołaj Zalewski, 2005
 */
package pl.zalewski.mikolaj.symbdev.core.mmpmodel;

import java.io.File;
import java.io.IOException;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;

import pl.zalewski.mikolaj.symbdev.SymbdevPlugin;
import pl.zalewski.mikolaj.symbdev.utils.FileStringType;

/**
 * A reference to a file in a MMP file. 
 * 
 * @author mikolaj
 */
public class MMPFileReference implements Cloneable {
    public MMPFileReference(String string, String sourcePath)
    {
        fString=string;
        fSourcePathString=sourcePath;
    }
    
    /**
     * @return The string set in the MMP file
     */
    public String fString;
    
    /**
     * @return The string of the SOURCEPATH corresponding to this
     * entry as found in the MMP file 
     */
    public String fSourcePathString;
    
    /**
     * Returns the path if the path is relative of <code>null</code>
     * if this is a absolute path
     * @param mmpPath The path to the directory containing the MMP file
     * @return The filesystem path
     */
    public IPath getPathIfRelative(IPath mmpPath) {
        if (fSourcePathString!=null && fSourcePathString.charAt(0)=='\\')
            return null;
        IPath path=mmpPath.append(fSourcePathString);
        return path.append(fString);
        
    }
    
    public IPath getCanonicalPathIfRelative(IPath mmpPath)
    {
        IPath path=getPathIfRelative(mmpPath);
        File f=path.toFile();
        try {
            return new Path(f.getCanonicalPath());
        }
        catch (IOException e) {
            return path;
        }
    }
    
    public IPath getCanonicalPath(IPath mmpPath, IPath rootPath) {
        if (fSourcePathString==null || fSourcePathString.charAt(0)!='\\')
            return getCanonicalPathIfRelative(mmpPath);
        IPath path=rootPath.append(fSourcePathString);
        path=path.append(fString);
        File f=path.toFile();
        try {
            return new Path(f.getCanonicalPath());
        }
        catch (IOException e) {
            SymbdevPlugin.logWarning(SymbdevPlugin.WARNING_IO_ACCESS,
                    "I/O exception while quering canoncal path", e);
            return path;
        }
    }
    
    /**
     * Resturns the workspace file that this reference points to
     * or <code>null</code> if no file was found or this path points
     * outside the workspace
     * @param mmpPath The filesystem path to the directory containing
     * the MMP file. Used to process relative paths
     * @return The workspace file or <code>null</code>
     */
    public IFile getWorkspaceFile(IPath mmpPath) {
        IPath path=getCanonicalPathIfRelative(mmpPath);
        if (path==null)
            return null;
        return ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(path);
    }
    
    /**
     * Resturns the workspace container that this reference points to
     * or <code>null</code> if no file was found or this path points
     * outside the workspace
     * @param mmpPath The filesystem path to the directory containing
     * the MMP file. Used to process relative paths
     * @return The workspace container or <code>null</code>
     */
    public IContainer getWorkspaceContainer(IPath mmpPath) {
        IPath path=getCanonicalPathIfRelative(mmpPath);
        if (path==null)
            return null;
        return ResourcesPlugin.getWorkspace().getRoot().getContainerForLocation(path);        
    }
    
    /**
     * Resturns the workspace file or container that this reference points to
     * or <code>null</code> if no file was found or this path points
     * outside the workspace
     * @param mmpPath The filesystem path to the directory containing
     * the MMP file. Used to process relative paths
     * @return The workspace resource or <code>null</code>
     */
    public IResource getWorkspaceResource(IPath mmpPath) {
        IResource res=getWorkspaceFile(mmpPath);
        if (res!=null) return res;
        return getWorkspaceContainer(mmpPath);
    }
    
    public FileStringType getFileStringType(
            String rootPath,
            String currentPath)
    {
        return new FileStringType(fString, rootPath, currentPath,
                fSourcePathString, FileStringType.TYPE_FILE);
    }
    
    public static boolean isEqual(Object o1, Object o2)
    {
        if (o1==o2)
            return true;
        
        return (o1!=null && o1.equals(o2)); // if o1==null then o2!=null and the result is false
    }
    
    public boolean equals(Object obj) {
        if (obj instanceof MMPFileReference)
        {
            MMPFileReference ref=(MMPFileReference)obj;
            if (!isEqual(fSourcePathString, ref.fSourcePathString))
                return false;
            return isEqual(fString, ref.fString);
        } else return super.equals(obj);
    }
    public Object clone()
    	throws CloneNotSupportedException
    {
        return super.clone();
    }
}
