/*
 * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.media.sound;

import java.util.StringTokenizer;



/**
 * Audio configuration class for exposing attributes specific to the platform or system.
 *
 * @author Kara Kytle
 * @author Florian Bomers
 */
class Platform {


    // STATIC FINAL CHARACTERISTICS

    // native library we need to load
    private static final String libNameMain     = "jsound";
    private static final String libNameMain2    = "jsoundhs";

    private static final String libNameALSA     = "jsoundalsa";
    private static final String libNameDSound   = "jsoundds";

    // extra libs handling: bit flags for each different library
    public static final int LIB_MAIN     = 1;
    public static final int LIB_ALSA     = 2;
    public static final int LIB_DSOUND   = 4;

    // bit field of the constants above. Willbe set in loadLibraries
    private static int loadedLibs = 0;

    // features: the main native library jsound reports which feature is
    // contained in which lib
    public static final int FEATURE_MIDIIO       = 1;
    public static final int FEATURE_PORTS        = 2;
    public static final int FEATURE_DIRECT_AUDIO = 3;

    // SYSTEM CHARACTERISTICS
    // vary according to hardware architecture

    // signed8 (use signed 8-bit values) is true for everything we support except for
    // the solaris sbpro card.
    // we'll leave it here as a variable; in the future we may need this in java.
    // wait, is that true?  i'm not sure.  i think solaris takes unsigned data?
    // $$kk: 03.11.99: i think solaris takes unsigned 8-bit or signed 16-bit data....
    private static boolean signed8;

    // intel is little-endian.  sparc is big-endian.
    private static boolean bigEndian;

    // this is the value of the "java.home" system property.  i am looking it up here
    // for use when trying to load the soundbank, just so
    // that all the privileged code is localized in this file....
    private static String javahome;

    // this is the value of the "java.class.path" system property
    private static String classpath;




    static {
        if(Printer.trace)Printer.trace(">> Platform.java: static");

        loadLibraries();
        readProperties();
    }


    /**
     * Private constructor.
     */
    private Platform() {
    }


    // METHODS FOR INTERNAL IMPLEMENTATION USE


    /**
     * Dummy method for forcing initialization.
     */
    static void initialize() {

        if(Printer.trace)Printer.trace("Platform: initialize()");
    }


    /**
     * Determine whether the system is big-endian.
     */
    static boolean isBigEndian() {

        return bigEndian;
    }


    /**
     * Determine whether the system takes signed 8-bit data.
     */
    static boolean isSigned8() {

        return signed8;
    }


    /**
     * Obtain javahome.
     * $$kk: 04.16.99: this is *bad*!!
     */
    static String getJavahome() {

        return javahome;
    }

    /**
     * Obtain classpath.
     * $$jb: 04.21.99: this is *bad* too!!
     */
    static String getClasspath() {

        return classpath;
    }


    // PRIVATE METHODS

    /**
     * Load the native library or libraries.
     */
    private static void loadLibraries() {
        if(Printer.trace)Printer.trace(">>Platform.loadLibraries");

        try {
            // load the main libraries
            JSSecurityManager.loadLibrary(libNameMain);
            JSSecurityManager.loadLibrary(libNameMain2);
            // just for the heck of it...
            loadedLibs |= LIB_MAIN;
        } catch (SecurityException e) {
            if(Printer.err)Printer.err("Security exception loading main native library.  JavaSound requires access to these resources.");
            throw(e);
        }

        // now try to load extra libs. They are defined at compile time in the Makefile
        // with the define EXTRA_SOUND_JNI_LIBS
        String extraLibs = nGetExtraLibraries();
        // the string is the libraries, separated by white space
        StringTokenizer st = new StringTokenizer(extraLibs);
        while (st.hasMoreTokens()) {
            String lib = st.nextToken();
            try {
                JSSecurityManager.loadLibrary(lib);
                if (lib.equals(libNameALSA)) {
                    loadedLibs |= LIB_ALSA;
                    if (Printer.debug) Printer.debug("Loaded ALSA lib successfully.");
                } else if (lib.equals(libNameDSound)) {
                    loadedLibs |= LIB_DSOUND;
                    if (Printer.debug) Printer.debug("Loaded DirectSound lib successfully.");
                } else {
                    if (Printer.err) Printer.err("Loaded unknown lib '"+lib+"' successfully.");
                }
            } catch (Throwable t) {
                if (Printer.err) Printer.err("Couldn't load library "+lib+": "+t.toString());
            }
        }
    }


    static boolean isMidiIOEnabled() {
        return isFeatureLibLoaded(FEATURE_MIDIIO);
    }

    static boolean isPortsEnabled() {
        return isFeatureLibLoaded(FEATURE_PORTS);
    }

    static boolean isDirectAudioEnabled() {
        return isFeatureLibLoaded(FEATURE_DIRECT_AUDIO);
    }

    private static boolean isFeatureLibLoaded(int feature) {
        if (Printer.debug) Printer.debug("Platform: Checking for feature "+feature+"...");
        int requiredLib = nGetLibraryForFeature(feature);
        boolean isLoaded = (requiredLib != 0) && ((loadedLibs & requiredLib) == requiredLib);
        if (Printer.debug) Printer.debug("          ...needs library "+requiredLib+". Result is loaded="+isLoaded);
        return isLoaded;
    }

    // the following native methods are implemented in Platform.c
    private native static boolean nIsBigEndian();
    private native static boolean nIsSigned8();
    private native static String nGetExtraLibraries();
    private native static int nGetLibraryForFeature(int feature);


    /**
     * Read the required system properties.
     */
    private static void readProperties() {
        // $$fb 2002-03-06: implement check for endianness in native. Facilitates porting !
        bigEndian = nIsBigEndian();
        signed8 = nIsSigned8(); // Solaris on Sparc: signed, all others unsigned
        javahome = JSSecurityManager.getProperty("java.home");
        classpath = JSSecurityManager.getProperty("java.class.path");
    }
}
