/*
 * File:     MimeType.java
 * Project:  MPI Linguistic Application
 * Date:     03 April 2006
 *
 * Copyright (C) 2001-2006  Max Planck Institute for Psycholinguistics
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package mpi.util;

import mpi.util.OurURL;


/**
 * MimeType class implements mime-type construction from type and format
 * strings Also contains the mapping between file name extensions and
 * MimeTypes adds some convenience functions
 */
public class MimeType {
    private String _type;
    private String _format;
    private boolean _status;
    private String _compression = null;

    /**
     * DOCUMENT ME!
     *
     * @param type the type part of the mime-type
     * @param format the format part of the mime-type
     */
    public MimeType(String type, String format) {
        //System.out.println("MimeType: constr; "+type+" "+format);
        _type = type;
        _format = format;
        _status = true;
    }

    /**
     * DOCUMENT ME!
     *
     * @param mimetype the type part of the mime-type
     */
    public MimeType(String mimetype) {
        //System.out.println("MimeType: constr; "+mimetype);
        int idx;

        if ((idx = mimetype.indexOf('/')) < 0) {
            _status = false;
        } else {
            _type = mimetype.substring(0, idx);
            _format = mimetype.substring(idx + 1);
            _status = true;
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param name DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static String getMimeTypeStringFromExtension(String name) {
        // Browsable Corpus special files
        if (name.endsWith(".xml")) {
            return "text/xml";
        }

        // imdi metadata descriptions
        if (name.endsWith(".imdi")) {
            return "text/x-imdi+xml";
        }

        // documentation files
        if (name.endsWith(".html")) {
            return "text/html";
        }

        if (name.endsWith(".htm")) {
            return "text/html";
        }

        if (name.endsWith(".pdf")) {
            return "application/pdf";
        }

        if (name.endsWith(".txt")) {
            return "text/plain";
        }

        if (name.endsWith(".text")) {
            return "text/plain";
        }

        // transcription files
        if (name.endsWith(".chat")) {
            return "text/x-chat";
        }

        //shoebox
        if (name.endsWith(".sht")) {
            return "text/x-shoebox-text";
        }

        if (name.endsWith(".eaf")) {
            return "text/x-eaf+xml";
        }

        // media files
        // audio
        if (name.endsWith(".au")) {
            return "audio/basic";
        }

        if (name.endsWith(".wav")) {
            return "audio/x-wav";
        }

        if (name.endsWith(".aif")) {
            return "audio/x-aiff";
        }

        if (name.endsWith(".aiff")) {
            return "audio/x-aiff";
        }

        if (name.endsWith(".aifc")) {
            return "audio/x-aiff";
        }

        if (name.endsWith(".sd")) {
            return "audio/x-esps";
        }

        if (name.endsWith(".mp3")) {
            return "audio/mpeg";
        }

        // video
        if (name.endsWith(".mpg")) {
            return "video/x-mpeg1";
        }

        if (name.endsWith(".mpeg")) {
            return "video/x-mpeg2";
        }

        if (name.endsWith(".mp4")) {
            return "video/x-mpeg4";
        }

        if (name.endsWith(".mov")) {
            return "video/quicktime";
        }

        if (name.endsWith(".avi")) {
            return "video/x-msvideo";
        }

        if (name.endsWith(".smil")) {
            return "application/smil+xml";
        }

        //image
        if (name.endsWith(".gif")) {
            return "image/gif";
        }

        if (name.endsWith(".jpg")) {
            return "image/jpeg";
        }

        if (name.endsWith(".png")) {
            return "image/png";
        }

        if (name.endsWith(".tiff")) {
            return "image/tiff";
        }

        return "unknown";
    }

    /**
     * DOCUMENT ME!
     *
     * @param name DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static MimeType getMimeTypeFromExtension(String name) {
        MimeType mt = new MimeType(getMimeTypeStringFromExtension(name));

        if (mt.status()) {
            return mt;
        } else {
            return null;
        }
    }

    /**
     * match()
     *
     * @param type1 The mime-type that needs to be matched
     * @param type2 The mime -type that needs to be matched
     *
     * @return if the two mime-type(s) match the wild card character '' is
     *         allowed as the last character of a mime-type specification
     */
    public static boolean matches(String type1, String type2) {
        //System.out.println("matches: "+type1+" "+type2);
        String t1 = type1;
        String t2 = type2;

        if (type1.endsWith("*") && type2.endsWith("*")) {
            t1 = type1.substring(0, type1.length() - 1);
            t2 = type2.substring(0, type2.length() - 1);

            if (t2.startsWith(t1) || t1.startsWith(t2)) {
                return true;
            }
        } else if (type1.endsWith("*")) {
            t1 = type1.substring(0, type1.length() - 1);

            if (t2.startsWith(t1)) {
                return true;
            }
        } else if (type2.endsWith("*")) {
            t2 = type2.substring(0, type2.length() - 1);

            if (t1.startsWith(t2)) {
                return true;
            }
        } else {
            if (t1.equals(t2)) {
                return true;
            }
            //try to group related formats such as wav and x-wav etc
            //if one format contains the other, return true
            // type can also be unknow or garbled string
            else if ((t1.indexOf('/') != -1) && (t2.indexOf('/') != -1)) {
                if (t1.substring(0, t1.indexOf('/')).equalsIgnoreCase(t2.substring(
                                0, t2.indexOf('/')))) {
                    String f1 = t1.substring(t1.indexOf('/') + 1).toLowerCase();
                    String f2 = t2.substring(t2.indexOf('/') + 1).toLowerCase();

                    if (f1.length() < f2.length()) {
                        if (f2.indexOf(f1) > -1) {
                            return true;
                        }
                    } else if (f2.length() < f1.length()) {
                        if (f1.indexOf(f2) > -1) {
                            return true;
                        }
                    }
                }

                // if t1
            }
        }

        //System.out.println("matches: NO MATCH");
        return false;
    }

    //matches

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean status() {
        return _status;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String toString() {
        if ((_compression != null) && !_compression.equalsIgnoreCase("None")) {
            return _type + "/" + _format + " - " + _compression;
        } else {
            return _type + "/" + _format;
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getType() {
        return _type;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getFormat() {
        return _format;
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public String getCompression() {
        return _compression;
    }

    /**
     * DOCUMENT ME!
     *
     * @param compr DOCUMENT ME!
     */
    public void setCompression(String compr) {
        _compression = compr;
    }

    /**
     * DOCUMENT ME!
     *
     * @param t DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean equals(String t) {
        //System.out.println("MimeType:equals "+t+" "+toString());
        if ((_compression != null) && !_compression.equalsIgnoreCase("None")) {
            return false;
        } else {
            return toString().equalsIgnoreCase(t);
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param t DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public boolean matches(String t) {
        if ((_compression != null) && !_compression.equalsIgnoreCase("None")) {
            return false;
        }

        if (t.endsWith("*")) {
            return toString().regionMatches(0, t, 0, t.length() - 1);
        } else {
            return toString().equals(t);
        }
    }
}
