/*
 * The Broad Institute
 * SOFTWARE COPYRIGHT NOTICE AGREEMENT
 * This is copyright (2007-2008) by the Broad Institute/Massachusetts Institute 
 * of Technology.  It is licensed to You under the Gnu Public License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *    http://www.opensource.org/licenses/gpl-2.0.php
 *
 * This software is supplied without any warranty or guaranteed support
 * whatsoever. Neither the Broad Institute nor MIT can be responsible for its
 * use, misuse, or functionality.
*/



package org.broad.igv.data;

import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;

/**
 *
 * Represents a data file or other resource, which might be local file or remote resource.
 * 
 * @author jrobinso
 */
public class ResourceLocator {

    /**
     * Name (label) of this locator.  
     */
    String name;
    
    /**
     * URL for the remote data server.  Null for local files
     */
    String serverURL;
    
    /**
     * The path for the file or resource.  For remote resource this value 
     * will be interpreted by the server and need not be the actualy, physical
     * path.
     */
    String path;

    /**
     * A hyperlink to information.
     */
    String hyperLink;
    
    /**
     * A hyperlink to information.
     */
    String description;;

    /**
     * Determines if the resource actually exists.
     * 
     * TODO - Method is implemented for local file not server files yet!
     * @return true if resource was found.
     */
    public boolean exists() {
        if(isLocal()) {
            return new File(path).exists();
        }
        return true;
    }
    
    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final ResourceLocator other = (ResourceLocator) obj;
        if (this.serverURL != other.serverURL && (this.serverURL == null || !this.serverURL.equals(other.serverURL))) {
            return false;
        }
        if (this.path != other.path && (this.path == null || !this.path.equals(other.path))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 29 * hash + (this.serverURL != null ? this.serverURL.hashCode() : 0);
        hash = 29 * hash + (this.path != null ? this.path.hashCode() : 0);
        return hash;
    }

    /**
     * Constructor for local files
     * @param path
     */
    public ResourceLocator(URL url) throws UnsupportedEncodingException {
        
        StringBuffer buffer = new StringBuffer();
        buffer.append(url.getProtocol());
        buffer.append("://");
        buffer.append(url.getHost());
        int port = url.getPort();
        if(port != -1) {
            buffer.append(":");
            buffer.append(port);
        }
        serverURL = buffer.toString();
        path = URLDecoder.decode(url.getFile(), "UTF-8");
    }
    
    /**
     * Constructor for local files
     * @param path
     */
    public ResourceLocator(String path) {
        this.serverURL = null;
        this.path = path;
    }
    
    /**
     * Constructor for remote files
     * 
     * @param serverURL
     * @param path
     */
    public ResourceLocator(String serverURL, String path) {
        this.serverURL = serverURL;
        this.path = path;
    }

    public URL toURL()
    throws MalformedURLException {
        return new URL(serverURL+path);
    }

    public String getPath() {
        return path;
    }

    public String getServerURL() {
        return serverURL;
    }
    
    public boolean isLocal() {
        return serverURL == null;
    }

    public void setHyperLink(String hyperLink) {
        this.hyperLink = hyperLink;
    }

    public String getHyperLink() {
        return hyperLink;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
    
    public String getDisplayName() {
        return name == null ? new File(getPath()).getName() : name;
    }

    /**
     * Name (label) of this locator.
     */
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
    
    /**
     * ResourceLocator Attribute types
     */
    public static enum AttributeType {

        DESCRIPTION("description"),
        HYPERLINK("hyperlink"),
        NAME("name"),
        SERVER_URL("serverURL"),
        PATH("path");

        private String name;

        AttributeType(String name) {
            this.name = name;
        }

        public String getText() {
            return name;
        }

        @Override
        public String toString() {
            return getText();
        }

        static public AttributeType findEnum(String value) {

            if (value == null) {
                return null;
            }

            if (value.equals(SERVER_URL.getText())) {
                return SERVER_URL;
            } else if (value.equals(PATH.getText())) {
                return PATH;
            } else if (value.equals(DESCRIPTION.getText())) {
                return DESCRIPTION;
            } else if (value.equals(HYPERLINK.getText())) {
                return HYPERLINK;
            } else if (value.equals(NAME.getText())) {
                return NAME;
            } 
            return null;
        }
    }
}
