/*
  ==============================================================================

   This file is part of the JUCE library - "Jules' Utility Class Extensions"
   Copyright 2004-7 by Raw Material Software ltd.

  ------------------------------------------------------------------------------

   JUCE can be redistributed and/or modified 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.

   JUCE 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 JUCE; if not, visit www.gnu.org/licenses or write to the
   Free Software Foundation, Inc., 59 Temple Place, Suite 330,
   Boston, MA 02111-1307 USA

  ------------------------------------------------------------------------------

   If you'd like to release a closed-source product which uses JUCE, commercial
   licenses are also available: visit www.rawmaterialsoftware.com/juce for
   more information.

  ==============================================================================
*/

/*
  ==============================================================================

    This header contains the entire Juce source tree, and can be #included in
    all your source files.

    As well as including this in your files, you should also add juce_inline.cpp
    to your project (or juce_inline.mm on the Mac).

  ==============================================================================
*/

#ifndef __JUCE_AMALGAMATED_TEMPLATE_JUCEHEADER__
#define __JUCE_AMALGAMATED_TEMPLATE_JUCEHEADER__

#define DONT_AUTOLINK_TO_JUCE_LIBRARY 1

/********* Start of inlined file: juce.h *********/
#ifndef __JUCE_JUCEHEADER__
#define __JUCE_JUCEHEADER__

/*
    This is the main JUCE header file that applications need to include.

*/

// (this includes things that need defining outside of the JUCE namespace)

/********* Start of inlined file: juce_StandardHeader.h *********/
#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__
#define __JUCE_STANDARDHEADER_JUCEHEADER__

/** Current Juce version number.

    See also SystemStats::getJUCEVersion() for a string version.
*/
#define JUCE_MAJOR_VERSION      1
#define JUCE_MINOR_VERSION      50

/** Current Juce version number.

    Bits 16 to 32 = major version.
    Bits 8 to 16 = minor version.
    Bits 0 to 8 = point release (not currently used).

    See also SystemStats::getJUCEVersion() for a string version.
*/
#define JUCE_VERSION            ((JUCE_MAJOR_VERSION << 16) + (JUCE_MINOR_VERSION << 8))

/********* Start of inlined file: juce_Config.h *********/
#ifndef __JUCE_CONFIG_JUCEHEADER__
#define __JUCE_CONFIG_JUCEHEADER__

/*
    This file contains macros that enable/disable various JUCE features.
*/

/** The name of the namespace that all Juce classes and functions will be
    put inside. If this is not defined, no namespace will be used.
*/
#ifndef JUCE_NAMESPACE
  #define JUCE_NAMESPACE juce
#endif

/** Normally, JUCE_DEBUG is set to 1 or 0 based on compiler and project settings,
    but if you define this value, you can override this can force it to be true or
    false.
*/
#ifndef JUCE_FORCE_DEBUG
  //#define JUCE_FORCE_DEBUG 1
#endif

/** If this flag is enabled, the the jassert and jassertfalse macros will
    always use Logger::writeToLog() to write a message when an assertion happens.

    Enabling it will also leave this turned on in release builds. When it's disabled,
    however, the jassert and jassertfalse macros will not be compiled in a
    release build.

    @see jassert, jassertfalse, Logger
*/
#ifndef JUCE_LOG_ASSERTIONS
//  #define JUCE_LOG_ASSERTIONS 1
#endif

/** Comment out this macro if you haven't got the Steinberg ASIO SDK, without
    which the ASIOAudioIODevice class can't be built. See the comments in the
    ASIOAudioIODevice class's header file for more info about this.

    (This only affects a Win32 build)
*/
#ifndef JUCE_ASIO
  #define JUCE_ASIO 1
#endif

/** Comment out this macro to disable building of ALSA device support on Linux.
*/
#ifndef JUCE_ALSA
  #define JUCE_ALSA 1
#endif

/** Comment out this macro if you don't want to enable QuickTime or if you don't
    have the SDK installed.

    If this flag is not enabled, the QuickTimeMovieComponent and QuickTimeAudioFormat
    classes will be unavailable.

    On Windows, if you enable this, you'll need to have the QuickTime SDK
    installed, and its header files will need to be on your include path.
*/
#if ! (defined (JUCE_QUICKTIME) || defined (LINUX) || (defined (_WIN32) && ! defined (_MSC_VER)))
  #define JUCE_QUICKTIME 1
#endif

/** Comment out this macro if you don't want to enable OpenGL or if you don't
    have the appropriate headers and libraries available. If it's not enabled, the
    OpenGLComponent class will be unavailable.
*/
#ifndef JUCE_OPENGL
  #define JUCE_OPENGL 1
#endif

/** These flags enable the Ogg-Vorbis and Flac audio formats.

    If you're not going to need either of these formats, turn off the flags to
    avoid bloating your codebase with them.
*/
#ifndef JUCE_USE_FLAC
  #define JUCE_USE_FLAC 1
#endif

#ifndef JUCE_USE_OGGVORBIS
  #define JUCE_USE_OGGVORBIS 1
#endif

/** This flag lets you enable support for CD-burning. You might want to disable
    it to build without the MS SDK under windows.
*/
#if (! defined (JUCE_USE_CDBURNER)) && ! (defined (_WIN32) && ! defined (_MSC_VER))
  #define JUCE_USE_CDBURNER 1
#endif

/** Enabling this provides support for cameras, using the CameraDevice class
*/
#if JUCE_QUICKTIME && ! defined (JUCE_USE_CAMERA)
//  #define JUCE_USE_CAMERA 1
#endif

/** Enabling this macro means that all regions that get repainted will have a coloured
    line drawn around them.

    This is handy if you're trying to optimise drawing, because it lets you easily see
    when anything is being repainted unnecessarily.
*/
#ifndef JUCE_ENABLE_REPAINT_DEBUGGING
//  #define JUCE_ENABLE_REPAINT_DEBUGGING 1
#endif

/** Enable this under Linux to use Xinerama for multi-monitor support.
*/
#ifndef JUCE_USE_XINERAMA
  #define JUCE_USE_XINERAMA 1
#endif

/** Enable this under Linux to use XShm for faster shared-memory rendering.
*/
#ifndef JUCE_USE_XSHM
  #define JUCE_USE_XSHM 1
#endif

/** Enabling this builds support for VST audio plugins.
    @see VSTPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_AU
*/
#ifndef JUCE_PLUGINHOST_VST
//  #define JUCE_PLUGINHOST_VST 1
#endif

/** Enabling this builds support for AudioUnit audio plugins.
    @see AudioUnitPluginFormat, AudioPluginFormat, AudioPluginFormatManager, JUCE_PLUGINHOST_VST
*/
#ifndef JUCE_PLUGINHOST_AU
//  #define JUCE_PLUGINHOST_AU 1
#endif

/** Enabling this will avoid including any UI code in the build. This is handy for
    writing command-line utilities, e.g. on linux boxes which don't have some
    of the UI libraries installed.
*/
#ifndef JUCE_ONLY_BUILD_CORE_LIBRARY
  //#define JUCE_ONLY_BUILD_CORE_LIBRARY  1
#endif

/** This lets you disable building of the WebBrowserComponent, if it's not required.
*/
#ifndef JUCE_WEB_BROWSER
  #define JUCE_WEB_BROWSER 1
#endif

/** Setting this allows the build to use old Carbon libraries that will be
    deprecated in newer versions of OSX. This is handy for some backwards-compatibility
    reasons.
*/
#ifndef JUCE_SUPPORT_CARBON
  #define JUCE_SUPPORT_CARBON 1
#endif

/*  These flags let you avoid the direct inclusion of some 3rd-party libs in the
    codebase - you might need to use this if you're linking to some of these libraries
    yourself.
*/
#ifndef JUCE_INCLUDE_ZLIB_CODE
  #define JUCE_INCLUDE_ZLIB_CODE        1
#endif

#ifndef JUCE_INCLUDE_FLAC_CODE
  #define JUCE_INCLUDE_FLAC_CODE        1
#endif

#ifndef JUCE_INCLUDE_OGGVORBIS_CODE
  #define JUCE_INCLUDE_OGGVORBIS_CODE   1
#endif

#ifndef JUCE_INCLUDE_PNGLIB_CODE
  #define JUCE_INCLUDE_PNGLIB_CODE      1
#endif

#ifndef JUCE_INCLUDE_JPEGLIB_CODE
  #define JUCE_INCLUDE_JPEGLIB_CODE     1
#endif

/** Enable this to add extra memory-leak info to the new and delete operators.

    (Currently, this only affects Windows builds in debug mode).
*/
#ifndef JUCE_CHECK_MEMORY_LEAKS
  #define JUCE_CHECK_MEMORY_LEAKS 1
#endif

/** Enable this to turn on juce's internal catching of exceptions.

    Turning it off will avoid any exception catching. With it on, all exceptions
    are passed to the JUCEApplication::unhandledException() callback for logging.
*/
#ifndef JUCE_CATCH_UNHANDLED_EXCEPTIONS
  #define JUCE_CATCH_UNHANDLED_EXCEPTIONS 1
#endif

/** If this macro is set, the Juce String class will use unicode as its
    internal representation. If it isn't set, it'll use ANSI.
*/
#ifndef JUCE_STRINGS_ARE_UNICODE
  #define JUCE_STRINGS_ARE_UNICODE 1
#endif

#endif
/********* End of inlined file: juce_Config.h *********/

#ifdef JUCE_NAMESPACE
  #define BEGIN_JUCE_NAMESPACE    namespace JUCE_NAMESPACE {
  #define END_JUCE_NAMESPACE      }
#else
  #define BEGIN_JUCE_NAMESPACE
  #define END_JUCE_NAMESPACE
#endif

// This sets up the JUCE_WIN32, JUCE_MAC, or JUCE_LINUX macros

/********* Start of inlined file: juce_PlatformDefs.h *********/
#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__
#define __JUCE_PLATFORMDEFS_JUCEHEADER__

/*  This file figures out which platform is being built, and defines some macros
    that the rest of the code can use for OS-specific compilation.

    Macros that will be set here are:

    - One of JUCE_WIN32, JUCE_MAC or JUCE_LINUX.
    - Either JUCE_32BIT or JUCE_64BIT, depending on the architecture.
    - Either JUCE_LITTLE_ENDIAN or JUCE_BIG_ENDIAN.
    - Either JUCE_INTEL or JUCE_PPC
    - Either JUCE_GCC or JUCE_MSVC

    On the Mac, it also defines MACOS_10_2_OR_EARLIER if the build is targeting OSX10.2,
    and MACOS_10_3_OR_EARLIER if it is targeting either 10.2 or 10.3

    It also includes a set of macros for debug console output and assertions.

*/

#if (defined (_WIN32) || defined (_WIN64))
  #define       JUCE_WIN32 1
#else
  #if defined (LINUX) || defined (__linux__)
    #define     JUCE_LINUX 1
  #else
    #define     JUCE_MAC 1
  #endif
#endif

#if JUCE_WIN32
  #ifdef _MSC_VER
    #ifdef _WIN64
      #define JUCE_64BIT 1
    #else
      #define JUCE_32BIT 1
    #endif
  #endif

  #ifdef _DEBUG
    #define JUCE_DEBUG 1
  #endif

  /** If defined, this indicates that the processor is little-endian. */
  #define JUCE_LITTLE_ENDIAN 1

  #define JUCE_INTEL 1
#endif

#if JUCE_MAC

  #include <CoreFoundation/CoreFoundation.h>

  #ifndef NDEBUG
    #define JUCE_DEBUG 1
  #endif

  #ifdef __LITTLE_ENDIAN__
    #define JUCE_LITTLE_ENDIAN 1
  #else
    #define JUCE_BIG_ENDIAN 1
  #endif

  #if defined (__ppc__) || defined (__ppc64__)
    #define JUCE_PPC 1
  #else
    #define JUCE_INTEL 1
  #endif

  #ifdef __LP64__
    #define JUCE_64BIT 1
  #else
    #define JUCE_32BIT 1
  #endif

  #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3)
    #define MACOS_10_2_OR_EARLIER 1
  #endif

  #if (! defined (MAC_OS_X_VERSION_10_4)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_4)
    #define MACOS_10_3_OR_EARLIER 1
  #endif

  #if (! defined (MAC_OS_X_VERSION_10_5)) || (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5)
    #define MACOS_10_4_OR_EARLIER 1
  #endif
#endif

#if JUCE_LINUX

  #ifdef _DEBUG
    #define JUCE_DEBUG 1
  #endif

  // Allow override for big-endian Linux platforms
  #ifndef JUCE_BIG_ENDIAN
    #define JUCE_LITTLE_ENDIAN 1
  #endif

  #if defined (__LP64__) || defined (_LP64)
    #define JUCE_64BIT 1
  #else
    #define JUCE_32BIT 1
  #endif

  #define JUCE_INTEL 1
#endif

#ifdef JUCE_FORCE_DEBUG
  #undef JUCE_DEBUG

  #if JUCE_FORCE_DEBUG
    #define JUCE_DEBUG 1
  #endif
#endif

// Compiler type macros.

#ifdef __GNUC__
  #define JUCE_GCC 1
#elif defined (_MSC_VER)
  #define JUCE_MSVC 1

  #if _MSC_VER >= 1400
    #define JUCE_USE_INTRINSICS 1
  #endif
#else
  #error unknown compiler
#endif

/** This macro defines the C calling convention used as the standard for Juce calls. */
#if JUCE_MSVC
  #define JUCE_CALLTYPE             __stdcall
#else
  #define JUCE_CALLTYPE
#endif

// Debugging and assertion macros

// (For info about JUCE_LOG_ASSERTIONS, have a look in juce_Config.h)
#if JUCE_LOG_ASSERTIONS
  #define juce_LogCurrentAssertion    juce_LogAssertion (__FILE__, __LINE__);
#elif defined (JUCE_DEBUG)
  #define juce_LogCurrentAssertion    fprintf (stderr, "JUCE Assertion failure in %s, line %d\n", __FILE__, __LINE__);
#else
  #define juce_LogCurrentAssertion
#endif

#ifdef JUCE_DEBUG

  // If debugging is enabled..

  /** Writes a string to the standard error stream.

    This is only compiled in a debug build.

    @see Logger::outputDebugString
  */
  #define DBG(dbgtext)                  Logger::outputDebugString (dbgtext);

  /** Printf's a string to the standard error stream.

    This is only compiled in a debug build.

    @see Logger::outputDebugString
  */
  #define DBG_PRINTF(dbgprintf)         Logger::outputDebugPrintf dbgprintf;

  // Assertions..

  #if JUCE_WIN32 || DOXYGEN

    #if JUCE_USE_INTRINSICS
      #pragma intrinsic (__debugbreak)

      /** This will try to break the debugger if one is currently hosting this app.
          @see jassert()
      */
      #define juce_breakDebugger            __debugbreak();

    #elif JUCE_GCC
      /** This will try to break the debugger if one is currently hosting this app.
          @see jassert()
      */
      #define juce_breakDebugger            asm("int $3");
    #else
      /** This will try to break the debugger if one is currently hosting this app.
          @see jassert()
      */
      #define juce_breakDebugger            { __asm int 3 }
    #endif
  #elif JUCE_MAC
    #define juce_breakDebugger              Debugger();
  #elif JUCE_LINUX
    #define juce_breakDebugger              kill (0, SIGTRAP);
  #endif

  /** This will always cause an assertion failure.

      It is only compiled in a debug build, (unless JUCE_LOG_ASSERTIONS is enabled
      in juce_Config.h).

      @see jassert()
  */
  #define jassertfalse                  { juce_LogCurrentAssertion; if (JUCE_NAMESPACE::juce_isRunningUnderDebugger()) juce_breakDebugger; }

  /** Platform-independent assertion macro.

      This gets optimised out when not being built with debugging turned on.

      Be careful not to call any functions within its arguments that are vital to
      the behaviour of the program, because these won't get called in the release
      build.

      @see jassertfalse
  */
  #define jassert(expression)           { if (! (expression)) jassertfalse }

#else

  // If debugging is disabled, these dummy debug and assertion macros are used..

  #define DBG(dbgtext)
  #define DBG_PRINTF(dbgprintf)

  #define jassertfalse                  { juce_LogCurrentAssertion }

  #if JUCE_LOG_ASSERTIONS
    #define jassert(expression)         { if (! (expression)) jassertfalse }
  #else
    #define jassert(a)                  { }
  #endif

#endif

#ifndef DOXYGEN
  template <bool b> struct JuceStaticAssert;
  template <> struct JuceStaticAssert <true> { static void dummy() {} };
#endif

/** A compile-time assertion macro.

    If the expression parameter is false, the macro will cause a compile error.
*/
#define static_jassert(expression)      JuceStaticAssert<expression>::dummy();

#if JUCE_CATCH_UNHANDLED_EXCEPTIONS

  #define JUCE_TRY try

  /** Used in try-catch blocks, this macro will send exceptions to the JUCEApplication
      object so they can be logged by the application if it wants to.
  */
  #define JUCE_CATCH_EXCEPTION \
    catch (const std::exception& e)  \
    { \
        JUCEApplication::sendUnhandledException (&e, __FILE__, __LINE__); \
    } \
    catch (...) \
    { \
        JUCEApplication::sendUnhandledException (0, __FILE__, __LINE__); \
    }

  #define JUCE_CATCH_ALL            catch (...) {}
  #define JUCE_CATCH_ALL_ASSERT     catch (...) { jassertfalse }

#else

  #define JUCE_TRY
  #define JUCE_CATCH_EXCEPTION
  #define JUCE_CATCH_ALL
  #define JUCE_CATCH_ALL_ASSERT

#endif

// Macros for inlining.

#if JUCE_MSVC
  /** A platform-independent way of forcing an inline function.

      Use the syntax: @code
      forcedinline void myfunction (int x)
      @endcode
  */
  #ifdef JUCE_DEBUG
    #define forcedinline  __forceinline
  #else
    #define forcedinline  inline
  #endif

  /** A platform-independent way of stopping the compiler inlining a function.

      Use the syntax: @code
      juce_noinline void myfunction (int x)
      @endcode
  */
  #define juce_noinline

#else
  /** A platform-independent way of forcing an inline function.

      Use the syntax: @code
      forcedinline void myfunction (int x)
      @endcode
  */
  #ifndef JUCE_DEBUG
    #define forcedinline  inline __attribute__((always_inline))
  #else
    #define forcedinline  inline
  #endif

  /** A platform-independent way of stopping the compiler inlining a function.

      Use the syntax: @code
      juce_noinline void myfunction (int x)
      @endcode
  */
  #define juce_noinline __attribute__((noinline))

#endif

#endif   // __JUCE_PLATFORMDEFS_JUCEHEADER__
/********* End of inlined file: juce_PlatformDefs.h *********/

// Now we'll include any OS headers we need.. (at this point we are outside the Juce namespace).
#if JUCE_MSVC
  #pragma warning (push)
  #pragma warning (disable: 4514 4245 4100)
#endif

#include <cstdlib>
#include <cstdarg>
#include <climits>
#include <cmath>
#include <cwchar>
#include <stdexcept>
#include <typeinfo>
#include <cstring>
#include <cstdio>

#if JUCE_USE_INTRINSICS
  #include <intrin.h>
#endif

#if JUCE_MAC
  #if MACOS_10_3_OR_EARLIER
    #include <CoreServices/CoreServices.h>
  #else
    #include <libkern/OSAtomic.h>
  #endif
#endif

#if JUCE_LINUX
  #include <signal.h>
#endif

#if JUCE_MSVC && JUCE_DEBUG
  #include <crtdbg.h>
#endif

#if JUCE_MSVC
  #pragma warning (pop)
#endif

// DLL building settings on Win32
#if JUCE_MSVC
  #ifdef JUCE_DLL_BUILD
    #define JUCE_API __declspec (dllexport)
    #pragma warning (disable: 4251)
  #elif defined (JUCE_DLL)
    #define JUCE_API __declspec (dllimport)
    #pragma warning (disable: 4251)
  #endif
#elif defined (__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
  #ifdef JUCE_DLL_BUILD
    #define JUCE_API __attribute__ ((visibility("default")))
  #endif
#endif

#ifndef JUCE_API
  /** This macro is added to all juce public class declarations. */
  #define JUCE_API
#endif

/** This macro is added to all juce public function declarations. */
#define JUCE_PUBLIC_FUNCTION        JUCE_API JUCE_CALLTYPE

// Now include some basics that are needed by most of the Juce classes...
BEGIN_JUCE_NAMESPACE

extern bool JUCE_API JUCE_CALLTYPE juce_isRunningUnderDebugger() throw();

#if JUCE_LOG_ASSERTIONS
  extern void JUCE_API juce_LogAssertion (const char* filename, const int lineNum) throw();
#endif

/********* Start of inlined file: juce_Memory.h *********/
#ifndef __JUCE_MEMORY_JUCEHEADER__
#define __JUCE_MEMORY_JUCEHEADER__

/*
    This file defines the various juce_malloc(), juce_free() macros that should be used in
    preference to the standard calls.
*/

#if defined (JUCE_DEBUG) && JUCE_MSVC && JUCE_CHECK_MEMORY_LEAKS
  #ifndef JUCE_DLL

    // Win32 debug non-DLL versions..

    /** This should be used instead of calling malloc directly. */
    #define juce_malloc(numBytes)                 _malloc_dbg  (numBytes, _NORMAL_BLOCK, __FILE__, __LINE__)
    /** This should be used instead of calling calloc directly. */
    #define juce_calloc(numBytes)                 _calloc_dbg  (1, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__)
    /** This should be used instead of calling realloc directly. */
    #define juce_realloc(location, numBytes)      _realloc_dbg (location, numBytes, _NORMAL_BLOCK, __FILE__, __LINE__)
    /** This should be used instead of calling free directly. */
    #define juce_free(location)                   _free_dbg    (location, _NORMAL_BLOCK)

  #else

    // Win32 debug DLL versions..

    // For the DLL, we'll define some functions in the DLL that will be used for allocation - that
    // way all juce calls in the DLL and in the host API will all use the same allocator.
    extern JUCE_API void* juce_DebugMalloc (const int size, const char* file, const int line);
    extern JUCE_API void* juce_DebugCalloc (const int size, const char* file, const int line);
    extern JUCE_API void* juce_DebugRealloc (void* const block, const int size, const char* file, const int line);
    extern JUCE_API void juce_DebugFree (void* const block);

    /** This should be used instead of calling malloc directly. */
    #define juce_malloc(numBytes)                 JUCE_NAMESPACE::juce_DebugMalloc (numBytes, __FILE__, __LINE__)
    /** This should be used instead of calling calloc directly. */
    #define juce_calloc(numBytes)                 JUCE_NAMESPACE::juce_DebugCalloc (numBytes, __FILE__, __LINE__)
    /** This should be used instead of calling realloc directly. */
    #define juce_realloc(location, numBytes)      JUCE_NAMESPACE::juce_DebugRealloc (location, numBytes, __FILE__, __LINE__)
    /** This should be used instead of calling free directly. */
    #define juce_free(location)                   JUCE_NAMESPACE::juce_DebugFree (location)
  #endif

  #if ! defined (_AFXDLL)
    /** This macro can be added to classes to add extra debugging information to the memory
        allocated for them, so you can see the type of objects involved when there's a dump
        of leaked objects at program shutdown. (Only works on win32 at the moment).
    */
    #define juce_UseDebuggingNewOperator \
      static void* operator new (size_t sz)           { void* const p = juce_malloc ((int) sz); return (p != 0) ? p : ::operator new (sz); } \
      static void* operator new (size_t sz, void* p)  { return ::operator new (sz, p); } \
      static void operator delete (void* p)           { juce_free (p); }
  #endif

#elif defined (JUCE_DLL)

  // Win32 DLL (release) versions..

  // For the DLL, we'll define some functions in the DLL that will be used for allocation - that
  // way all juce calls in the DLL and in the host API will all use the same allocator.
  extern JUCE_API void* juce_Malloc (const int size);
  extern JUCE_API void* juce_Calloc (const int size);
  extern JUCE_API void* juce_Realloc (void* const block, const int size);
  extern JUCE_API void juce_Free (void* const block);

  /** This should be used instead of calling malloc directly. */
  #define juce_malloc(numBytes)                 JUCE_NAMESPACE::juce_Malloc (numBytes)
  /** This should be used instead of calling calloc directly. */
  #define juce_calloc(numBytes)                 JUCE_NAMESPACE::juce_Calloc (numBytes)
  /** This should be used instead of calling realloc directly. */
  #define juce_realloc(location, numBytes)      JUCE_NAMESPACE::juce_Realloc (location, numBytes)
  /** This should be used instead of calling free directly. */
  #define juce_free(location)                   JUCE_NAMESPACE::juce_Free (location)

  #define juce_UseDebuggingNewOperator \
    static void* operator new (size_t sz)           { void* const p = juce_malloc ((int) sz); return (p != 0) ? p : ::operator new (sz); } \
    static void* operator new (size_t sz, void* p)  { return ::operator new (sz, p); } \
    static void operator delete (void* p)           { juce_free (p); }

#else

  // Mac, Linux and Win32 (release) versions..

  /** This should be used instead of calling malloc directly. */
  #define juce_malloc(numBytes)                 malloc (numBytes)
  /** This should be used instead of calling calloc directly. */
  #define juce_calloc(numBytes)                 calloc (1, numBytes)
  /** This should be used instead of calling realloc directly. */
  #define juce_realloc(location, numBytes)      realloc (location, numBytes)
  /** This should be used instead of calling free directly. */
  #define juce_free(location)                   free (location)

#endif

/** This macro can be added to classes to add extra debugging information to the memory
    allocated for them, so you can see the type of objects involved when there's a dump
    of leaked objects at program shutdown. (Only works on win32 at the moment).

    Note that if you create a class that inherits from a class that uses this macro,
    your class must also use the macro, otherwise you'll probably get compile errors
    because of ambiguous new operators.

    Most of the JUCE classes use it, so see these for examples of where it should go.
*/
#ifndef juce_UseDebuggingNewOperator
  #define juce_UseDebuggingNewOperator
#endif

#if JUCE_MSVC
  /** This is a compiler-indenpendent way of declaring a variable as being thread-local.

      E.g.
      @code
      juce_ThreadLocal int myVariable;
      @endcode
  */
  #define juce_ThreadLocal    __declspec(thread)
#else
  #define juce_ThreadLocal    __thread
#endif

/** Clears a block of memory. */
#define zeromem(memory, numBytes)               memset (memory, 0, numBytes)

/** Clears a reference to a local structure. */
#define zerostruct(structure)                   memset (&structure, 0, sizeof (structure))

/** A handy macro that calls delete on a pointer if it's non-zero, and
    then sets the pointer to null.
*/
#define deleteAndZero(pointer)                  { delete (pointer); (pointer) = 0; }

#endif   // __JUCE_MEMORY_JUCEHEADER__
/********* End of inlined file: juce_Memory.h *********/

/********* Start of inlined file: juce_MathsFunctions.h *********/
#ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__
#define __JUCE_MATHSFUNCTIONS_JUCEHEADER__

/*
    This file sets up some handy mathematical typdefs and functions.
*/

// Definitions for the int8, int16, int32, int64 and pointer_sized_int types.

/** A platform-independent 8-bit signed integer type. */
typedef signed char                 int8;
/** A platform-independent 8-bit unsigned integer type. */
typedef unsigned char               uint8;
/** A platform-independent 16-bit signed integer type. */
typedef signed short                int16;
/** A platform-independent 16-bit unsigned integer type. */
typedef unsigned short              uint16;
/** A platform-independent 32-bit signed integer type. */
typedef signed int                  int32;
/** A platform-independent 32-bit unsigned integer type. */
typedef unsigned int                uint32;

#if JUCE_MSVC
  /** A platform-independent 64-bit integer type. */
  typedef __int64                   int64;
  /** A platform-independent 64-bit unsigned integer type. */
  typedef unsigned __int64          uint64;
  /** A platform-independent macro for writing 64-bit literals, needed because
      different compilers have different syntaxes for this.

      E.g. writing literal64bit (0x1000000000) will translate to 0x1000000000LL for
      GCC, or 0x1000000000 for MSVC.
  */
  #define literal64bit(longLiteral)     ((__int64) longLiteral)
#else
  /** A platform-independent 64-bit integer type. */
  typedef long long                 int64;
  /** A platform-independent 64-bit unsigned integer type. */
  typedef unsigned long long        uint64;
  /** A platform-independent macro for writing 64-bit literals, needed because
      different compilers have different syntaxes for this.

      E.g. writing literal64bit (0x1000000000) will translate to 0x1000000000LL for
      GCC, or 0x1000000000 for MSVC.
  */
  #define literal64bit(longLiteral)     (longLiteral##LL)
#endif

#if JUCE_64BIT
  /** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
  typedef int64                     pointer_sized_int;
  /** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
  typedef uint64                    pointer_sized_uint;
#elif _MSC_VER >= 1300
  /** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
  typedef _W64 int                  pointer_sized_int;
  /** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
  typedef _W64 unsigned int         pointer_sized_uint;
#else
  /** A signed integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
  typedef int                       pointer_sized_int;
  /** An unsigned integer type that's guaranteed to be large enough to hold a pointer without truncating it. */
  typedef unsigned int              pointer_sized_uint;
#endif

/** A platform-independent unicode character type. */
typedef wchar_t                     juce_wchar;

// Some indispensible min/max functions

/** Returns the larger of two values. */
forcedinline int    jmax (const int a, const int b) throw()                                   { return (a < b) ? b : a; }
/** Returns the larger of two values. */
forcedinline int64  jmax (const int64 a, const int64 b) throw()                               { return (a < b) ? b : a; }
/** Returns the larger of two values. */
forcedinline float  jmax (const float a, const float b) throw()                               { return (a < b) ? b : a; }
/** Returns the larger of two values. */
forcedinline double jmax (const double a, const double b) throw()                             { return (a < b) ? b : a; }

/** Returns the larger of three values. */
inline int    jmax (const int a, const int b, const int c) throw()                            { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }
/** Returns the larger of three values. */
inline int64  jmax (const int64 a, const int64 b, const int64 c) throw()                      { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }
/** Returns the larger of three values. */
inline float  jmax (const float a, const float b, const float c) throw()                      { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }
/** Returns the larger of three values. */
inline double jmax (const double a, const double b, const double c) throw()                   { return (a < b) ? ((b < c) ? c : b) : ((a < c) ? c : a); }

/** Returns the larger of four values. */
inline int    jmax (const int a, const int b, const int c, const int d) throw()               { return jmax (a, jmax (b, c, d)); }
/** Returns the larger of four values. */
inline int64  jmax (const int64 a, const int64 b, const int64 c, const int64 d) throw()       { return jmax (a, jmax (b, c, d)); }
/** Returns the larger of four values. */
inline float  jmax (const float a, const float b, const float c, const float d) throw()       { return jmax (a, jmax (b, c, d)); }
/** Returns the larger of four values. */
inline double jmax (const double a, const double b, const double c, const double d) throw()   { return jmax (a, jmax (b, c, d)); }

/** Returns the smaller of two values. */
inline int    jmin (const int a, const int b) throw()                                         { return (a > b) ? b : a; }
/** Returns the smaller of two values. */
inline int64  jmin (const int64 a, const int64 b) throw()                                     { return (a > b) ? b : a; }
/** Returns the smaller of two values. */
inline float  jmin (const float a, const float b) throw()                                     { return (a > b) ? b : a; }
/** Returns the smaller of two values. */
inline double jmin (const double a, const double b) throw()                                   { return (a > b) ? b : a; }

/** Returns the smaller of three values. */
inline int    jmin (const int a, const int b, const int c) throw()                            { return (a > b) ? ((b > c) ? c : b) : ((a > c) ? c : a); }
/** Returns the smaller of three values. */
inline int64  jmin (const int64 a, const int64 b, const int64 c) throw()                      { return (a > b) ? ((b > c) ? c : b) : ((a > c) ? c : a); }
/** Returns the smaller of three values. */
inline float  jmin (const float a, const float b, const float c) throw()                      { return (a > b) ? ((b > c) ? c : b) : ((a > c) ? c : a); }
/** Returns the smaller of three values. */
inline double jmin (const double a, const double b, const double c) throw()                   { return (a > b) ? ((b > c) ? c : b) : ((a > c) ? c : a); }

/** Returns the smaller of four values. */
inline int    jmin (const int a, const int b, const int c, const int d) throw()               { return jmin (a, jmin (b, c, d)); }
/** Returns the smaller of four values. */
inline int64  jmin (const int64 a, const int64 b, const int64 c, const int64 d) throw()       { return jmin (a, jmin (b, c, d)); }
/** Returns the smaller of four values. */
inline float  jmin (const float a, const float b, const float c, const float d) throw()       { return jmin (a, jmin (b, c, d)); }
/** Returns the smaller of four values. */
inline double jmin (const double a, const double b, const double c, const double d) throw()   { return jmin (a, jmin (b, c, d)); }

/** Constrains a value to keep it within a given range.

    This will check that the specified value lies between the lower and upper bounds
    specified, and if not, will return the nearest value that would be in-range. Effectively,
    it's like calling jmax (lowerLimit, jmin (upperLimit, value)).

    Note that it expects that lowerLimit <= upperLimit. If this isn't true,
    the results will be unpredictable.

    @param lowerLimit           the minimum value to return
    @param upperLimit           the maximum value to return
    @param valueToConstrain     the value to try to return
    @returns    the closest value to valueToConstrain which lies between lowerLimit
                and upperLimit (inclusive)
    @see jlimit0To, jmin, jmax
*/
template <class Type>
inline Type jlimit (const Type lowerLimit,
                    const Type upperLimit,
                    const Type valueToConstrain) throw()
{
    jassert (lowerLimit <= upperLimit); // if these are in the wrong order, results are unpredictable..

    return (valueToConstrain < lowerLimit) ? lowerLimit
                                           : ((valueToConstrain > upperLimit) ? upperLimit
                                                                              : valueToConstrain);
}

/** Handy function to swap two values over.
*/
template <class Type>
inline void swapVariables (Type& variable1, Type& variable2) throw()
{
    const Type tempVal = variable1;
    variable1 = variable2;
    variable2 = tempVal;
}

/** Handy macro for getting the number of elements in a simple const C array.

    E.g.
    @code
    static int myArray[] = { 1, 2, 3 };

    int numElements = numElementsInArray (myArray) // returns 3
    @endcode
*/
#define numElementsInArray(a)   ((int) (sizeof (a) / sizeof ((a)[0])))

// Some useful maths functions that aren't always present with all compilers and build settings.

#if JUCE_WIN32 || defined (DOXYGEN)
  /** Using juce_hypot and juce_hypotf is easier than dealing with all the different
      versions of these functions of various platforms and compilers. */
  forcedinline double juce_hypot (double a, double b)           { return _hypot (a, b); }

  /** Using juce_hypot and juce_hypotf is easier than dealing with all the different
      versions of these functions of various platforms and compilers. */
  forcedinline float juce_hypotf (float a, float b)             { return (float) _hypot (a, b); }
#elif MACOS_10_2_OR_EARLIER
  /** Using juce_hypot and juce_hypotf is easier than dealing with all the different
      versions of these functions of various platforms and compilers. */
  forcedinline double juce_hypot (double a, double b)           { return hypot (a, b); }

  /** Using juce_hypot and juce_hypotf is easier than dealing with all the different
      versions of these functions of various platforms and compilers. */
  forcedinline float juce_hypotf (float a, float b)             { return (float) hypot (a, b); }
  forcedinline float sinf (const float a)                       { return (float) sin (a); }
  forcedinline float cosf (const float a)                       { return (float) cos (a); }
  forcedinline float tanf (const float a)                       { return (float) tan (a); }
  forcedinline float atan2f (const float a, const float b)      { return (float) atan2 (a, b); }
  forcedinline float sqrtf (const float a)                      { return (float) sqrt (a); }
  forcedinline float logf (const float a)                       { return (float) log (a); }
  forcedinline float powf (const float a, const float b)        { return (float) pow (a, b); }
  forcedinline float expf (const float a)                       { return (float) exp (a); }
#else
  /** Using juce_hypot and juce_hypotf is easier than dealing with all the different
      versions of these functions of various platforms and compilers. */
  forcedinline double juce_hypot (double a, double b)           { return hypot (a, b); }

  /** Using juce_hypot and juce_hypotf is easier than dealing with all the different
      versions of these functions of various platforms and compilers. */
  forcedinline float juce_hypotf (float a, float b)             { return hypotf (a, b); }
#endif

inline int64 abs64 (const int64 n) throw()                      { return (n >= 0) ? n : -n; }

/** A predefined value for Pi, at double-precision.

    @see float_Pi
*/
const double  double_Pi  = 3.1415926535897932384626433832795;

/** A predefined value for Pi, at sngle-precision.

    @see double_Pi
*/
const float   float_Pi   = 3.14159265358979323846f;

/** The isfinite() method seems to vary greatly between platforms, so this is a
    platform-independent macro for it.
*/
#if JUCE_LINUX
  #define juce_isfinite(v)      std::isfinite(v)
#elif JUCE_MAC
  #if MACOS_10_2_OR_EARLIER
    #define juce_isfinite(v)    __isfinite(v)
  #elif MACOS_10_3_OR_EARLIER
    #ifdef isfinite
      #define juce_isfinite(v)    isfinite(v)
    #else
      // no idea why the isfinite macro is sometimes impossible to include, so just copy the built-in one..
      static __inline__ int juce_isfinite (double __x) { return __x == __x && __builtin_fabs (__x) != __builtin_inf(); }
    #endif
  #else
    #define juce_isfinite(v)    std::isfinite(v)
  #endif
#elif JUCE_WIN32 && ! defined (isfinite)
  #define juce_isfinite(v)      _finite(v)
#else
  #define juce_isfinite(v)      isfinite(v)
#endif

#endif   // __JUCE_MATHSFUNCTIONS_JUCEHEADER__
/********* End of inlined file: juce_MathsFunctions.h *********/

/********* Start of inlined file: juce_DataConversions.h *********/
#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__
#define __JUCE_DATACONVERSIONS_JUCEHEADER__

#if JUCE_USE_INTRINSICS
  #pragma intrinsic (_byteswap_ulong)
#endif

// Endianness conversions..

/** Swaps the byte-order in an integer from little to big-endianness or vice-versa. */
forcedinline uint32 swapByteOrder (uint32 n) throw()
{
#if JUCE_MAC
    // Mac version
    return CFSwapInt32 (n);
#elif JUCE_GCC
    // Inpenetrable GCC version..
    asm("bswap %%eax" : "=a"(n) : "a"(n));
    return n;
#elif JUCE_USE_INTRINSICS
    // Win32 intrinsics version..
    return _byteswap_ulong (n);
#else
    // Win32 version..
    __asm {
        mov eax, n
        bswap eax
        mov n, eax
    }
    return n;
#endif
}

/** Swaps the byte-order of a 16-bit short. */
inline uint16 swapByteOrder (const uint16 n) throw()
{
#if JUCE_USE_INTRINSICSxxx // agh - the MS compiler has an internal error when you try to use this intrinsic!
    // Win32 intrinsics version..
    return (uint16) _byteswap_ushort (n);
#else
    return (uint16) ((n << 8) | (n >> 8));
#endif
}

inline uint64 swapByteOrder (const uint64 value) throw()
{
#if JUCE_MAC
    return CFSwapInt64 (value);
#elif JUCE_USE_INTRINSICS
    return _byteswap_uint64 (value);
#else
    return (((int64) swapByteOrder ((uint32) value)) << 32)
            | swapByteOrder ((uint32) (value >> 32));
#endif
}

#if JUCE_LITTLE_ENDIAN
  /** Swaps the byte order of a 16-bit int if the CPU is big-endian */
  inline uint16     swapIfBigEndian (const uint16 v) throw()             { return v; }
  /** Swaps the byte order of a 32-bit int if the CPU is big-endian */
  inline uint32     swapIfBigEndian (const uint32 v) throw()             { return v; }
  /** Swaps the byte order of a 64-bit int if the CPU is big-endian */
  inline uint64     swapIfBigEndian (const uint64 v) throw()             { return v; }

  /** Swaps the byte order of a 16-bit int if the CPU is little-endian */
  inline uint16     swapIfLittleEndian (const uint16 v) throw()          { return swapByteOrder (v); }
  /** Swaps the byte order of a 32-bit int if the CPU is little-endian */
  inline uint32     swapIfLittleEndian (const uint32 v) throw()          { return swapByteOrder (v); }
  /** Swaps the byte order of a 64-bit int if the CPU is little-endian */
  inline uint64     swapIfLittleEndian (const uint64 v) throw()          { return swapByteOrder (v); }

  /** Turns 4 bytes into a little-endian integer. */
  inline uint32     littleEndianInt (const char* const bytes) throw()    { return *(uint32*) bytes; }
  /** Turns 2 bytes into a little-endian integer. */
  inline uint16     littleEndianShort (const char* const bytes) throw()  { return *(uint16*) bytes; }

  /** Turns 4 bytes into a big-endian integer. */
  inline uint32     bigEndianInt (const char* const bytes) throw()       { return swapByteOrder (*(uint32*) bytes); }
  /** Turns 2 bytes into a big-endian integer. */
  inline uint16     bigEndianShort (const char* const bytes) throw()     { return swapByteOrder (*(uint16*) bytes); }

#else
  /** Swaps the byte order of a 16-bit int if the CPU is big-endian */
  inline uint16     swapIfBigEndian (const uint16 v) throw()             { return swapByteOrder (v); }
  /** Swaps the byte order of a 32-bit int if the CPU is big-endian */
  inline uint32     swapIfBigEndian (const uint32 v) throw()             { return swapByteOrder (v); }
  /** Swaps the byte order of a 64-bit int if the CPU is big-endian */
  inline uint64     swapIfBigEndian (const uint64 v) throw()             { return swapByteOrder (v); }

  /** Swaps the byte order of a 16-bit int if the CPU is little-endian */
  inline uint16     swapIfLittleEndian (const uint16 v) throw()          { return v; }
  /** Swaps the byte order of a 32-bit int if the CPU is little-endian */
  inline uint32     swapIfLittleEndian (const uint32 v) throw()          { return v; }
  /** Swaps the byte order of a 64-bit int if the CPU is little-endian */
  inline uint64     swapIfLittleEndian (const uint64 v) throw()          { return v; }

  /** Turns 4 bytes into a little-endian integer. */
  inline uint32     littleEndianInt (const char* const bytes) throw()    { return swapByteOrder (*(uint32*) bytes); }
  /** Turns 2 bytes into a little-endian integer. */
  inline uint16     littleEndianShort (const char* const bytes) throw()  { return swapByteOrder (*(uint16*) bytes); }

  /** Turns 4 bytes into a big-endian integer. */
  inline uint32     bigEndianInt (const char* const bytes) throw()       { return *(uint32*) bytes; }
  /** Turns 2 bytes into a big-endian integer. */
  inline uint16     bigEndianShort (const char* const bytes) throw()     { return *(uint16*) bytes; }
#endif

/** Converts 3 little-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
inline int littleEndian24Bit (const char* const bytes) throw()                          { return (((int) bytes[2]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[0]); }
/** Converts 3 big-endian bytes into a signed 24-bit value (which is sign-extended to 32 bits). */
inline int bigEndian24Bit (const char* const bytes) throw()                             { return (((int) bytes[0]) << 16) | (((uint32) (uint8) bytes[1]) << 8) | ((uint32) (uint8) bytes[2]); }

/** Copies a 24-bit number to 3 little-endian bytes. */
inline void littleEndian24BitToChars (const int value, char* const destBytes) throw()   { destBytes[0] = (char)(value & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)((value >> 16) & 0xff); }
/** Copies a 24-bit number to 3 big-endian bytes. */
inline void bigEndian24BitToChars (const int value, char* const destBytes) throw()      { destBytes[0] = (char)((value >> 16) & 0xff); destBytes[1] = (char)((value >> 8) & 0xff); destBytes[2] = (char)(value & 0xff); }

/** Fast floating-point-to-integer conversion.

    This is faster than using the normal c++ cast to convert a double to an int, and
    it will round the value to the nearest integer, rather than rounding it down
    like the normal cast does.

    Note that this routine gets its speed at the expense of some accuracy, and when
    rounding values whose floating point component is exactly 0.5, odd numbers and
    even numbers will be rounded up or down differently. For a more accurate conversion,
    see roundDoubleToIntAccurate().
*/
inline int roundDoubleToInt (const double value) throw()
{
    union { int asInt[2]; double asDouble; } n;
    n.asDouble = value + 6755399441055744.0;

#if JUCE_BIG_ENDIAN
    return n.asInt [1];
#else
    return n.asInt [0];
#endif
}

/** Fast floating-point-to-integer conversion.

    This is a slightly slower and slightly more accurate version of roundDoubleToInt(). It works
    fine for values above zero, but negative numbers are rounded the wrong way.
*/
inline int roundDoubleToIntAccurate (const double value) throw()
{
    return roundDoubleToInt (value + 1.5e-8);
}

/** Fast floating-point-to-integer conversion.

    This is faster than using the normal c++ cast to convert a float to an int, and
    it will round the value to the nearest integer, rather than rounding it down
    like the normal cast does.

    Note that this routine gets its speed at the expense of some accuracy, and when
    rounding values whose floating point component is exactly 0.5, odd numbers and
    even numbers will be rounded up or down differently.
*/
inline int roundFloatToInt (const float value) throw()
{
    union { int asInt[2]; double asDouble; } n;
    n.asDouble = value + 6755399441055744.0;

#if JUCE_BIG_ENDIAN
    return n.asInt [1];
#else
    return n.asInt [0];
#endif
}

#endif   // __JUCE_DATACONVERSIONS_JUCEHEADER__
/********* End of inlined file: juce_DataConversions.h *********/

/********* Start of inlined file: juce_Logger.h *********/
#ifndef __JUCE_LOGGER_JUCEHEADER__
#define __JUCE_LOGGER_JUCEHEADER__

/********* Start of inlined file: juce_String.h *********/
#ifndef __JUCE_STRING_JUCEHEADER__
#define __JUCE_STRING_JUCEHEADER__

/********* Start of inlined file: juce_CharacterFunctions.h *********/
#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__
#define __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__

/* The String class can either use wchar_t unicode characters, or 8-bit characters
   (in the default system encoding) as its internal representation.

   To use unicode, define the JUCE_STRINGS_ARE_UNICODE macro in juce_Config.h

   Be sure to use "tchar" for characters rather than "char", and always wrap string
   literals in the T("abcd") macro, so that it all works nicely either way round.
*/
#if JUCE_STRINGS_ARE_UNICODE

  #define JUCE_T(stringLiteral)     (L##stringLiteral)
  typedef juce_wchar                tchar;
  #define juce_tcharToWideChar(c)   (c)

#else

  #define JUCE_T(stringLiteral)     (stringLiteral)
  typedef char                      tchar;
  #define juce_tcharToWideChar(c)   ((juce_wchar) (unsigned char) (c))

#endif

#if ! JUCE_DONT_DEFINE_MACROS

/** The 'T' macro allows a literal string to be compiled using either 8-bit characters
    or unicode.

    If you write your string literals in the form T("xyz"), this will either be compiled
    as "xyz" for non-unicode builds, or L"xyz" for unicode builds, depending on whether the
    JUCE_STRINGS_ARE_UNICODE macro has been set in juce_Config.h

    Because the 'T' symbol is occasionally used inside 3rd-party library headers which you
    may need to include after juce.h, you can use the juce_withoutMacros.h file (in
    the juce/src directory) to avoid defining this macro. See the comments in
    juce_withoutMacros.h for more info.
*/
#define T(stringLiteral)            JUCE_T(stringLiteral)

#endif

/**
    A set of methods for manipulating characters and character strings, with
    duplicate methods to handle 8-bit and unicode characters.

    These are defined as wrappers around the basic C string handlers, to provide
    a clean, cross-platform layer, (because various platforms differ in the
    range of C library calls that they provide).

    @see String
*/
class JUCE_API  CharacterFunctions
{
public:
    static int length (const char* const s) throw();
    static int length (const juce_wchar* const s) throw();

    static void copy (char* dest, const char* src, const int maxBytes) throw();
    static void copy (juce_wchar* dest, const juce_wchar* src, const int maxChars) throw();

    static void copy (juce_wchar* dest, const char* src, const int maxChars) throw();
    static void copy (char* dest, const juce_wchar* src, const int maxBytes) throw();
    static int bytesRequiredForCopy (const juce_wchar* src) throw();

    static void append (char* dest, const char* src) throw();
    static void append (juce_wchar* dest, const juce_wchar* src) throw();

    static int compare (const char* const s1, const char* const s2) throw();
    static int compare (const juce_wchar* s1, const juce_wchar* s2) throw();

    static int compare (const char* const s1, const char* const s2, const int maxChars) throw();
    static int compare (const juce_wchar* s1, const juce_wchar* s2, int maxChars) throw();

    static int compareIgnoreCase (const char* const s1, const char* const s2) throw();
    static int compareIgnoreCase (const juce_wchar* s1, const juce_wchar* s2) throw();

    static int compareIgnoreCase (const char* const s1, const char* const s2, const int maxChars) throw();
    static int compareIgnoreCase (const juce_wchar* s1, const juce_wchar* s2, int maxChars) throw();

    static const char* find (const char* const haystack, const char* const needle) throw();
    static const juce_wchar* find (const juce_wchar* haystack, const juce_wchar* const needle) throw();

    static int indexOfChar (const char* const haystack, const char needle, const bool ignoreCase) throw();
    static int indexOfChar (const juce_wchar* const haystack, const juce_wchar needle, const bool ignoreCase) throw();

    static int indexOfCharFast (const char* const haystack, const char needle) throw();
    static int indexOfCharFast (const juce_wchar* const haystack, const juce_wchar needle) throw();

    static int getIntialSectionContainingOnly (const char* const text, const char* const allowedChars) throw();
    static int getIntialSectionContainingOnly (const juce_wchar* const text, const juce_wchar* const allowedChars) throw();

    static int ftime (char* const dest, const int maxChars, const char* const format, const struct tm* const tm) throw();
    static int ftime (juce_wchar* const dest, const int maxChars, const juce_wchar* const format, const struct tm* const tm) throw();

    static int getIntValue (const char* const s) throw();
    static int getIntValue (const juce_wchar* s) throw();

    static int64 getInt64Value (const char* s) throw();
    static int64 getInt64Value (const juce_wchar* s) throw();

    static double getDoubleValue (const char* const s) throw();
    static double getDoubleValue (const juce_wchar* const s) throw();

    static char toUpperCase (const char character) throw();
    static juce_wchar toUpperCase (const juce_wchar character) throw();
    static void toUpperCase (char* s) throw();

    static void toUpperCase (juce_wchar* s) throw();
    static bool isUpperCase (const char character) throw();
    static bool isUpperCase (const juce_wchar character) throw();

    static char toLowerCase (const char character) throw();
    static juce_wchar toLowerCase (const juce_wchar character) throw();
    static void toLowerCase (char* s) throw();
    static void toLowerCase (juce_wchar* s) throw();
    static bool isLowerCase (const char character) throw();
    static bool isLowerCase (const juce_wchar character) throw();

    static bool isWhitespace (const char character) throw();
    static bool isWhitespace (const juce_wchar character) throw();

    static bool isDigit (const char character) throw();
    static bool isDigit (const juce_wchar character) throw();

    static bool isLetter (const char character) throw();
    static bool isLetter (const juce_wchar character) throw();

    static bool isLetterOrDigit (const char character) throw();
    static bool isLetterOrDigit (const juce_wchar character) throw();

    /** Returns 0 to 16 for '0' to 'F", or -1 for characters that aren't a legel
        hex digit.
    */
    static int getHexDigitValue (const tchar digit) throw();

    static int printf (char* const dest, const int maxLength, const char* const format, ...) throw();
    static int printf (juce_wchar* const dest, const int maxLength, const juce_wchar* const format, ...) throw();

    static int vprintf (char* const dest, const int maxLength, const char* const format, va_list& args) throw();
    static int vprintf (juce_wchar* const dest, const int maxLength, const juce_wchar* const format, va_list& args) throw();
};

#endif   // __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__
/********* End of inlined file: juce_CharacterFunctions.h *********/

/**
    The JUCE String class!

    Using a reference-counted internal representation, these strings are fast
    and efficient, and there are methods to do just about any operation you'll ever
    dream of.

    @see StringArray, StringPairArray
*/
class JUCE_API  String
{
public:

    /** Creates an empty string.

        @see empty
    */
    String() throw();

    /** Creates a copy of another string. */
    String (const String& other) throw();

    /** Creates a string from a zero-terminated text string.

        The string is assumed to be stored in the default system encoding.
    */
    String (const char* const text) throw();

    /** Creates a string from an string of characters.

        This will use up the the first maxChars characters of the string (or
        less if the string is actually shorter)
    */
    String (const char* const text,
            const int maxChars) throw();

    /** Creates a string from a zero-terminated unicode text string. */
    String (const juce_wchar* const unicodeText) throw();

    /** Creates a string from a unicode text string.

        This will use up the the first maxChars characters of the string (or
        less if the string is actually shorter)
    */
    String (const juce_wchar* const unicodeText,
            const int maxChars) throw();

    /** Creates a string from a single character. */
    static const String charToString (const tchar character) throw();

    /** Destructor. */
    ~String() throw();

    /** This is an empty string that can be used whenever one is needed.

        It's better to use this than String() because it explains what's going on
        and is more efficient.
    */
    static const String empty;

    /** Generates a probably-unique 32-bit hashcode from this string. */
    int hashCode() const throw();

    /** Generates a probably-unique 64-bit hashcode from this string. */
    int64 hashCode64() const throw();

    /** Returns the number of characters in the string. */
    int length() const throw();

    // Assignment and concatenation operators..

    /** Replaces this string's contents with another string. */
    const String& operator= (const tchar* const other) throw();

    /** Replaces this string's contents with another string. */
    const String& operator= (const String& other) throw();

    /** Appends another string at the end of this one. */
    const String& operator+= (const tchar* const textToAppend) throw();
    /** Appends another string at the end of this one. */
    const String& operator+= (const String& stringToAppend) throw();
    /** Appends a character at the end of this string. */
    const String& operator+= (const char characterToAppend) throw();
    /** Appends a character at the end of this string. */
    const String& operator+= (const juce_wchar characterToAppend) throw();

    /** Appends a string at the end of this one.

        @param textToAppend     the string to add
        @param maxCharsToTake   the maximum number of characters to take from the string passed in
    */
    void append (const tchar* const textToAppend,
                 const int maxCharsToTake) throw();

    /** Appends a string at the end of this one.
        @returns     the concatenated string
    */
    const String operator+ (const String& stringToAppend) const throw();

    /** Appends a string at the end of this one.
        @returns     the concatenated string
    */
    const String operator+ (const tchar* const textToAppend) const throw();

    /** Appends a character at the end of this one.
        @returns     the concatenated string
    */
    const String operator+ (const tchar characterToAppend) const throw();

    /** Appends a character at the end of this string. */
    String& operator<< (const char n) throw();
    /** Appends a character at the end of this string. */
    String& operator<< (const juce_wchar n) throw();
    /** Appends another string at the end of this one. */
    String& operator<< (const char* const text) throw();
    /** Appends another string at the end of this one. */
    String& operator<< (const juce_wchar* const text) throw();
    /** Appends another string at the end of this one. */
    String& operator<< (const String& text) throw();

    /** Appends a decimal number at the end of this string. */
    String& operator<< (const short number) throw();
    /** Appends a decimal number at the end of this string. */
    String& operator<< (const int number) throw();
    /** Appends a decimal number at the end of this string. */
    String& operator<< (const unsigned int number) throw();
    /** Appends a decimal number at the end of this string. */
    String& operator<< (const float number) throw();
    /** Appends a decimal number at the end of this string. */
    String& operator<< (const double number) throw();

    // Comparison methods..

    /** Returns true if the string contains no characters.

        Note that there's also an isNotEmpty() method to help write readable code.

        @see containsNonWhitespaceChars()
    */
    inline bool isEmpty() const throw()                     { return text->text[0] == 0; }

    /** Returns true if the string contains at least one character.

        Note that there's also an isEmpty() method to help write readable code.

        @see containsNonWhitespaceChars()
    */
    inline bool isNotEmpty() const throw()                  { return text->text[0] != 0; }

    /** Case-sensitive comparison with another string. */
    bool operator== (const String& other) const throw();
    /** Case-sensitive comparison with another string. */
    bool operator== (const tchar* const other) const throw();

    /** Case-sensitive comparison with another string. */
    bool operator!= (const String& other) const throw();
    /** Case-sensitive comparison with another string. */
    bool operator!= (const tchar* const other) const throw();

    /** Case-insensitive comparison with another string. */
    bool equalsIgnoreCase (const String& other) const throw();
    /** Case-insensitive comparison with another string. */
    bool equalsIgnoreCase (const tchar* const other) const throw();

    /** Case-sensitive comparison with another string. */
    bool operator> (const String& other) const throw();
    /** Case-sensitive comparison with another string. */
    bool operator< (const tchar* const other) const throw();

    /** Case-sensitive comparison with another string. */
    bool operator>= (const String& other) const throw();
    /** Case-sensitive comparison with another string. */
    bool operator<= (const tchar* const other) const throw();

    /** Case-sensitive comparison with another string.
        @returns     0 if the two strings are identical; negative if this string
                     comes before the other one alphabetically, or positive if it
                     comes after it.
    */
    int compare (const tchar* const other) const throw();

    /** Case-insensitive comparison with another string.
        @returns     0 if the two strings are identical; negative if this string
                     comes before the other one alphabetically, or positive if it
                     comes after it.
    */
    int compareIgnoreCase (const tchar* const other) const throw();

    /** Lexicographic comparison with another string.

        The comparison used here is case-insensitive and ignores leading non-alphanumeric
        characters, making it good for sorting human-readable strings.

        @returns     0 if the two strings are identical; negative if this string
                     comes before the other one alphabetically, or positive if it
                     comes after it.
    */
    int compareLexicographically (const tchar* const other) const throw();

    /** Tests whether the string begins with another string.

        Uses a case-sensitive comparison.
    */
    bool startsWith (const tchar* const text) const throw();

    /** Tests whether the string begins with a particular character.

        Uses a case-sensitive comparison.
    */
    bool startsWithChar (const tchar character) const throw();

    /** Tests whether the string begins with another string.

        Uses a case-insensitive comparison.
    */
    bool startsWithIgnoreCase (const tchar* const text) const throw();

    /** Tests whether the string ends with another string.

        Uses a case-sensitive comparison.
    */
    bool endsWith (const tchar* const text) const throw();

    /** Tests whether the string ends with a particular character.

        Uses a case-sensitive comparison.
    */
    bool endsWithChar (const tchar character) const throw();

    /** Tests whether the string ends with another string.

        Uses a case-insensitive comparison.
    */
    bool endsWithIgnoreCase (const tchar* const text) const throw();

    /** Tests whether the string contains another substring.

        Uses a case-sensitive comparison.
    */
    bool contains (const tchar* const text) const throw();

    /** Tests whether the string contains a particular character.

        Uses a case-sensitive comparison.
    */
    bool containsChar (const tchar character) const throw();

    /** Tests whether the string contains another substring.

        Uses a case-insensitive comparison.
    */
    bool containsIgnoreCase (const tchar* const text) const throw();

    /** Tests whether the string contains another substring as a distict word.

        @returns    true if the string contains this word, surrounded by
                    non-alphanumeric characters
        @see indexOfWholeWord, containsWholeWordIgnoreCase
    */
    bool containsWholeWord (const tchar* const wordToLookFor) const throw();

    /** Tests whether the string contains another substring as a distict word.

        @returns    true if the string contains this word, surrounded by
                    non-alphanumeric characters
        @see indexOfWholeWordIgnoreCase, containsWholeWord
    */
    bool containsWholeWordIgnoreCase (const tchar* const wordToLookFor) const throw();

    /** Finds an instance of another substring if it exists as a distict word.

        @returns    if the string contains this word, surrounded by non-alphanumeric characters,
                    then this will return the index of the start of the substring. If it isn't
                    found, then it will return -1
        @see indexOfWholeWordIgnoreCase, containsWholeWord
    */
    int indexOfWholeWord (const tchar* const wordToLookFor) const throw();

    /** Finds an instance of another substring if it exists as a distict word.

        @returns    if the string contains this word, surrounded by non-alphanumeric characters,
                    then this will return the index of the start of the substring. If it isn't
                    found, then it will return -1
        @see indexOfWholeWord, containsWholeWordIgnoreCase
    */
    int indexOfWholeWordIgnoreCase (const tchar* const wordToLookFor) const throw();

    /** Looks for any of a set of characters in the string.

        Uses a case-sensitive comparison.

        @returns    true if the string contains any of the characters from
                    the string that is passed in.
    */
    bool containsAnyOf (const tchar* const charactersItMightContain) const throw();

    /** Looks for a set of characters in the string.

        Uses a case-sensitive comparison.

        @returns    true if the all the characters in the string are also found in the
                    string that is passed in.
    */
    bool containsOnly (const tchar* const charactersItMightContain) const throw();

    /** Returns true if this string contains any non-whitespace characters.

        This will return false if the string contains only whitespace characters, or
        if it's empty.

        It is equivalent to calling "myString.trim().isNotEmpty()".
    */
    bool containsNonWhitespaceChars() const throw();

    /** Returns true if the string matches this simple wildcard expression.

        So for example String ("abcdef").matchesWildcard ("*DEF", true) would return true.

        This isn't a full-blown regex though! The only wildcard characters supported
        are "*" and "?". It's mainly intended for filename pattern matching.
    */
    bool matchesWildcard (const tchar* wildcard, const bool ignoreCase) const throw();

    // Substring location methods..

    /** Searches for a character inside this string.

        Uses a case-sensitive comparison.

        @returns    the index of the first occurrence of the character in this
                    string, or -1 if it's not found.
    */
    int indexOfChar (const tchar characterToLookFor) const throw();

    /** Searches for a character inside this string.

        Uses a case-sensitive comparison.

        @param startIndex           the index from which the search should proceed
        @param characterToLookFor   the character to look for
        @returns            the index of the first occurrence of the character in this
                            string, or -1 if it's not found.
    */
    int indexOfChar (const int startIndex, const tchar characterToLookFor) const throw();

    /** Returns the index of the first character that matches one of the characters
        passed-in to this method.

        This scans the string, beginning from the startIndex supplied, and if it finds
        a character that appears in the string charactersToLookFor, it returns its index.

        If none of these characters are found, it returns -1.

        If ignoreCase is true, the comparison will be case-insensitive.

        @see indexOfChar, lastIndexOfAnyOf
    */
    int indexOfAnyOf (const tchar* const charactersToLookFor,
                      const int startIndex = 0,
                      const bool ignoreCase = false) const throw();

    /** Searches for a substring within this string.

        Uses a case-sensitive comparison.

        @returns    the index of the first occurrence of this substring, or -1 if it's not found.
    */
    int indexOf (const tchar* const text) const throw();

    /** Searches for a substring within this string.

        Uses a case-sensitive comparison.

        @param startIndex       the index from which the search should proceed
        @param textToLookFor    the string to search for
        @returns                the index of the first occurrence of this substring, or -1 if it's not found.
    */
    int indexOf (const int startIndex,
                 const tchar* const textToLookFor) const throw();

    /** Searches for a substring within this string.

        Uses a case-insensitive comparison.

        @returns    the index of the first occurrence of this substring, or -1 if it's not found.
    */
    int indexOfIgnoreCase (const tchar* const textToLookFor) const throw();

    /** Searches for a substring within this string.

        Uses a case-insensitive comparison.

        @param startIndex       the index from which the search should proceed
        @param textToLookFor    the string to search for
        @returns                the index of the first occurrence of this substring, or -1 if it's not found.
    */
    int indexOfIgnoreCase (const int startIndex,
                           const tchar* const textToLookFor) const throw();

    /** Searches for a character inside this string (working backwards from the end of the string).

        Uses a case-sensitive comparison.

        @returns            the index of the last occurrence of the character in this
                            string, or -1 if it's not found.
    */
    int lastIndexOfChar (const tchar character) const throw();

    /** Searches for a substring inside this string (working backwards from the end of the string).

        Uses a case-sensitive comparison.

        @returns            the index of the start of the last occurrence of the
                            substring within this string, or -1 if it's not found.
    */
    int lastIndexOf (const tchar* const textToLookFor) const throw();

    /** Searches for a substring inside this string (working backwards from the end of the string).

        Uses a case-insensitive comparison.

        @returns            the index of the start of the last occurrence of the
                            substring within this string, or -1 if it's not found.
    */
    int lastIndexOfIgnoreCase (const tchar* const textToLookFor) const throw();

    /** Returns the index of the last character in this string that matches one of the
        characters passed-in to this method.

        This scans the string backwards, starting from its end, and if it finds
        a character that appears in the string charactersToLookFor, it returns its index.

        If none of these characters are found, it returns -1.

        If ignoreCase is true, the comparison will be case-insensitive.

        @see lastIndexOf, indexOfAnyOf
    */
    int lastIndexOfAnyOf (const tchar* const charactersToLookFor,
                          const bool ignoreCase = false) const throw();

    // Substring extraction and manipulation methods..

    /** Returns the character at this index in the string.

        No checks are made to see if the index is within a valid range, so be careful!
    */
    inline const tchar& operator[] (const int index) const throw()  { jassert (((unsigned int) index) <= (unsigned int) length()); return text->text [index]; }

    /** Returns a character from the string such that it can also be altered.

        This can be used as a way of easily changing characters in the string.

        Note that the index passed-in is not checked to see whether it's in-range, so
        be careful when using this.
    */
    tchar& operator[] (const int index) throw();

    /** Returns the final character of the string.

        If the string is empty this will return 0.
    */
    tchar getLastCharacter() const throw();

    /** Returns a subsection of the string.

        If the range specified is beyond the limits of the string, as much as
        possible is returned.

        @param startIndex   the index of the start of the substring needed
        @param endIndex     all characters from startIndex up to (but not including)
                            this index are returned
        @see fromFirstOccurrenceOf, dropLastCharacters, upToFirstOccurrenceOf
    */
    const String substring (int startIndex,
                            int endIndex) const throw();

    /** Returns a section of the string, starting from a given position.

        @param startIndex   the first character to include. If this is beyond the end
                            of the string, an empty string is returned. If it is zero or
                            less, the whole string is returned.
        @returns            the substring from startIndex up to the end of the string
        @see dropLastCharacters, fromFirstOccurrenceOf, upToFirstOccurrenceOf, fromLastOccurrenceOf
    */
    const String substring (const int startIndex) const throw();

    /** Returns a version of this string with a number of characters removed
        from the end.

        @param numberToDrop     the number of characters to drop from the end of the
                                string. If this is greater than the length of the string,
                                an empty string will be returned. If zero or less, the
                                original string will be returned.
        @see substring, fromFirstOccurrenceOf, upToFirstOccurrenceOf, fromLastOccurrenceOf, getLastCharacter
    */
    const String dropLastCharacters (const int numberToDrop) const throw();

    /** Returns a section of the string starting from a given substring.

        This will search for the first occurrence of the given substring, and
        return the section of the string starting from the point where this is
        found (optionally not including the substring itself).

        e.g. for the string "123456", fromFirstOccurrenceOf ("34", true) would return "3456", and
                                      fromFirstOccurrenceOf ("34", false) would return "56".

        If the substring isn't found, the method will return an empty string.

        If ignoreCase is true, the comparison will be case-insensitive.

        @see upToFirstOccurrenceOf, fromLastOccurrenceOf
    */
    const String fromFirstOccurrenceOf (const tchar* const substringToStartFrom,
                                        const bool includeSubStringInResult,
                                        const bool ignoreCase) const throw();

    /** Returns a section of the string starting from the last occurrence of a given substring.

        Similar to fromFirstOccurrenceOf(), but using the last occurrence of the substring, and
        unlike fromFirstOccurrenceOf(), if the substring isn't found, this method will
        return the whole of the original string.

        @see fromFirstOccurrenceOf, upToLastOccurrenceOf
    */
    const String fromLastOccurrenceOf (const tchar* const substringToFind,
                                       const bool includeSubStringInResult,
                                       const bool ignoreCase) const throw();

    /** Returns the start of this string, up to the first occurrence of a substring.

        This will search for the first occurrence of a given substring, and then
        return a copy of the string, up to the position of this substring,
        optionally including or excluding the substring itself in the result.

        e.g. for the string "123456", upTo ("34", false) would return "12", and
                                      upTo ("34", true) would return "1234".

        If the substring isn't found, this will return the whole of the original string.

        @see upToLastOccurrenceOf, fromFirstOccurrenceOf
    */
    const String upToFirstOccurrenceOf (const tchar* const substringToEndWith,
                                        const bool includeSubStringInResult,
                                        const bool ignoreCase) const throw();

    /** Returns the start of this string, up to the last occurrence of a substring.

        Similar to upToFirstOccurrenceOf(), but this finds the last occurrence rather than the first.

        @see upToFirstOccurrenceOf, fromFirstOccurrenceOf
    */
    const String upToLastOccurrenceOf (const tchar* substringToFind,
                                       const bool includeSubStringInResult,
                                       const bool ignoreCase) const throw();

    /** Returns a copy of this string with any whitespace characters removed from the start and end. */
    const String trim() const throw();
    /** Returns a copy of this string with any whitespace characters removed from the start. */
    const String trimStart() const throw();
    /** Returns a copy of this string with any whitespace characters removed from the end. */
    const String trimEnd() const throw();

    /** Returns an upper-case version of this string. */
    const String toUpperCase() const throw();

    /** Returns an lower-case version of this string. */
    const String toLowerCase() const throw();

    /** Replaces a sub-section of the string with another string.

        This will return a copy of this string, with a set of characters
        from startIndex to startIndex + numCharsToReplace removed, and with
        a new string inserted in their place.

        Note that this is a const method, and won't alter the string itself.

        @param startIndex               the first character to remove. If this is beyond the bounds of the string,
                                        it will be constrained to a valid range.
        @param numCharactersToReplace   the number of characters to remove. If zero or less, no
                                        characters will be taken out.
        @param stringToInsert           the new string to insert at startIndex after the characters have been
                                        removed.
    */
    const String replaceSection (int startIndex,
                                 int numCharactersToReplace,
                                 const tchar* const stringToInsert) const throw();

    /** Replaces all occurrences of a substring with another string.

        Returns a copy of this string, with any occurrences of stringToReplace
        swapped for stringToInsertInstead.

        Note that this is a const method, and won't alter the string itself.
    */
    const String replace (const tchar* const stringToReplace,
                          const tchar* const stringToInsertInstead,
                          const bool ignoreCase = false) const throw();

    /** Returns a string with all occurrences of a character replaced with a different one. */
    const String replaceCharacter (const tchar characterToReplace,
                                   const tchar characterToInsertInstead) const throw();

    /** Replaces a set of characters with another set.

        Returns a string in which each character from charactersToReplace has been replaced
        by the character at the equivalent position in newCharacters (so the two strings
        passed in must be the same length).

        e.g. translate ("abc", "def") replaces 'a' with 'd', 'b' with 'e', etc.

        Note that this is a const method, and won't affect the string itself.
    */
    const String replaceCharacters (const String& charactersToReplace,
                                    const tchar* const charactersToInsertInstead) const throw();

    /** Returns a version of this string that only retains a fixed set of characters.

        This will return a copy of this string, omitting any characters which are not
        found in the string passed-in.

        e.g. for "1122334455", retainCharacters ("432") would return "223344"

        Note that this is a const method, and won't alter the string itself.
    */
    const String retainCharacters (const tchar* const charactersToRetain) const throw();

    /** Returns a version of this string with a set of characters removed.

        This will return a copy of this string, omitting any characters which are
        found in the string passed-in.

        e.g. for "1122334455", removeCharacters ("432") would return "1155"

        Note that this is a const method, and won't alter the string itself.
    */
    const String removeCharacters (const tchar* const charactersToRemove) const throw();

    /** Returns a section from the start of the string that only contains a certain set of characters.

        This returns the leftmost section of the string, up to (and not including) the
        first character that doesn't appear in the string passed in.
    */
    const String initialSectionContainingOnly (const tchar* const permittedCharacters) const throw();

    /** Returns a section from the start of the string that only contains a certain set of characters.

        This returns the leftmost section of the string, up to (and not including) the
        first character that occurs in the string passed in.
    */
    const String initialSectionNotContaining (const tchar* const charactersToStopAt) const throw();

    /** Checks whether the string might be in quotation marks.

        @returns    true if the string begins with a quote character (either a double or single quote).
                    It is also true if there is whitespace before the quote, but it doesn't check the end of the string.
        @see unquoted, quoted
    */
    bool isQuotedString() const throw();

    /** Removes quotation marks from around the string, (if there are any).

        Returns a copy of this string with any quotes removed from its ends. Quotes that aren't
        at the ends of the string are not affected. If there aren't any quotes, the original string
        is returned.

        Note that this is a const method, and won't alter the string itself.

        @see isQuotedString, quoted
    */
    const String unquoted() const throw();

    /** Adds quotation marks around a string.

        This will return a copy of the string with a quote at the start and end, (but won't
        add the quote if there's already one there, so it's safe to call this on strings that
        may already have quotes around them).

        Note that this is a const method, and won't alter the string itself.

        @param quoteCharacter   the character to add at the start and end
        @see isQuotedString, unquoted
    */
    const String quoted (const tchar quoteCharacter = JUCE_T('"')) const throw();

    /** Writes text into this string, using printf style-arguments.

        This will replace the contents of the string with the output of this
        formatted printf.

        Note that using the %s token with a juce string is probably a bad idea, as
        this may expect differect encodings on different platforms.

        @see formatted
    */
    void printf (const tchar* const format, ...) throw();

    /** Returns a string, created using arguments in the style of printf.

        This will return a string which is the result of a sprintf using the
        arguments passed-in.

        Note that using the %s token with a juce string is probably a bad idea, as
        this may expect differect encodings on different platforms.

        @see printf, vprintf
    */
    static const String formatted (const tchar* const format, ...) throw();

    /** Writes text into this string, using a printf style, but taking a va_list argument.

        This will replace the contents of the string with the output of this
        formatted printf. Used by other methods, this is public in case it's
        useful for other purposes where you want to pass a va_list through directly.

        Note that using the %s token with a juce string is probably a bad idea, as
        this may expect differect encodings on different platforms.

        @see printf, formatted
    */
    void vprintf (const tchar* const format, va_list& args) throw();

    /** Creates a string which is a version of a string repeated and joined together.

        @param stringToRepeat         the string to repeat
        @param numberOfTimesToRepeat  how many times to repeat it
    */
    static const String repeatedString (const tchar* const stringToRepeat,
                                        int numberOfTimesToRepeat) throw();

    /** Creates a string from data in an unknown format.

        This looks at some binary data and tries to guess whether it's Unicode
        or 8-bit characters, then returns a string that represents it correctly.

        Should be able to handle Unicode endianness correctly, by looking at
        the first two bytes.
    */
    static const String createStringFromData (const void* const data,
                                              const int size) throw();

    // Numeric conversions..

    /** Creates a string containing this signed 32-bit integer as a decimal number.

        @see getIntValue, getFloatValue, getDoubleValue, toHexString
    */
    explicit String (const int decimalInteger) throw();

    /** Creates a string containing this unsigned 32-bit integer as a decimal number.

        @see getIntValue, getFloatValue, getDoubleValue, toHexString
    */
    explicit String (const unsigned int decimalInteger) throw();

    /** Creates a string containing this signed 16-bit integer as a decimal number.

        @see getIntValue, getFloatValue, getDoubleValue, toHexString
    */
    explicit String (const short decimalInteger) throw();

    /** Creates a string containing this unsigned 16-bit integer as a decimal number.

        @see getIntValue, getFloatValue, getDoubleValue, toHexString
    */
    explicit String (const unsigned short decimalInteger) throw();

    /** Creates a string containing this signed 64-bit integer as a decimal number.

        @see getLargeIntValue, getFloatValue, getDoubleValue, toHexString
    */
    explicit String (const int64 largeIntegerValue) throw();

    /** Creates a string containing this unsigned 64-bit integer as a decimal number.

        @see getLargeIntValue, getFloatValue, getDoubleValue, toHexString
    */
    explicit String (const uint64 largeIntegerValue) throw();

    /** Creates a string representing this floating-point number.

        @param floatValue               the value to convert to a string
        @param numberOfDecimalPlaces    if this is > 0, it will format the number using that many
                                        decimal places, and will not use exponent notation. If 0 or
                                        less, it will use exponent notation if necessary.
        @see getDoubleValue, getIntValue
    */
    explicit String (const float floatValue,
                     const int numberOfDecimalPlaces = 0) throw();

    /** Creates a string representing this floating-point number.

        @param doubleValue              the value to convert to a string
        @param numberOfDecimalPlaces    if this is > 0, it will format the number using that many
                                        decimal places, and will not use exponent notation. If 0 or
                                        less, it will use exponent notation if necessary.

        @see getFloatValue, getIntValue
    */
    explicit String (const double doubleValue,
                     const int numberOfDecimalPlaces = 0) throw();

    /** Parses this string to find its numerical value (up to 32 bits in size).

        @returns the value of the string as a 32 bit signed base-10 integer.
        @see getTrailingIntValue, getHexValue32, getHexValue64
    */
    int getIntValue() const throw();

    /** Parses this string to find its numerical value (up to 64 bits in size).

        @returns the value of the string as a 64 bit signed base-10 integer.
    */
    int64 getLargeIntValue() const throw();

    /** Parses a decimal number from the end of the string.

        This will look for a value at the end of the string.
        e.g. for "321 xyz654" it will return 654; for "2 3 4" it'll return 4.

        Negative numbers are not handled, so "xyz-5" returns 5.

        @see getIntValue
    */
    int getTrailingIntValue() const throw();

    /** Parses this string as a floating point number.

        @returns    the value of the string as a 32-bit floating point value.
        @see getDoubleValue
    */
    float getFloatValue() const throw();

    /** Parses this string as a floating point number.

        @returns    the value of the string as a 64-bit floating point value.
        @see getFloatValue
    */
    double getDoubleValue() const throw();

    /** Parses the string as a hexadecimal number.

        Non-hexadecimal characters in the string are ignored.

        If the string contains too many characters, then the lowest significant
        digits are returned, e.g. "ffff12345678" would produce 0x12345678.

        @returns    a 32-bit number which is the value of the string in hex.
    */
    int getHexValue32() const throw();

    /** Parses the string as a hexadecimal number.

        Non-hexadecimal characters in the string are ignored.

        If the string contains too many characters, then the lowest significant
        digits are returned, e.g. "ffff1234567812345678" would produce 0x1234567812345678.

        @returns    a 64-bit number which is the value of the string in hex.
    */
    int64 getHexValue64() const throw();

    /** Creates a string representing this 32-bit value in hexadecimal. */
    static const String toHexString (const int number) throw();

    /** Creates a string representing this 64-bit value in hexadecimal. */
    static const String toHexString (const int64 number) throw();

    /** Creates a string representing this 16-bit value in hexadecimal. */
    static const String toHexString (const short number) throw();

    /** Creates a string containing a hex dump of a block of binary data.

        @param data         the binary data to use as input
        @param size         how many bytes of data to use
        @param groupSize    how many bytes are grouped together before inserting a
                            space into the output. e.g. group size 0 has no spaces,
                            group size 1 looks like: "be a1 c2 ff", group size 2 looks
                            like "bea1 c2ff".
    */
    static const String toHexString (const unsigned char* data,
                                     const int size,
                                     const int groupSize = 1) throw();

    // Casting to character arrays..

#if JUCE_STRINGS_ARE_UNICODE
    /** Returns a version of this string using the default 8-bit system encoding.

        Because it returns a reference to the string's internal data, the pointer
        that is returned must not be stored anywhere, as it can be deleted whenever the
        string changes.
    */
    operator const char*() const throw();

    /** Returns a unicode version of this string.

        Because it returns a reference to the string's internal data, the pointer
        that is returned must not be stored anywhere, as it can be deleted whenever the
        string changes.
    */
    inline operator const juce_wchar*() const throw()   { return text->text; }
#else
    /** Returns a version of this string using the default 8-bit system encoding.

        Because it returns a reference to the string's internal data, the pointer
        that is returned must not be stored anywhere, as it can be deleted whenever the
        string changes.
    */
    inline operator const char*() const throw()         { return text->text; }

    /** Returns a unicode version of this string.

        Because it returns a reference to the string's internal data, the pointer
        that is returned must not be stored anywhere, as it can be deleted whenever the
        string changes.
    */
    operator const juce_wchar*() const throw();
#endif

    /** Copies the string to a buffer.

        @param destBuffer       the place to copy it to
        @param maxCharsToCopy   the maximum number of characters to copy to the buffer,
                                not including the tailing zero, so this shouldn't be
                                larger than the size of your destination buffer - 1
    */
    void copyToBuffer (char* const destBuffer,
                       const int maxCharsToCopy) const throw();

    /** Copies the string to a unicode buffer.

        @param destBuffer       the place to copy it to
        @param maxCharsToCopy   the maximum number of characters to copy to the buffer,
                                not including the tailing zero, so this shouldn't be
                                larger than the size of your destination buffer - 1
    */
    void copyToBuffer (juce_wchar* const destBuffer,
                       const int maxCharsToCopy) const throw();

    /** Copies the string to a buffer as UTF-8 characters.

        Returns the number of bytes copied to the buffer, including the terminating null
        character.

        @param destBuffer       the place to copy it to; if this is a null pointer,
                                the method just returns the number of bytes required
                                (including the terminating null character).
        @param maxBufferSizeBytes  the size of the destination buffer, in bytes. If the
                                string won't fit, it'll put in as many as it can while
                                still allowing for a terminating null char at the end,
                                and will return the number of bytes that were actually
                                used. If this value is < 0, no limit is used.
    */
    int copyToUTF8 (uint8* const destBuffer, const int maxBufferSizeBytes = 0x7fffffff) const throw();

    /** Returns a pointer to a UTF-8 version of this string.

        Because it returns a reference to the string's internal data, the pointer
        that is returned must not be stored anywhere, as it can be deleted whenever the
        string changes.
    */
    const char* toUTF8() const throw();

    /** Creates a String from a UTF-8 encoded buffer.

        If the size is < 0, it'll keep reading until it hits a zero.
    */
    static const String fromUTF8 (const uint8* const utf8buffer,
                                  int bufferSizeBytes = -1) throw();

    /** Increases the string's internally allocated storage.

        Although the string's contents won't be affected by this call, it will
        increase the amount of memory allocated internally for the string to grow into.

        If you're about to make a large number of calls to methods such
        as += or <<, it's more efficient to preallocate enough extra space
        beforehand, so that these methods won't have to keep resizing the string
        to append the extra characters.

        @param numCharsNeeded   the number of characters to allocate storage for. If this
                                value is less than the currently allocated size, it will
                                have no effect.
    */
    void preallocateStorage (const int numCharsNeeded) throw();

    juce_UseDebuggingNewOperator // (adds debugging info to find leaked objects)

private:

    struct InternalRefCountedStringHolder
    {
        int refCount;
        int allocatedNumChars;

#if JUCE_STRINGS_ARE_UNICODE
          wchar_t text[1];
#else
          char text[1];
#endif
    };

    InternalRefCountedStringHolder* text;
    static InternalRefCountedStringHolder emptyString;

    // internal constructor that preallocates a certain amount of memory
    String (const int numChars, const int dummyVariable) throw();

    void deleteInternal() throw();
    void createInternal (const int numChars) throw();
    void createInternal (const tchar* const text, const tchar* const textEnd) throw();
    void appendInternal (const tchar* const text, const int numExtraChars) throw();
    void doubleToStringWithDecPlaces (double n, int numDecPlaces) throw();
    void dupeInternalIfMultiplyReferenced() throw();
};

/** Global operator to allow a String to be appended to a string literal.

    This allows the use of expressions such as "abc" + String (x)

    @see String
 */
const String JUCE_PUBLIC_FUNCTION   operator+ (const char* const string1,
                                               const String& string2) throw();

/** Global operator to allow a String to be appended to a string literal.

    This allows the use of expressions such as "abc" + String (x)

    @see String
 */
const String JUCE_PUBLIC_FUNCTION   operator+ (const juce_wchar* const string1,
                                               const String& string2) throw();

#endif   // __JUCE_STRING_JUCEHEADER__
/********* End of inlined file: juce_String.h *********/

/**
    Acts as an application-wide logging class.

    A subclass of Logger can be created and passed into the Logger::setCurrentLogger
    method and this will then be used by all calls to writeToLog.

    The logger class also contains methods for writing messages to the debugger's
    output stream.

    @see FileLogger
*/
class JUCE_API  Logger
{
public:

    /** Destructor. */
    virtual ~Logger();

    /** Sets the current logging class to use.

        Note that the object passed in won't be deleted when no longer needed.
        A null pointer can be passed-in to disable any logging.

        If deleteOldLogger is set to true, the existing logger will be
        deleted (if there is one).
    */
    static void JUCE_CALLTYPE setCurrentLogger (Logger* const newLogger,
                                                const bool deleteOldLogger = false);

    /** Writes a string to the current logger.

        This will pass the string to the logger's logMessage() method if a logger
        has been set.

        @see logMessage
    */
    static void JUCE_CALLTYPE writeToLog (const String& message);

    /** Writes a message to the standard error stream.

        This can be called directly, or by using the DBG() macro in
        juce_PlatformDefs.h (which will avoid calling the method in non-debug builds).
    */
    static void JUCE_CALLTYPE outputDebugString (const String& text) throw();

    /** Writes a message to the standard error stream.

        This can be called directly, or by using the DBG_PRINTF() macro in
        juce_PlatformDefs.h (which will avoid calling the method in non-debug builds).
    */
    static void JUCE_CALLTYPE outputDebugPrintf (const tchar* format, ...) throw();

protected:

    Logger();

    /** This is overloaded by subclasses to implement custom logging behaviour.

        @see setCurrentLogger
    */
    virtual void logMessage (const String& message) = 0;
};

#endif   // __JUCE_LOGGER_JUCEHEADER__
/********* End of inlined file: juce_Logger.h *********/

END_JUCE_NAMESPACE

#endif   // __JUCE_STANDARDHEADER_JUCEHEADER__
/********* End of inlined file: juce_StandardHeader.h *********/

BEGIN_JUCE_NAMESPACE

#if JUCE_MSVC
  // this is set explicitly in case the app is using a different packing size.
  #pragma pack (push, 8)
  #pragma warning (push)
  #pragma warning (disable: 4786) // (old vc6 warning about long class names)
#endif

#if JUCE_MAC
  #pragma align=natural
#endif

#define JUCE_PUBLIC_INCLUDES

// this is where all the class header files get brought in..

/********* Start of inlined file: juce_core_includes.h *********/
#ifndef __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__
#define __JUCE_JUCE_CORE_INCLUDES_INCLUDEFILES__

#ifndef __JUCE_ATOMIC_JUCEHEADER__

/********* Start of inlined file: juce_Atomic.h *********/
#ifndef __JUCE_ATOMIC_JUCEHEADER__
#define __JUCE_ATOMIC_JUCEHEADER__

// Atomic increment/decrement operations..

#if JUCE_MAC && ! DOXYGEN

  #if ! MACOS_10_3_OR_EARLIER

    forcedinline void atomicIncrement (int& variable) throw()           { OSAtomicIncrement32 ((int32_t*) &variable); }
    forcedinline int atomicIncrementAndReturn (int& variable) throw()   { return OSAtomicIncrement32 ((int32_t*) &variable); }
    forcedinline void atomicDecrement (int& variable) throw()           { OSAtomicDecrement32 ((int32_t*) &variable); }
    forcedinline int atomicDecrementAndReturn (int& variable) throw()   { return OSAtomicDecrement32 ((int32_t*) &variable); }
  #else

    forcedinline void atomicIncrement (int& variable) throw()           { OTAtomicAdd32 (1, (SInt32*) &variable); }
    forcedinline int atomicIncrementAndReturn (int& variable) throw()   { return OTAtomicAdd32 (1, (SInt32*) &variable); }
    forcedinline void atomicDecrement (int& variable) throw()           { OTAtomicAdd32 (-1, (SInt32*) &variable); }
    forcedinline int atomicDecrementAndReturn (int& variable) throw()   { return OTAtomicAdd32 (-1, (SInt32*) &variable); }
  #endif

#elif JUCE_GCC

  #if JUCE_USE_GCC_ATOMIC_INTRINSICS
    forcedinline void atomicIncrement (int& variable) throw()           { __sync_add_and_fetch (&variable, 1); }
    forcedinline int atomicIncrementAndReturn (int& variable) throw()   { return __sync_add_and_fetch (&variable, 1); }
    forcedinline void atomicDecrement (int& variable) throw()           { __sync_add_and_fetch (&variable, -1); }
    forcedinline int atomicDecrementAndReturn (int& variable) throw()   { return __sync_add_and_fetch (&variable, -1); }
  #else

    /** Increments an integer in a thread-safe way. */
    forcedinline void atomicIncrement (int& variable) throw()
    {
        __asm__ __volatile__ (
        #if JUCE_64BIT
            "lock incl (%%rax)"
            :
            : "a" (&variable)
            : "cc", "memory");
        #else
            "lock incl %0"
            : "=m" (variable)
            : "m" (variable));
        #endif
    }

    /** Increments an integer in a thread-safe way and returns the incremented value. */
    forcedinline int atomicIncrementAndReturn (int& variable) throw()
    {
        int result;

        __asm__ __volatile__ (
        #if JUCE_64BIT
            "lock xaddl %%ebx, (%%rax) \n\
             incl %%ebx"
            : "=b" (result)
            : "a" (&variable), "b" (1)
            : "cc", "memory");
        #else
            "lock xaddl %%eax, (%%ecx) \n\
             incl %%eax"
            : "=a" (result)
            : "c" (&variable), "a" (1)
            : "memory");
        #endif

        return result;
    }

    /** Decrememts an integer in a thread-safe way. */
    forcedinline void atomicDecrement (int& variable) throw()
    {
        __asm__ __volatile__ (
        #if JUCE_64BIT
            "lock decl (%%rax)"
            :
            : "a" (&variable)
            : "cc", "memory");
        #else
            "lock decl %0"
            : "=m" (variable)
            : "m" (variable));
        #endif
    }

    /** Decrememts an integer in a thread-safe way and returns the incremented value. */
    forcedinline int atomicDecrementAndReturn (int& variable) throw()
    {
        int result;

        __asm__ __volatile__ (
        #if JUCE_64BIT
            "lock xaddl %%ebx, (%%rax) \n\
             decl %%ebx"
            : "=b" (result)
            : "a" (&variable), "b" (-1)
            : "cc", "memory");
        #else
            "lock xaddl %%eax, (%%ecx) \n\
             decl %%eax"
            : "=a" (result)
            : "c" (&variable), "a" (-1)
            : "memory");
        #endif
        return result;
    }
  #endif

#elif JUCE_USE_INTRINSICS

    #pragma intrinsic (_InterlockedIncrement)
    #pragma intrinsic (_InterlockedDecrement)

    /** Increments an integer in a thread-safe way. */
    forcedinline void __fastcall atomicIncrement (int& variable) throw()
    {
        _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable));
    }

    /** Increments an integer in a thread-safe way and returns the incremented value. */
    forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw()
    {
        return _InterlockedIncrement (reinterpret_cast <volatile long*> (&variable));
    }

    /** Decrememts an integer in a thread-safe way. */
    forcedinline void __fastcall atomicDecrement (int& variable) throw()
    {
        _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable));
    }

    /** Decrememts an integer in a thread-safe way and returns the incremented value. */
    forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw()
    {
        return _InterlockedDecrement (reinterpret_cast <volatile long*> (&variable));
    }
#else

    /** Increments an integer in a thread-safe way. */
    forcedinline void __fastcall atomicIncrement (int& variable) throw()
    {
        __asm {
            mov ecx, dword ptr [variable]
            lock inc dword ptr [ecx]
        }
    }

    /** Increments an integer in a thread-safe way and returns the incremented value. */
    forcedinline int __fastcall atomicIncrementAndReturn (int& variable) throw()
    {
        int result;

        __asm {
            mov ecx, dword ptr [variable]
            mov eax, 1
            lock xadd dword ptr [ecx], eax
            inc eax
            mov result, eax
        }

        return result;
    }

    /** Decrememts an integer in a thread-safe way. */
    forcedinline void __fastcall atomicDecrement (int& variable) throw()
    {
        __asm {
            mov ecx, dword ptr [variable]
            lock dec dword ptr [ecx]
        }
    }

    /** Decrememts an integer in a thread-safe way and returns the incremented value. */
    forcedinline int __fastcall atomicDecrementAndReturn (int& variable) throw()
    {
        int result;

        __asm {
            mov ecx, dword ptr [variable]
            mov eax, -1
            lock xadd dword ptr [ecx], eax
            dec eax
            mov result, eax
        }

        return result;
    }
#endif

#endif   // __JUCE_ATOMIC_JUCEHEADER__
/********* End of inlined file: juce_Atomic.h *********/

#endif
#ifndef __JUCE_FILELOGGER_JUCEHEADER__

/********* Start of inlined file: juce_FileLogger.h *********/
#ifndef __JUCE_FILELOGGER_JUCEHEADER__
#define __JUCE_FILELOGGER_JUCEHEADER__

/********* Start of inlined file: juce_File.h *********/
#ifndef __JUCE_FILE_JUCEHEADER__
#define __JUCE_FILE_JUCEHEADER__

/********* Start of inlined file: juce_OwnedArray.h *********/
#ifndef __JUCE_OWNEDARRAY_JUCEHEADER__
#define __JUCE_OWNEDARRAY_JUCEHEADER__

/********* Start of inlined file: juce_ArrayAllocationBase.h *********/
#ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__
#define __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__

/** The default size of chunk in which arrays increase their storage.

    Used by ArrayAllocationBase and its subclasses.
*/
const int juceDefaultArrayGranularity = 8;

/**
    Implements some basic array storage allocation functions.

    This class isn't really for public use - it's used by the other
    array classes, but might come in handy for some purposes.

    @see Array, OwnedArray, ReferenceCountedArray
*/
template <class ElementType>
class ArrayAllocationBase
{
protected:

    /** Creates an empty array.

        @param granularity_  this is the size of increment by which the internal storage
        will be increased.
    */
    ArrayAllocationBase (const int granularity_) throw()
        : elements (0),
          numAllocated (0),
          granularity (granularity_)
    {
        jassert (granularity > 0);
    }

    /** Destructor. */
    ~ArrayAllocationBase() throw()
    {
        delete[] elements;
    }

    /** Changes the amount of storage allocated.

        This will retain any data currently held in the array, and either add or
        remove extra space at the end.

        @param numElements  the number of elements that are needed
    */
    void setAllocatedSize (const int numElements) throw()
    {
        if (numAllocated != numElements)
        {
            if (numElements > 0)
            {
                ElementType* const newElements = new ElementType [numElements];

                const int itemsToRetain = jmin (numElements, numAllocated);

                for (int i = 0; i < itemsToRetain; ++i)
                    newElements[i] = elements[i];

                delete[] elements;
                elements = newElements;

            }
            else if (elements != 0)
            {
                delete[] elements;
                elements = 0;
            }

            numAllocated = numElements;
        }
    }

    /** Increases the amount of storage allocated if it is less than a given amount.

        This will retain any data currently held in the array, but will add
        extra space at the end to make sure there it's at least as big as the size
        passed in. If it's already bigger, no action is taken.

        @param minNumElements  the minimum number of elements that are needed
    */
    void ensureAllocatedSize (int minNumElements) throw()
    {
        if (minNumElements > numAllocated)
        {
            // for arrays with small granularity that get big, start
            // increasing the size in bigger jumps
            if (minNumElements > (granularity << 6))
            {
                minNumElements += (minNumElements / granularity);
                if (minNumElements > (granularity << 8))
                    minNumElements += granularity << 6;
                else
                    minNumElements += granularity << 5;
            }

            setAllocatedSize (granularity * (minNumElements / granularity + 1));
        }
    }

    ElementType* elements;
    int numAllocated, granularity;

private:
    ArrayAllocationBase (const ArrayAllocationBase&);
    const ArrayAllocationBase& operator= (const ArrayAllocationBase&);
};

#endif   // __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__
/********* End of inlined file: juce_ArrayAllocationBase.h *********/

/********* Start of inlined file: juce_ElementComparator.h *********/
#ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__
#define __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__

/**
    Sorts a range of elements in an array.

    The comparator object that is passed-in must define a public method with the following
    signature:
    @code
    int compareElements (ElementType first, ElementType second);
    @endcode

    ..and this method must return:
      - a value of < 0 if the first comes before the second
      - a value of 0 if the two objects are equivalent
      - a value of > 0 if the second comes before the first

    To improve performance, the compareElements() method can be declared as static or const.

    @param comparator       an object which defines a compareElements() method
    @param array            the array to sort
    @param firstElement     the index of the first element of the range to be sorted
    @param lastElement      the index of the last element in the range that needs
                            sorting (this is inclusive)
    @param retainOrderOfEquivalentItems     if true, the order of items that the
                            comparator deems the same will be maintained - this will be
                            a slower algorithm than if they are allowed to be moved around.

    @see sortArrayRetainingOrder
*/
template <class ElementType, class ElementComparator>
static void sortArray (ElementComparator& comparator,
                       ElementType* const array,
                       int firstElement,
                       int lastElement,
                       const bool retainOrderOfEquivalentItems)
{
    (void) comparator;  // if you pass in an object with a static compareElements() method, this
                        // avoids getting warning messages about the parameter being unused

    if (lastElement > firstElement)
    {
        if (retainOrderOfEquivalentItems)
        {
            for (int i = firstElement; i < lastElement; ++i)
            {
                if (comparator.compareElements (array[i], array [i + 1]) > 0)
                {
                    const ElementType temp = array [i];
                    array [i] = array[i + 1];
                    array [i + 1] = temp;

                    if (i > firstElement)
                        i -= 2;
                }
            }
        }
        else
        {
            int fromStack[30], toStack[30];
            int stackIndex = 0;

            for (;;)
            {
                const int size = (lastElement - firstElement) + 1;

                if (size <= 8)
                {
                    int j = lastElement;
                    int maxIndex;

                    while (j > firstElement)
                    {
                        maxIndex = firstElement;
                        for (int k = firstElement + 1; k <= j; ++k)
                            if (comparator.compareElements (array[k], array [maxIndex]) > 0)
                                maxIndex = k;

                        const ElementType temp = array [maxIndex];
                        array [maxIndex] = array[j];
                        array [j] = temp;

                        --j;
                    }
                }
                else
                {
                    const int mid = firstElement + (size >> 1);
                    ElementType temp = array [mid];
                    array [mid] = array [firstElement];
                    array [firstElement] = temp;

                    int i = firstElement;
                    int j = lastElement + 1;

                    for (;;)
                    {
                        while (++i <= lastElement
                                && comparator.compareElements (array[i], array [firstElement]) <= 0)
                        {}

                        while (--j > firstElement
                                && comparator.compareElements (array[j], array [firstElement]) >= 0)
                        {}

                        if (j < i)
                            break;

                        temp = array[i];
                        array[i] = array[j];
                        array[j] = temp;
                    }

                    temp = array [firstElement];
                    array [firstElement] = array[j];
                    array [j] = temp;

                    if (j - 1 - firstElement >= lastElement - i)
                    {
                        if (firstElement + 1 < j)
                        {
                            fromStack [stackIndex] = firstElement;
                            toStack [stackIndex] = j - 1;
                            ++stackIndex;
                        }

                        if (i < lastElement)
                        {
                            firstElement = i;
                            continue;
                        }
                    }
                    else
                    {
                        if (i < lastElement)
                        {
                            fromStack [stackIndex] = i;
                            toStack [stackIndex] = lastElement;
                            ++stackIndex;
                        }

                        if (firstElement + 1 < j)
                        {
                            lastElement = j - 1;
                            continue;
                        }
                    }
                }

                if (--stackIndex < 0)
                    break;

                jassert (stackIndex < numElementsInArray (fromStack));

                firstElement = fromStack [stackIndex];
                lastElement = toStack [stackIndex];
            }
        }
    }
}

/**
    Searches a sorted array of elements, looking for the index at which a specified value
    should be inserted for it to be in the correct order.

    The comparator object that is passed-in must define a public method with the following
    signature:
    @code
    int compareElements (ElementType first, ElementType second);
    @endcode

    ..and this method must return:
      - a value of < 0 if the first comes before the second
      - a value of 0 if the two objects are equivalent
      - a value of > 0 if the second comes before the first

    To improve performance, the compareElements() method can be declared as static or const.

    @param comparator       an object which defines a compareElements() method
    @param array            the array to search
    @param newElement       the value that is going to be inserted
    @param firstElement     the index of the first element to search
    @param lastElement      the index of the last element in the range (this is non-inclusive)
*/
template <class ElementType, class ElementComparator>
static int findInsertIndexInSortedArray (ElementComparator& comparator,
                                         ElementType* const array,
                                         const ElementType newElement,
                                         int firstElement,
                                         int lastElement)
{
    jassert (firstElement <= lastElement);

    (void) comparator;  // if you pass in an object with a static compareElements() method, this
                        // avoids getting warning messages about the parameter being unused

    while (firstElement < lastElement)
    {
        if (comparator.compareElements (newElement, array [firstElement]) == 0)
        {
            ++firstElement;
            break;
        }
        else
        {
            const int halfway = (firstElement + lastElement) >> 1;

            if (halfway == firstElement)
            {
                if (comparator.compareElements (newElement, array [halfway]) >= 0)
                    ++firstElement;

                break;
            }
            else if (comparator.compareElements (newElement, array [halfway]) >= 0)
            {
                firstElement = halfway;
            }
            else
            {
                lastElement = halfway;
            }
        }
    }

    return firstElement;
}

/**
    A simple ElementComparator class that can be used to sort an array of
    integer primitive objects.

    Example: @code
    Array <int> myArray;

    IntegerElementComparator<int> sorter;
    myArray.sort (sorter);
    @endcode

    For floating point values, see the FloatElementComparator class instead.

    @see FloatElementComparator, ElementComparator
*/
template <class ElementType>
class IntegerElementComparator
{
public:
    static int compareElements (const ElementType first,
                                const ElementType second) throw()
    {
        return (first < second) ? -1 : ((first == second) ? 0 : 1);
    }
};

/**
    A simple ElementComparator class that can be used to sort an array of numeric
    double or floating point primitive objects.

    Example: @code
    Array <double> myArray;

    FloatElementComparator<double> sorter;
    myArray.sort (sorter);
    @endcode

    For integer values, see the IntegerElementComparator class instead.

    @see IntegerElementComparator, ElementComparator
*/
template <class ElementType>
class FloatElementComparator
{
public:
    static int compareElements (const ElementType first,
                                const ElementType second) throw()
    {
        return (first < second) ? -1 : ((first == second) ? 0 : 1);
    }
};

#endif   // __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__
/********* End of inlined file: juce_ElementComparator.h *********/

/********* Start of inlined file: juce_CriticalSection.h *********/
#ifndef __JUCE_CRITICALSECTION_JUCEHEADER__
#define __JUCE_CRITICALSECTION_JUCEHEADER__

/**
    Prevents multiple threads from accessing shared objects at the same time.

    @see ScopedLock, Thread, InterProcessLock
*/
class JUCE_API  CriticalSection
{
public:

    /**
        Creates a CriticalSection object
    */
    CriticalSection() throw();

    /** Destroys a CriticalSection object.

        If the critical section is deleted whilst locked, its subsequent behaviour
        is unpredictable.
    */
    ~CriticalSection() throw();

    /** Locks this critical section.

        If the lock is currently held by another thread, this will wait until it
        becomes free.

        If the lock is already held by the caller thread, the method returns immediately.

        @see exit, ScopedLock
    */
    void enter() const throw();

    /** Attempts to lock this critical section without blocking.

        This method behaves identically to CriticalSection::enter, except that the caller thread
        does not wait if the lock is currently held by another thread but returns false immediately.

        @returns false if the lock is currently held by another thread, true otherwise.
        @see enter
    */
    bool tryEnter() const throw();

    /** Releases the lock.

        If the caller thread hasn't got the lock, this can have unpredictable results.

        If the enter() method has been called multiple times by the thread, each
        call must be matched by a call to exit() before other threads will be allowed
        to take over the lock.

        @see enter, ScopedLock
    */
    void exit() const throw();

    juce_UseDebuggingNewOperator

private:

#if JUCE_WIN32
  #if JUCE_64BIT
    // To avoid including windows.h in the public Juce includes, we'll just allocate a
    // block of memory here that's big enough to be used internally as a windows critical
    // section object.
    uint8 internal [44];
  #else
    uint8 internal [24];
  #endif
#else
    mutable pthread_mutex_t internal;
#endif

    CriticalSection (const CriticalSection&);
    const CriticalSection& operator= (const CriticalSection&);
};

/**
    A class that can be used in place of a real CriticalSection object.

    This is currently used by some templated array classes, and should get
    optimised out by the compiler.

    @see Array, OwnedArray, ReferenceCountedArray
*/
class JUCE_API  DummyCriticalSection
{
public:
    forcedinline DummyCriticalSection() throw()         {}
    forcedinline ~DummyCriticalSection() throw()        {}

    forcedinline void enter() const throw()             {}
    forcedinline void exit() const throw()              {}
};

#endif   // __JUCE_CRITICALSECTION_JUCEHEADER__
/********* End of inlined file: juce_CriticalSection.h *********/

/** An array designed for holding objects.

    This holds a list of pointers to objects, and will automatically
    delete the objects when they are removed from the array, or when the
    array is itself deleted.

    Declare it in the form:  OwnedArray<MyObjectClass>

    ..and then add new objects, e.g.   myOwnedArray.add (new MyObjectClass());

    After adding objects, they are 'owned' by the array and will be deleted when
    removed or replaced.

    To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
    TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.

    @see Array, ReferenceCountedArray, StringArray, CriticalSection
*/
template <class ObjectClass,
          class TypeOfCriticalSectionToUse = DummyCriticalSection>

class OwnedArray   : private ArrayAllocationBase <ObjectClass*>
{
public:

    /** Creates an empty array.

        @param granularity  this is the size of increment by which the internal storage
        used by the array will grow. Only change it from the default if you know the
        array is going to be very big and needs to be able to grow efficiently.

        @see ArrayAllocationBase
    */
    OwnedArray (const int granularity = juceDefaultArrayGranularity) throw()
        : ArrayAllocationBase <ObjectClass*> (granularity),
          numUsed (0)
    {
    }

    /** Deletes the array and also deletes any objects inside it.

        To get rid of the array without deleting its objects, use its
        clear (false) method before deleting it.
    */
    ~OwnedArray()
    {
        clear (true);
    }

    /** Clears the array, optionally deleting the objects inside it first. */
    void clear (const bool deleteObjects = true)
    {
        lock.enter();

        if (deleteObjects)
        {
            while (numUsed > 0)
                delete this->elements [--numUsed];
        }

        this->setAllocatedSize (0);
        numUsed = 0;
        lock.exit();
    }

    /** Returns the number of items currently in the array.
        @see operator[]
    */
    inline int size() const throw()
    {
        return numUsed;
    }

    /** Returns a pointer to the object at this index in the array.

        If the index is out-of-range, this will return a null pointer, (and
        it could be null anyway, because it's ok for the array to hold null
        pointers as well as objects).

        @see getUnchecked
    */
    inline ObjectClass* operator[] (const int index) const throw()
    {
        lock.enter();
        ObjectClass* const result = (((unsigned int) index) < (unsigned int) numUsed)
                                            ? this->elements [index]
                                            : (ObjectClass*) 0;
        lock.exit();

        return result;
    }

    /** Returns a pointer to the object at this index in the array, without checking whether the index is in-range.

        This is a faster and less safe version of operator[] which doesn't check the index passed in, so
        it can be used when you're sure the index if always going to be legal.
    */
    inline ObjectClass* getUnchecked (const int index) const throw()
    {
        lock.enter();
        jassert (((unsigned int) index) < (unsigned int) numUsed);
        ObjectClass* const result = this->elements [index];
        lock.exit();

        return result;
    }

    /** Returns a pointer to the first object in the array.

        This will return a null pointer if the array's empty.
        @see getLast
    */
    inline ObjectClass* getFirst() const throw()
    {
        lock.enter();
        ObjectClass* const result = (numUsed > 0) ? this->elements [0]
                                                  : (ObjectClass*) 0;
        lock.exit();
        return result;
    }

    /** Returns a pointer to the last object in the array.

        This will return a null pointer if the array's empty.
        @see getFirst
    */
    inline ObjectClass* getLast() const throw()
    {
        lock.enter();
        ObjectClass* const result = (numUsed > 0) ? this->elements [numUsed - 1]
                                                  : (ObjectClass*) 0;
        lock.exit();

        return result;
    }

    /** Finds the index of an object which might be in the array.

        @param objectToLookFor    the object to look for
        @returns                  the index at which the object was found, or -1 if it's not found
    */
    int indexOf (const ObjectClass* const objectToLookFor) const throw()
    {
        int result = -1;

        lock.enter();
        ObjectClass* const* e = this->elements;

        for (int i = numUsed; --i >= 0;)
        {
            if (objectToLookFor == *e)
            {
                result = (int) (e - this->elements);
                break;
            }

            ++e;
        }

        lock.exit();
        return result;
    }

    /** Returns true if the array contains a specified object.

        @param objectToLookFor      the object to look for
        @returns                    true if the object is in the array
    */
    bool contains (const ObjectClass* const objectToLookFor) const throw()
    {
        lock.enter();

        ObjectClass* const* e = this->elements;
        int i = numUsed;

        while (i >= 4)
        {
            if (objectToLookFor == *e
                 || objectToLookFor == *++e
                 || objectToLookFor == *++e
                 || objectToLookFor == *++e)
            {
                lock.exit();
                return true;
            }

            i -= 4;
            ++e;
        }

        while (i > 0)
        {
            if (objectToLookFor == *e)
            {
                lock.exit();
                return true;
            }

            --i;
            ++e;
        }

        lock.exit();
        return false;
    }

    /** Appends a new object to the end of the array.

        Note that the this object will be deleted by the OwnedArray when it
        is removed, so be careful not to delete it somewhere else.

        Also be careful not to add the same object to the array more than once,
        as this will obviously cause deletion of dangling pointers.

        @param newObject       the new object to add to the array
        @see set, insert, addIfNotAlreadyThere, addSorted
    */
    void add (const ObjectClass* const newObject) throw()
    {
        lock.enter();
        this->ensureAllocatedSize (numUsed + 1);
        this->elements [numUsed++] = const_cast <ObjectClass*> (newObject);
        lock.exit();
    }

    /** Inserts a new object into the array at the given index.

        Note that the this object will be deleted by the OwnedArray when it
        is removed, so be careful not to delete it somewhere else.

        If the index is less than 0 or greater than the size of the array, the
        element will be added to the end of the array.
        Otherwise, it will be inserted into the array, moving all the later elements
        along to make room.

        Be careful not to add the same object to the array more than once,
        as this will obviously cause deletion of dangling pointers.

        @param indexToInsertAt      the index at which the new element should be inserted
        @param newObject            the new object to add to the array
        @see add, addSorted, addIfNotAlreadyThere, set
    */
    void insert (int indexToInsertAt,
                 const ObjectClass* const newObject) throw()
    {
        if (indexToInsertAt >= 0)
        {
            lock.enter();

            if (indexToInsertAt > numUsed)
                indexToInsertAt = numUsed;

            this->ensureAllocatedSize (numUsed + 1);

            ObjectClass** const e = this->elements + indexToInsertAt;
            const int numToMove = numUsed - indexToInsertAt;

            if (numToMove > 0)
                memmove (e + 1, e, numToMove * sizeof (ObjectClass*));

            *e = const_cast <ObjectClass*> (newObject);
            ++numUsed;

            lock.exit();
        }
        else
        {
            add (newObject);
        }
    }

    /** Appends a new object at the end of the array as long as the array doesn't
        already contain it.

        If the array already contains a matching object, nothing will be done.

        @param newObject   the new object to add to the array
    */
    void addIfNotAlreadyThere (const ObjectClass* const newObject) throw()
    {
        lock.enter();

        if (! contains (newObject))
            add (newObject);

        lock.exit();
    }

    /** Replaces an object in the array with a different one.

        If the index is less than zero, this method does nothing.
        If the index is beyond the end of the array, the new object is added to the end of the array.

        Be careful not to add the same object to the array more than once,
        as this will obviously cause deletion of dangling pointers.

        @param indexToChange        the index whose value you want to change
        @param newObject            the new value to set for this index.
        @param deleteOldElement     whether to delete the object that's being replaced with the new one
        @see add, insert, remove
    */
    void set (const int indexToChange,
              const ObjectClass* const newObject,
              const bool deleteOldElement = true)
    {
        if (indexToChange >= 0)
        {
            ObjectClass* toDelete = 0;
            lock.enter();

            if (indexToChange < numUsed)
            {
                if (deleteOldElement)
                {
                    toDelete = this->elements [indexToChange];

                    if (toDelete == newObject)
                        toDelete = 0;
                }

                this->elements [indexToChange] = const_cast <ObjectClass*> (newObject);
            }
            else
            {
                this->ensureAllocatedSize (numUsed + 1);
                this->elements [numUsed++] = const_cast <ObjectClass*> (newObject);
            }

            lock.exit();

            delete toDelete;
        }
    }

    /** Inserts a new object into the array assuming that the array is sorted.

        This will use a comparator to find the position at which the new object
        should go. If the array isn't sorted, the behaviour of this
        method will be unpredictable.

        @param comparator   the comparator to use to compare the elements - see the sort method
                            for details about this object's structure
        @param newObject    the new object to insert to the array
        @see add, sort, indexOfSorted
    */
    template <class ElementComparator>
    void addSorted (ElementComparator& comparator,
                    ObjectClass* const newObject) throw()
    {
        (void) comparator;  // if you pass in an object with a static compareElements() method, this
                            // avoids getting warning messages about the parameter being unused
        lock.enter();
        insert (findInsertIndexInSortedArray (comparator, this->elements, newObject, 0, numUsed), newObject);
        lock.exit();
    }

    /** Finds the index of an object in the array, assuming that the array is sorted.

        This will use a comparator to do a binary-chop to find the index of the given
        element, if it exists. If the array isn't sorted, the behaviour of this
        method will be unpredictable.

        @param comparator           the comparator to use to compare the elements - see the sort()
                                    method for details about the form this object should take
        @param objectToLookFor      the object to search for
        @returns                    the index of the element, or -1 if it's not found
        @see addSorted, sort
    */
    template <class ElementComparator>
    int indexOfSorted (ElementComparator& comparator,
                       const ObjectClass* const objectToLookFor) const throw()
    {
        (void) comparator;  // if you pass in an object with a static compareElements() method, this
                            // avoids getting warning messages about the parameter being unused
        lock.enter();

        int start = 0;
        int end = numUsed;

        for (;;)
        {
            if (start >= end)
            {
                lock.exit();
                return -1;
            }
            else if (comparator.compareElements (objectToLookFor, this->elements [start]) == 0)
            {
                lock.exit();
                return start;
            }
            else
            {
                const int halfway = (start + end) >> 1;

                if (halfway == start)
                {
                    lock.exit();
                    return -1;
                }
                else if (comparator.compareElements (objectToLookFor, this->elements [halfway]) >= 0)
                    start = halfway;
                else
                    end = halfway;
            }
        }
    }

    /** Removes an object from the array.

        This will remove the object at a given index (optionally also
        deleting it) and move back all the subsequent objects to close the gap.
        If the index passed in is out-of-range, nothing will happen.

        @param indexToRemove    the index of the element to remove
        @param deleteObject     whether to delete the object that is removed
        @see removeObject, removeRange
    */
    void remove (const int indexToRemove,
                 const bool deleteObject = true)
    {
        lock.enter();
        ObjectClass* toDelete = 0;

        if (((unsigned int) indexToRemove) < (unsigned int) numUsed)
        {
            ObjectClass** const e = this->elements + indexToRemove;

            if (deleteObject)
                toDelete = *e;

            --numUsed;
            const int numToShift = numUsed - indexToRemove;

            if (numToShift > 0)
                memmove (e, e + 1, numToShift * sizeof (ObjectClass*));

            if ((numUsed << 1) < this->numAllocated)
                minimiseStorageOverheads();
        }

        lock.exit();

        delete toDelete;
    }

    /** Removes a specified object from the array.

        If the item isn't found, no action is taken.

        @param objectToRemove   the object to try to remove
        @param deleteObject     whether to delete the object (if it's found)
        @see remove, removeRange
    */
    void removeObject (const ObjectClass* const objectToRemove,
                       const bool deleteObject = true)
    {
        lock.enter();
        ObjectClass** e = this->elements;

        for (int i = numUsed; --i >= 0;)
        {
            if (objectToRemove == *e)
            {
                remove ((int) (e - this->elements), deleteObject);
                break;
            }

            ++e;
        }

        lock.exit();
    }

    /** Removes a range of objects from the array.

        This will remove a set of objects, starting from the given index,
        and move any subsequent elements down to close the gap.

        If the range extends beyond the bounds of the array, it will
        be safely clipped to the size of the array.

        @param startIndex       the index of the first object to remove
        @param numberToRemove   how many objects should be removed
        @param deleteObjects    whether to delete the objects that get removed
        @see remove, removeObject
    */
    void removeRange (int startIndex,
                      const int numberToRemove,
                      const bool deleteObjects = true)
    {
        lock.enter();
        const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove);
        startIndex = jlimit (0, numUsed, startIndex);

        if (endIndex > startIndex)
        {
            if (deleteObjects)
            {
                for (int i = startIndex; i < endIndex; ++i)
                {
                    delete this->elements [i];
                    this->elements [i] = 0; // (in case one of the destructors accesses this array and hits a dangling pointer)
                }
            }

            const int rangeSize = endIndex - startIndex;
            ObjectClass** e = this->elements + startIndex;
            int numToShift = numUsed - endIndex;
            numUsed -= rangeSize;

            while (--numToShift >= 0)
            {
                *e = e [rangeSize];
                ++e;
            }

            if ((numUsed << 1) < this->numAllocated)
                minimiseStorageOverheads();
        }

        lock.exit();
    }

    /** Removes the last n objects from the array.

        @param howManyToRemove   how many objects to remove from the end of the array
        @param deleteObjects     whether to also delete the objects that are removed
        @see remove, removeObject, removeRange
    */
    void removeLast (int howManyToRemove = 1,
                     const bool deleteObjects = true)
    {
        lock.enter();

        if (howManyToRemove >= numUsed)
        {
            clear (deleteObjects);
        }
        else
        {
            while (--howManyToRemove >= 0)
                remove (numUsed - 1, deleteObjects);
        }

        lock.exit();
    }

    /** Swaps a pair of objects in the array.

        If either of the indexes passed in is out-of-range, nothing will happen,
        otherwise the two objects at these positions will be exchanged.
    */
    void swap (const int index1,
               const int index2) throw()
    {
        lock.enter();

        if (((unsigned int) index1) < (unsigned int) numUsed
             && ((unsigned int) index2) < (unsigned int) numUsed)
        {
            swapVariables (this->elements [index1],
                           this->elements [index2]);
        }

        lock.exit();
    }

    /** Moves one of the objects to a different position.

        This will move the object to a specified index, shuffling along
        any intervening elements as required.

        So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
        move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.

        @param currentIndex     the index of the object to be moved. If this isn't a
                                valid index, then nothing will be done
        @param newIndex         the index at which you'd like this object to end up. If this
                                is less than zero, it will be moved to the end of the array
    */
    void move (const int currentIndex,
               int newIndex) throw()
    {
        if (currentIndex != newIndex)
        {
            lock.enter();

            if (((unsigned int) currentIndex) < (unsigned int) numUsed)
            {
                if (((unsigned int) newIndex) >= (unsigned int) numUsed)
                    newIndex = numUsed - 1;

                ObjectClass* const value = this->elements [currentIndex];

                if (newIndex > currentIndex)
                {
                    memmove (this->elements + currentIndex,
                             this->elements + currentIndex + 1,
                             (newIndex - currentIndex) * sizeof (ObjectClass*));
                }
                else
                {
                    memmove (this->elements + newIndex + 1,
                             this->elements + newIndex,
                             (currentIndex - newIndex) * sizeof (ObjectClass*));
                }

                this->elements [newIndex] = value;
            }

            lock.exit();
        }
    }

    /** This swaps the contents of this array with those of another array.

        If you need to exchange two arrays, this is vastly quicker than using copy-by-value
        because it just swaps their internal pointers.
    */
    template <class OtherArrayType>
    void swapWithArray (OtherArrayType& otherArray) throw()
    {
        lock.enter();
        otherArray.lock.enter();
        swapVariables <int> (this->numUsed, otherArray.numUsed);
        swapVariables <ObjectClass**> (this->elements, otherArray.elements);
        swapVariables <int> (this->numAllocated, otherArray.numAllocated);
        otherArray.lock.exit();
        lock.exit();
    }

    /** Reduces the amount of storage being used by the array.

        Arrays typically allocate slightly more storage than they need, and after
        removing elements, they may have quite a lot of unused space allocated.
        This method will reduce the amount of allocated storage to a minimum.
    */
    void minimiseStorageOverheads() throw()
    {
        lock.enter();

        if (numUsed == 0)
        {
            this->setAllocatedSize (0);
        }
        else
        {
            const int newAllocation = this->granularity * (numUsed / this->granularity + 1);

            if (newAllocation < this->numAllocated)
                this->setAllocatedSize (newAllocation);
        }

        lock.exit();
    }

    /** Increases the array's internal storage to hold a minimum number of elements.

        Calling this before adding a large known number of elements means that
        the array won't have to keep dynamically resizing itself as the elements
        are added, and it'll therefore be more efficient.
    */
    void ensureStorageAllocated (const int minNumElements) throw()
    {
        this->ensureAllocatedSize (minNumElements);
    }

    /** Sorts the elements in the array.

        This will use a comparator object to sort the elements into order. The object
        passed must have a method of the form:
        @code
        int compareElements (ElementType first, ElementType second);
        @endcode

        ..and this method must return:
          - a value of < 0 if the first comes before the second
          - a value of 0 if the two objects are equivalent
          - a value of > 0 if the second comes before the first

        To improve performance, the compareElements() method can be declared as static or const.

        @param comparator   the comparator to use for comparing elements.
        @param retainOrderOfEquivalentItems     if this is true, then items
                            which the comparator says are equivalent will be
                            kept in the order in which they currently appear
                            in the array. This is slower to perform, but may
                            be important in some cases. If it's false, a faster
                            algorithm is used, but equivalent elements may be
                            rearranged.
        @see sortArray, indexOfSorted
    */
    template <class ElementComparator>
    void sort (ElementComparator& comparator,
               const bool retainOrderOfEquivalentItems = false) const throw()
    {
        (void) comparator;  // if you pass in an object with a static compareElements() method, this
                            // avoids getting warning messages about the parameter being unused

        lock.enter();
        sortArray (comparator, this->elements, 0, size() - 1, retainOrderOfEquivalentItems);
        lock.exit();
    }

    /** Locks the array's CriticalSection.

        Of course if the type of section used is a DummyCriticalSection, this won't
        have any effect.

        @see unlockArray
    */
    void lockArray() const throw()
    {
        lock.enter();
    }

    /** Unlocks the array's CriticalSection.

        Of course if the type of section used is a DummyCriticalSection, this won't
        have any effect.

        @see lockArray
    */
    void unlockArray() const throw()
    {
        lock.exit();
    }

    juce_UseDebuggingNewOperator

private:
    int numUsed;
    TypeOfCriticalSectionToUse lock;

    // disallow copy constructor and assignment
    OwnedArray (const OwnedArray&);
    const OwnedArray& operator= (const OwnedArray&);
};

#endif   // __JUCE_OWNEDARRAY_JUCEHEADER__
/********* End of inlined file: juce_OwnedArray.h *********/

/********* Start of inlined file: juce_Time.h *********/
#ifndef __JUCE_TIME_JUCEHEADER__
#define __JUCE_TIME_JUCEHEADER__

/********* Start of inlined file: juce_RelativeTime.h *********/
#ifndef __JUCE_RELATIVETIME_JUCEHEADER__
#define __JUCE_RELATIVETIME_JUCEHEADER__

/** A relative measure of time.

    The time is stored as a number of seconds, at double-precision floating
    point accuracy, and may be positive or negative.

    If you need an absolute time, (i.e. a date + time), see the Time class.
*/
class JUCE_API  RelativeTime
{
public:

    /** Creates a RelativeTime.

        @param seconds  the number of seconds, which may be +ve or -ve.
        @see milliseconds, minutes, hours, days, weeks
    */
    explicit RelativeTime (const double seconds = 0.0) throw();

    /** Copies another relative time. */
    RelativeTime (const RelativeTime& other) throw();

    /** Copies another relative time. */
    const RelativeTime& operator= (const RelativeTime& other) throw();

    /** Destructor. */
    ~RelativeTime() throw();

    /** Creates a new RelativeTime object representing a number of milliseconds.

        @see minutes, hours, days, weeks
    */
    static const RelativeTime milliseconds (const int milliseconds) throw();

    /** Creates a new RelativeTime object representing a number of milliseconds.

        @see minutes, hours, days, weeks
    */
    static const RelativeTime milliseconds (const int64 milliseconds) throw();

    /** Creates a new RelativeTime object representing a number of minutes.

        @see milliseconds, hours, days, weeks
    */
    static const RelativeTime minutes (const double numberOfMinutes) throw();

    /** Creates a new RelativeTime object representing a number of hours.

        @see milliseconds, minutes, days, weeks
    */
    static const RelativeTime hours (const double numberOfHours) throw();

    /** Creates a new RelativeTime object representing a number of days.

        @see milliseconds, minutes, hours, weeks
    */
    static const RelativeTime days (const double numberOfDays) throw();

    /** Creates a new RelativeTime object representing a number of weeks.

        @see milliseconds, minutes, hours, days
    */
    static const RelativeTime weeks (const double numberOfWeeks) throw();

    /** Returns the number of milliseconds this time represents.

        @see milliseconds, inSeconds, inMinutes, inHours, inDays, inWeeks
    */
    int64 inMilliseconds() const throw();

    /** Returns the number of seconds this time represents.

        @see inMilliseconds, inMinutes, inHours, inDays, inWeeks
    */
    double inSeconds() const throw()        { return seconds; }

    /** Returns the number of minutes this time represents.

        @see inMilliseconds, inSeconds, inHours, inDays, inWeeks
    */
    double inMinutes() const throw();

    /** Returns the number of hours this time represents.

        @see inMilliseconds, inSeconds, inMinutes, inDays, inWeeks
    */
    double inHours() const throw();

    /** Returns the number of days this time represents.

        @see inMilliseconds, inSeconds, inMinutes, inHours, inWeeks
    */
    double inDays() const throw();

    /** Returns the number of weeks this time represents.

        @see inMilliseconds, inSeconds, inMinutes, inHours, inDays
    */
    double inWeeks() const throw();

    /** Returns a readable textual description of the time.

        The exact format of the string returned will depend on
        the magnitude of the time - e.g.

        "1 min 4 secs", "1 hr 45 mins", "2 weeks 5 days", "140 ms"

        so that only the two most significant units are printed.

        The returnValueForZeroTime value is the result that is returned if the
        length is zero. Depending on your application you might want to use this
        to return something more relevant like "empty" or "0 secs", etc.

        @see inMilliseconds, inSeconds, inMinutes, inHours, inDays, inWeeks
    */
    const String getDescription (const String& returnValueForZeroTime = JUCE_T("0")) const throw();

    /** Compares two RelativeTimes. */
    bool operator== (const RelativeTime& other) const throw();
    /** Compares two RelativeTimes. */
    bool operator!= (const RelativeTime& other) const throw();

    /** Compares two RelativeTimes. */
    bool operator>  (const RelativeTime& other) const throw();
    /** Compares two RelativeTimes. */
    bool operator<  (const RelativeTime& other) const throw();
    /** Compares two RelativeTimes. */
    bool operator>= (const RelativeTime& other) const throw();
    /** Compares two RelativeTimes. */
    bool operator<= (const RelativeTime& other) const throw();

    /** Adds another RelativeTime to this one and returns the result. */
    const RelativeTime  operator+  (const RelativeTime& timeToAdd) const throw();
    /** Subtracts another RelativeTime from this one and returns the result. */
    const RelativeTime  operator-  (const RelativeTime& timeToSubtract) const throw();

    /** Adds a number of seconds to this RelativeTime and returns the result. */
    const RelativeTime  operator+  (const double secondsToAdd) const throw();
    /** Subtracts a number of seconds from this RelativeTime and returns the result. */
    const RelativeTime  operator-  (const double secondsToSubtract) const throw();

    /** Adds another RelativeTime to this one. */
    const RelativeTime& operator+= (const RelativeTime& timeToAdd) throw();
    /** Subtracts another RelativeTime from this one. */
    const RelativeTime& operator-= (const RelativeTime& timeToSubtract) throw();

    /** Adds a number of seconds to this time. */
    const RelativeTime& operator+= (const double secondsToAdd) throw();

    /** Subtracts a number of seconds from this time. */
    const RelativeTime& operator-= (const double secondsToSubtract) throw();

    juce_UseDebuggingNewOperator

private:
    double seconds;
};

#endif   // __JUCE_RELATIVETIME_JUCEHEADER__
/********* End of inlined file: juce_RelativeTime.h *********/

/**
    Holds an absolute date and time.

    Internally, the time is stored at millisecond precision.

    @see RelativeTime
*/
class JUCE_API  Time
{
public:

    /** Creates a Time object.

        This default constructor creates a time of 1st January 1970, (which is
        represented internally as 0ms).

        To create a time object representing the current time, use getCurrentTime().

        @see getCurrentTime
    */
    Time() throw();

    /** Creates a copy of another Time object. */
    Time (const Time& other) throw();

    /** Creates a time based on a number of milliseconds.

        The internal millisecond count is set to 0 (1st January 1970). To create a
        time object set to the current time, use getCurrentTime().

        @param millisecondsSinceEpoch   the number of milliseconds since the unix
                                        'epoch' (midnight Jan 1st 1970).
        @see getCurrentTime, currentTimeMillis
    */
    Time (const int64 millisecondsSinceEpoch) throw();

    /** Creates a time from a set of date components.

        The timezone is assumed to be whatever the system is using as its locale.

        @param year             the year, in 4-digit format, e.g. 2004
        @param month            the month, in the range 0 to 11
        @param day              the day of the month, in the range 1 to 31
        @param hours            hours in 24-hour clock format, 0 to 23
        @param minutes          minutes 0 to 59
        @param seconds          seconds 0 to 59
        @param milliseconds     milliseconds 0 to 999
        @param useLocalTime     if true, encode using the current machine's local time; if
                                false, it will always work in GMT.
    */
    Time (const int year,
          const int month,
          const int day,
          const int hours,
          const int minutes,
          const int seconds = 0,
          const int milliseconds = 0,
          const bool useLocalTime = true) throw();

    /** Destructor. */
    ~Time() throw();

    /** Copies this time from another one. */
    const Time& operator= (const Time& other) throw();

    /** Returns a Time object that is set to the current system time.

        @see currentTimeMillis
    */
    static const Time JUCE_CALLTYPE getCurrentTime() throw();

    /** Returns the time as a number of milliseconds.

        @returns    the number of milliseconds this Time object represents, since
                    midnight jan 1st 1970.
        @see getMilliseconds
    */
    int64 toMilliseconds() const throw()                            { return millisSinceEpoch; }

    /** Returns the year.

        A 4-digit format is used, e.g. 2004.
    */
    int getYear() const throw();

    /** Returns the number of the month.

        The value returned is in the range 0 to 11.
        @see getMonthName
    */
    int getMonth() const throw();

    /** Returns the name of the month.

        @param threeLetterVersion   if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false
                                    it'll return the long form, e.g. "January"
        @see getMonth
    */
    const String getMonthName (const bool threeLetterVersion) const throw();

    /** Returns the day of the month.

        The value returned is in the range 1 to 31.
    */
    int getDayOfMonth() const throw();

    /** Returns the number of the day of the week.

        The value returned is in the range 0 to 6 (0 = sunday, 1 = monday, etc).
    */
    int getDayOfWeek() const throw();

    /** Returns the name of the weekday.

        @param threeLetterVersion   if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if
                                    false, it'll return the full version, e.g. "Tuesday".
    */
    const String getWeekdayName (const bool threeLetterVersion) const throw();

    /** Returns the number of hours since midnight.

        This is in 24-hour clock format, in the range 0 to 23.

        @see getHoursInAmPmFormat, isAfternoon
    */
    int getHours() const throw();

    /** Returns true if the time is in the afternoon.

        So it returns true for "PM", false for "AM".

        @see getHoursInAmPmFormat, getHours
    */
    bool isAfternoon() const throw();

    /** Returns the hours in 12-hour clock format.

        This will return a value 1 to 12 - use isAfternoon() to find out
        whether this is in the afternoon or morning.

        @see getHours, isAfternoon
    */
    int getHoursInAmPmFormat() const throw();

    /** Returns the number of minutes, 0 to 59. */
    int getMinutes() const throw();

    /** Returns the number of seconds, 0 to 59. */
    int getSeconds() const throw();

    /** Returns the number of milliseconds, 0 to 999.

        Unlike toMilliseconds(), this just returns the position within the
        current second rather than the total number since the epoch.

        @see toMilliseconds
    */
    int getMilliseconds() const throw();

    /** Returns true if the local timezone uses a daylight saving correction. */
    bool isDaylightSavingTime() const throw();

    /** Returns a 3-character string to indicate the local timezone. */
    const String getTimeZone() const throw();

    /** Quick way of getting a string version of a date and time.

        For a more powerful way of formatting the date and time, see the formatted() method.

        @param includeDate      whether to include the date in the string
        @param includeTime      whether to include the time in the string
        @param includeSeconds   if the time is being included, this provides an option not to include
                                the seconds in it
        @param use24HourClock   if the time is being included, sets whether to use am/pm or 24
                                hour notation.
        @see formatted
    */
    const String toString (const bool includeDate,
                           const bool includeTime,
                           const bool includeSeconds = true,
                           const bool use24HourClock = false) const throw();

    /** Converts this date/time to a string with a user-defined format.

        This uses the C strftime() function to format this time as a string. To save you
        looking it up, these are the escape codes that strftime uses (other codes might
        work on some platforms and not others, but these are the common ones):

        %a  is replaced by the locale's abbreviated weekday name.
        %A  is replaced by the locale's full weekday name.
        %b  is replaced by the locale's abbreviated month name.
        %B  is replaced by the locale's full month name.
        %c  is replaced by the locale's appropriate date and time representation.
        %d  is replaced by the day of the month as a decimal number [01,31].
        %H  is replaced by the hour (24-hour clock) as a decimal number [00,23].
        %I  is replaced by the hour (12-hour clock) as a decimal number [01,12].
        %j  is replaced by the day of the year as a decimal number [001,366].
        %m  is replaced by the month as a decimal number [01,12].
        %M  is replaced by the minute as a decimal number [00,59].
        %p  is replaced by the locale's equivalent of either a.m. or p.m.
        %S  is replaced by the second as a decimal number [00,61].
        %U  is replaced by the week number of the year (Sunday as the first day of the week) as a decimal number [00,53].
        %w  is replaced by the weekday as a decimal number [0,6], with 0 representing Sunday.
        %W  is replaced by the week number of the year (Monday as the first day of the week) as a decimal number [00,53]. All days in a new year preceding the first Monday are considered to be in week 0.
        %x  is replaced by the locale's appropriate date representation.
        %X  is replaced by the locale's appropriate time representation.
        %y  is replaced by the year without century as a decimal number [00,99].
        %Y  is replaced by the year with century as a decimal number.
        %Z  is replaced by the timezone name or abbreviation, or by no bytes if no timezone information exists.
        %%  is replaced by %.

        @see toString
    */
    const String formatted (const tchar* const format) const throw();

    /** Adds a RelativeTime to this time and returns the result. */
    const Time operator+ (const RelativeTime& delta) const throw()  { return Time (millisSinceEpoch + delta.inMilliseconds()); }

    /** Subtracts a RelativeTime from this time and returns the result. */
    const Time operator- (const RelativeTime& delta) const throw()  { return Time (millisSinceEpoch - delta.inMilliseconds()); }

    /** Returns the relative time difference between this time and another one. */
    const RelativeTime operator- (const Time& other) const throw()  { return RelativeTime::milliseconds (millisSinceEpoch - other.millisSinceEpoch); }

    /** Compares two Time objects. */
    bool operator== (const Time& other) const throw()               { return millisSinceEpoch == other.millisSinceEpoch; }

    /** Compares two Time objects. */
    bool operator!= (const Time& other) const throw()               { return millisSinceEpoch != other.millisSinceEpoch; }

    /** Compares two Time objects. */
    bool operator<  (const Time& other) const throw()               { return millisSinceEpoch < other.millisSinceEpoch; }

    /** Compares two Time objects. */
    bool operator<= (const Time& other) const throw()               { return millisSinceEpoch <= other.millisSinceEpoch; }

    /** Compares two Time objects. */
    bool operator>  (const Time& other) const throw()               { return millisSinceEpoch > other.millisSinceEpoch; }

    /** Compares two Time objects. */
    bool operator>= (const Time& other) const throw()               { return millisSinceEpoch >= other.millisSinceEpoch; }

    /** Tries to set the computer's clock.

        @returns    true if this succeeds, although depending on the system, the
                    application might not have sufficient privileges to do this.
    */
    bool setSystemTimeToThisTime() const throw();

    /** Returns the name of a day of the week.

        @param dayNumber            the day, 0 to 6 (0 = sunday, 1 = monday, etc)
        @param threeLetterVersion   if true, it'll return a 3-letter abbreviation, e.g. "Tue"; if
                                    false, it'll return the full version, e.g. "Tuesday".
    */
    static const String getWeekdayName (int dayNumber,
                                        const bool threeLetterVersion) throw();

    /** Returns the name of one of the months.

        @param monthNumber  the month, 0 to 11
        @param threeLetterVersion   if true, it'll be a 3-letter abbreviation, e.g. "Jan"; if false
                                    it'll return the long form, e.g. "January"
    */
    static const String getMonthName (int monthNumber,
                                      const bool threeLetterVersion) throw();

    // Static methods for getting system timers directly..

    /** Returns the current system time.

        Returns the number of milliseconds since midnight jan 1st 1970.

        Should be accurate to within a few millisecs, depending on platform,
        hardware, etc.
    */
    static int64 currentTimeMillis() throw();

    /** Returns the number of millisecs since system startup.

        Should be accurate to within a few millisecs, depending on platform,
        hardware, etc.

        @see getApproximateMillisecondCounter
    */
    static uint32 getMillisecondCounter() throw();

    /** Returns the number of millisecs since system startup.

        Same as getMillisecondCounter(), but returns a more accurate value, using
        the high-res timer.

        @see getMillisecondCounter
    */
    static double getMillisecondCounterHiRes() throw();

    /** Waits until the getMillisecondCounter() reaches a given value.

        This will make the thread sleep as efficiently as it can while it's waiting.
    */
    static void waitForMillisecondCounter (const uint32 targetTime) throw();

    /** Less-accurate but faster version of getMillisecondCounter().

        This will return the last value that getMillisecondCounter() returned, so doesn't
        need to make a system call, but is less accurate - it shouldn't be more than
        100ms away from the correct time, though, so is still accurate enough for a
        lot of purposes.

        @see getMillisecondCounter
    */
    static uint32 getApproximateMillisecondCounter() throw();

    // High-resolution timers..

    /** Returns the current high-resolution counter's tick-count.

        This is a similar idea to getMillisecondCounter(), but with a higher
        resolution.

        @see getHighResolutionTicksPerSecond, highResolutionTicksToSeconds,
             secondsToHighResolutionTicks
    */
    static int64 getHighResolutionTicks() throw();

    /** Returns the resolution of the high-resolution counter in ticks per second.

        @see getHighResolutionTicks, highResolutionTicksToSeconds,
             secondsToHighResolutionTicks
    */
    static int64 getHighResolutionTicksPerSecond() throw();

    /** Converts a number of high-resolution ticks into seconds.

        @see getHighResolutionTicks, getHighResolutionTicksPerSecond,
             secondsToHighResolutionTicks
    */
    static double highResolutionTicksToSeconds (const int64 ticks) throw();

    /** Converts a number seconds into high-resolution ticks.

        @see getHighResolutionTicks, getHighResolutionTicksPerSecond,
             highResolutionTicksToSeconds
    */
    static int64 secondsToHighResolutionTicks (const double seconds) throw();

private:

    int64 millisSinceEpoch;
};

#endif   // __JUCE_TIME_JUCEHEADER__
/********* End of inlined file: juce_Time.h *********/

/********* Start of inlined file: juce_StringArray.h *********/
#ifndef __JUCE_STRINGARRAY_JUCEHEADER__
#define __JUCE_STRINGARRAY_JUCEHEADER__

/********* Start of inlined file: juce_VoidArray.h *********/
#ifndef __JUCE_VOIDARRAY_JUCEHEADER__
#define __JUCE_VOIDARRAY_JUCEHEADER__

/********* Start of inlined file: juce_Array.h *********/
#ifndef __JUCE_ARRAY_JUCEHEADER__
#define __JUCE_ARRAY_JUCEHEADER__

/**
    Holds a list of primitive objects, such as ints, doubles, or pointers.

    Examples of arrays are: Array<int> or Array<MyClass*>

    Note that when holding pointers to objects, the array doesn't take any ownership
    of the objects - for doing this, see the OwnedArray class or the ReferenceCountedArray class.

    If you're using a class or struct as the element type, it must be
    capable of being copied or moved with a straightforward memcpy, rather than
    needing construction and destruction code.

    For holding lists of strings, use the specialised class StringArray.

    To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
    TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.

    @see OwnedArray, ReferenceCountedArray, StringArray, CriticalSection
*/
template <class ElementType, class TypeOfCriticalSectionToUse = DummyCriticalSection>
class Array   : private ArrayAllocationBase <ElementType>
{
public:

    /** Creates an empty array.

        @param granularity  this is the size of increment by which the internal storage
        used by the array will grow. Only change it from the default if you know the
        array is going to be very big and needs to be able to grow efficiently.

        @see ArrayAllocationBase
    */
    Array (const int granularity = juceDefaultArrayGranularity) throw()
       : ArrayAllocationBase <ElementType> (granularity),
         numUsed (0)
    {
    }

    /** Creates a copy of another array.
        @param other    the array to copy
    */
    Array (const Array<ElementType, TypeOfCriticalSectionToUse>& other) throw()
       : ArrayAllocationBase <ElementType> (other.granularity)
    {
        other.lockArray();
        numUsed = other.numUsed;
        this->setAllocatedSize (other.numUsed);
        memcpy (this->elements, other.elements, numUsed * sizeof (ElementType));
        other.unlockArray();
    }

    /** Initalises from a null-terminated C array of values.

        @param values   the array to copy from
    */
    Array (const ElementType* values) throw()
       : ArrayAllocationBase <ElementType> (juceDefaultArrayGranularity),
         numUsed (0)
    {
        while (*values != 0)
            add (*values++);
    }

    /** Initalises from a C array of values.

        @param values       the array to copy from
        @param numValues    the number of values in the array
    */
    Array (const ElementType* values, int numValues) throw()
       : ArrayAllocationBase <ElementType> (juceDefaultArrayGranularity),
         numUsed (numValues)
    {
        this->setAllocatedSize (numValues);
        memcpy (this->elements, values, numValues * sizeof (ElementType));
    }

    /** Destructor. */
    ~Array() throw()
    {
    }

    /** Copies another array.
        @param other    the array to copy
    */
    const Array <ElementType, TypeOfCriticalSectionToUse>& operator= (const Array <ElementType, TypeOfCriticalSectionToUse>& other) throw()
    {
        if (this != &other)
        {
            other.lockArray();
            lock.enter();

            this->granularity = other.granularity;
            this->ensureAllocatedSize (other.size());
            numUsed = other.numUsed;
            memcpy (this->elements, other.elements, this->numUsed * sizeof (ElementType));
            minimiseStorageOverheads();

            lock.exit();
            other.unlockArray();
        }

        return *this;
    }

    /** Compares this array to another one.
        Two arrays are considered equal if they both contain the same set of
        elements, in the same order.
        @param other    the other array to compare with
    */
    template <class OtherArrayType>
    bool operator== (const OtherArrayType& other) const throw()
    {
        lock.enter();

        if (this->numUsed != other.numUsed)
        {
            lock.exit();
            return false;
        }

        for (int i = numUsed; --i >= 0;)
        {
            if (this->elements [i] != other.elements [i])
            {
                lock.exit();
                return false;
            }
        }

        lock.exit();
        return true;
    }

    /** Compares this array to another one.
        Two arrays are considered equal if they both contain the same set of
        elements, in the same order.
        @param other    the other array to compare with
    */
    template <class OtherArrayType>
    bool operator!= (const OtherArrayType& other) const throw()
    {
        return ! operator== (other);
    }

    /** Removes all elements from the array.
        This will remove all the elements, and free any storage that the array is
        using. To clear the array without freeing the storage, use the clearQuick()
        method instead.

        @see clearQuick
    */
    void clear() throw()
    {
        lock.enter();
        this->setAllocatedSize (0);
        numUsed = 0;
        lock.exit();
    }

    /** Removes all elements from the array without freeing the array's allocated storage.

        @see clear
    */
    void clearQuick() throw()
    {
        lock.enter();
        numUsed = 0;
        lock.exit();
    }

    /** Returns the current number of elements in the array.
    */
    inline int size() const throw()
    {
        return numUsed;
    }

    /** Returns one of the elements in the array.
        If the index passed in is beyond the range of valid elements, this
        will return zero.

        If you're certain that the index will always be a valid element, you
        can call getUnchecked() instead, which is faster.

        @param index    the index of the element being requested (0 is the first element in the array)
        @see getUnchecked, getFirst, getLast
    */
    inline ElementType operator[] (const int index) const throw()
    {
        lock.enter();
        const ElementType result = (((unsigned int) index) < (unsigned int) numUsed)
                                        ? this->elements [index]
                                        : ElementType();
        lock.exit();

        return result;
    }

    /** Returns one of the elements in the array, without checking the index passed in.

        Unlike the operator[] method, this will try to return an element without
        checking that the index is within the bounds of the array, so should only
        be used when you're confident that it will always be a valid index.

        @param index    the index of the element being requested (0 is the first element in the array)
        @see operator[], getFirst, getLast
    */
    inline ElementType getUnchecked (const int index) const throw()
    {
        lock.enter();
        jassert (((unsigned int) index) < (unsigned int) numUsed);
        const ElementType result = this->elements [index];
        lock.exit();

        return result;
    }

    /** Returns a direct reference to one of the elements in the array, without checking the index passed in.

        This is like getUnchecked, but returns a direct reference to the element, so that
        you can alter it directly. Obviously this can be dangerous, so only use it when
        absolutely necessary.

        @param index    the index of the element being requested (0 is the first element in the array)
        @see operator[], getFirst, getLast
    */
    inline ElementType& getReference (const int index) const throw()
    {
        lock.enter();
        jassert (((unsigned int) index) < (unsigned int) numUsed);
        ElementType& result = this->elements [index];
        lock.exit();
        return result;
    }

    /** Returns the first element in the array, or 0 if the array is empty.

        @see operator[], getUnchecked, getLast
    */
    inline ElementType getFirst() const throw()
    {
        lock.enter();
        const ElementType result = (numUsed > 0) ? this->elements [0]
                                                 : ElementType();
        lock.exit();

        return result;
    }

    /** Returns the last element in the array, or 0 if the array is empty.

        @see operator[], getUnchecked, getFirst
    */
    inline ElementType getLast() const throw()
    {
        lock.enter();
        const ElementType result = (numUsed > 0) ? this->elements [numUsed - 1]
                                                 : ElementType();
        lock.exit();

        return result;
    }

    /** Finds the index of the first element which matches the value passed in.

        This will search the array for the given object, and return the index
        of its first occurrence. If the object isn't found, the method will return -1.

        @param elementToLookFor   the value or object to look for
        @returns                  the index of the object, or -1 if it's not found
    */
    int indexOf (const ElementType elementToLookFor) const throw()
    {
        int result = -1;

        lock.enter();
        const ElementType* e = this->elements;

        for (int i = numUsed; --i >= 0;)
        {
            if (elementToLookFor == *e)
            {
                result = (int) (e - this->elements);
                break;
            }

            ++e;
        }

        lock.exit();
        return result;
    }

    /** Returns true if the array contains at least one occurrence of an object.

        @param elementToLookFor     the value or object to look for
        @returns                    true if the item is found
    */
    bool contains (const ElementType elementToLookFor) const throw()
    {
        lock.enter();

        const ElementType* e = this->elements;
        int num = numUsed;

        while (num >= 4)
        {
            if (*e == elementToLookFor
                 || *++e == elementToLookFor
                 || *++e == elementToLookFor
                 || *++e == elementToLookFor)
            {
                lock.exit();
                return true;
            }

            num -= 4;
            ++e;
        }

        while (num > 0)
        {
            if (elementToLookFor == *e)
            {
                lock.exit();
                return true;
            }

            --num;
            ++e;
        }

        lock.exit();
        return false;
    }

    /** Appends a new element at the end of the array.

        @param newElement       the new object to add to the array
        @see set, insert, addIfNotAlreadyThere, addSorted, addArray
    */
    void add (const ElementType newElement) throw()
    {
        lock.enter();
        this->ensureAllocatedSize (numUsed + 1);
        this->elements [numUsed++] = newElement;
        lock.exit();
    }

    /** Inserts a new element into the array at a given position.

        If the index is less than 0 or greater than the size of the array, the
        element will be added to the end of the array.
        Otherwise, it will be inserted into the array, moving all the later elements
        along to make room.

        @param indexToInsertAt    the index at which the new element should be
                                  inserted (pass in -1 to add it to the end)
        @param newElement         the new object to add to the array
        @see add, addSorted, set
    */
    void insert (int indexToInsertAt, const ElementType newElement) throw()
    {
        lock.enter();
        this->ensureAllocatedSize (numUsed + 1);

        if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed)
        {
            ElementType* const insertPos = this->elements + indexToInsertAt;
            const int numberToMove = numUsed - indexToInsertAt;

            if (numberToMove > 0)
                memmove (insertPos + 1, insertPos, numberToMove * sizeof (ElementType));

            *insertPos = newElement;
            ++numUsed;
        }
        else
        {
            this->elements [numUsed++] = newElement;
        }

        lock.exit();
    }

    /** Inserts multiple copies of an element into the array at a given position.

        If the index is less than 0 or greater than the size of the array, the
        element will be added to the end of the array.
        Otherwise, it will be inserted into the array, moving all the later elements
        along to make room.

        @param indexToInsertAt    the index at which the new element should be inserted
        @param newElement         the new object to add to the array
        @param numberOfTimesToInsertIt  how many copies of the value to insert
        @see insert, add, addSorted, set
    */
    void insertMultiple (int indexToInsertAt, const ElementType newElement,
                         int numberOfTimesToInsertIt) throw()
    {
        if (numberOfTimesToInsertIt > 0)
        {
            lock.enter();
            this->ensureAllocatedSize (numUsed + numberOfTimesToInsertIt);

            if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed)
            {
                ElementType* insertPos = this->elements + indexToInsertAt;
                const int numberToMove = numUsed - indexToInsertAt;

                memmove (insertPos + numberOfTimesToInsertIt, insertPos, numberToMove * sizeof (ElementType));
                numUsed += numberOfTimesToInsertIt;

                while (--numberOfTimesToInsertIt >= 0)
                    *insertPos++ = newElement;
            }
            else
            {
                while (--numberOfTimesToInsertIt >= 0)
                    this->elements [numUsed++] = newElement;
            }

            lock.exit();
        }
    }

    /** Inserts an array of values into this array at a given position.

        If the index is less than 0 or greater than the size of the array, the
        new elements will be added to the end of the array.
        Otherwise, they will be inserted into the array, moving all the later elements
        along to make room.

        @param indexToInsertAt      the index at which the first new element should be inserted
        @param newElements          the new values to add to the array
        @param numberOfElements     how many items are in the array
        @see insert, add, addSorted, set
    */
    void insertArray (int indexToInsertAt,
                      const ElementType* newElements,
                      int numberOfElements) throw()
    {
        if (numberOfElements > 0)
        {
            lock.enter();
            this->ensureAllocatedSize (numUsed + numberOfElements);

            if (((unsigned int) indexToInsertAt) < (unsigned int) numUsed)
            {
                ElementType* insertPos = this->elements + indexToInsertAt;
                const int numberToMove = numUsed - indexToInsertAt;

                memmove (insertPos + numberOfElements, insertPos, numberToMove * sizeof (ElementType));
                numUsed += numberOfElements;

                while (--numberOfElements >= 0)
                    *insertPos++ = *newElements++;
            }
            else
            {
                while (--numberOfElements >= 0)
                    this->elements [numUsed++] = *newElements++;
            }

            lock.exit();
        }
    }

    /** Appends a new element at the end of the array as long as the array doesn't
        already contain it.

        If the array already contains an element that matches the one passed in, nothing
        will be done.

        @param newElement   the new object to add to the array
    */
    void addIfNotAlreadyThere (const ElementType newElement) throw()
    {
        lock.enter();

        if (! contains (newElement))
            add (newElement);

        lock.exit();
    }

    /** Replaces an element with a new value.

        If the index is less than zero, this method does nothing.
        If the index is beyond the end of the array, the item is added to the end of the array.

        @param indexToChange    the index whose value you want to change
        @param newValue         the new value to set for this index.
        @see add, insert
    */
    void set (const int indexToChange,
              const ElementType newValue) throw()
    {
        jassert (indexToChange >= 0);

        if (indexToChange >= 0)
        {
            lock.enter();

            if (indexToChange < numUsed)
            {
                this->elements [indexToChange] = newValue;
            }
            else
            {
                this->ensureAllocatedSize (numUsed + 1);
                this->elements [numUsed++] = newValue;
            }

            lock.exit();
        }
    }

    /** Replaces an element with a new value without doing any bounds-checking.

        This just sets a value directly in the array's internal storage, so you'd
        better make sure it's in range!

        @param indexToChange    the index whose value you want to change
        @param newValue         the new value to set for this index.
        @see set, getUnchecked
    */
    void setUnchecked (const int indexToChange,
                       const ElementType newValue) throw()
    {
        lock.enter();
        jassert (((unsigned int) indexToChange) < (unsigned int) numUsed);
        this->elements [indexToChange] = newValue;
        lock.exit();
    }

    /** Adds elements from an array to the end of this array.

        @param elementsToAdd        the array of elements to add
        @param numElementsToAdd     how many elements are in this other array
        @see add
    */
    void addArray (const ElementType* elementsToAdd,
                   int numElementsToAdd) throw()
    {
        lock.enter();

        if (numElementsToAdd > 0)
        {
            this->ensureAllocatedSize (numUsed + numElementsToAdd);

            while (--numElementsToAdd >= 0)
                this->elements [numUsed++] = *elementsToAdd++;
        }

        lock.exit();
    }

    /** This swaps the contents of this array with those of another array.

        If you need to exchange two arrays, this is vastly quicker than using copy-by-value
        because it just swaps their internal pointers.
    */
    template <class OtherArrayType>
    void swapWithArray (OtherArrayType& otherArray) throw()
    {
        lock.enter();
        otherArray.lock.enter();
        swapVariables <int> (this->numUsed, otherArray.numUsed);
        swapVariables <ElementType*> (this->elements, otherArray.elements);
        swapVariables <int> (this->numAllocated, otherArray.numAllocated);
        otherArray.lock.exit();
        lock.exit();
    }

    /** Adds elements from another array to the end of this array.

        @param arrayToAddFrom       the array from which to copy the elements
        @param startIndex           the first element of the other array to start copying from
        @param numElementsToAdd     how many elements to add from the other array. If this
                                    value is negative or greater than the number of available elements,
                                    all available elements will be copied.
        @see add
    */
    template <class OtherArrayType>
    void addArray (const OtherArrayType& arrayToAddFrom,
                   int startIndex = 0,
                   int numElementsToAdd = -1) throw()
    {
        arrayToAddFrom.lockArray();
        lock.enter();
        jassert (this != &arrayToAddFrom);

        if (startIndex < 0)
        {
            jassertfalse
            startIndex = 0;
        }

        if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size())
            numElementsToAdd = arrayToAddFrom.size() - startIndex;

        this->addArray ((const ElementType*) (arrayToAddFrom.elements + startIndex), numElementsToAdd);

        lock.exit();
        arrayToAddFrom.unlockArray();
    }

    /** Inserts a new element into the array, assuming that the array is sorted.

        This will use a comparator to find the position at which the new element
        should go. If the array isn't sorted, the behaviour of this
        method will be unpredictable.

        @param comparator   the comparator to use to compare the elements - see the sort()
                            method for details about the form this object should take
        @param newElement   the new element to insert to the array
        @see add, sort
    */
    template <class ElementComparator>
    void addSorted (ElementComparator& comparator,
                    const ElementType newElement) throw()
    {
        lock.enter();
        insert (findInsertIndexInSortedArray (comparator, this->elements, newElement, 0, numUsed), newElement);
        lock.exit();
    }

    /** Finds the index of an element in the array, assuming that the array is sorted.

        This will use a comparator to do a binary-chop to find the index of the given
        element, if it exists. If the array isn't sorted, the behaviour of this
        method will be unpredictable.

        @param comparator           the comparator to use to compare the elements - see the sort()
                                    method for details about the form this object should take
        @param elementToLookFor     the element to search for
        @returns                    the index of the element, or -1 if it's not found
        @see addSorted, sort
    */
    template <class ElementComparator>
    int indexOfSorted (ElementComparator& comparator,
                       const ElementType elementToLookFor) const throw()
    {
        (void) comparator;  // if you pass in an object with a static compareElements() method, this
                            // avoids getting warning messages about the parameter being unused
        lock.enter();

        int start = 0;
        int end = numUsed;

        for (;;)
        {
            if (start >= end)
            {
                lock.exit();
                return -1;
            }
            else if (comparator.compareElements (elementToLookFor, this->elements [start]) == 0)
            {
                lock.exit();
                return start;
            }
            else
            {
                const int halfway = (start + end) >> 1;

                if (halfway == start)
                {
                    lock.exit();
                    return -1;
                }
                else if (comparator.compareElements (elementToLookFor, this->elements [halfway]) >= 0)
                    start = halfway;
                else
                    end = halfway;
            }
        }
    }

    /** Removes an element from the array.

        This will remove the element at a given index, and move back
        all the subsequent elements to close the gap.
        If the index passed in is out-of-range, nothing will happen.

        @param indexToRemove    the index of the element to remove
        @returns                the element that has been removed
        @see removeValue, removeRange
    */
    ElementType remove (const int indexToRemove) throw()
    {
        lock.enter();

        if (((unsigned int) indexToRemove) < (unsigned int) numUsed)
        {
            --numUsed;

            ElementType* const e = this->elements + indexToRemove;
            ElementType const removed = *e;
            const int numberToShift = numUsed - indexToRemove;

            if (numberToShift > 0)
                memmove (e, e + 1, numberToShift * sizeof (ElementType));

            if ((numUsed << 1) < this->numAllocated)
                minimiseStorageOverheads();

            lock.exit();
            return removed;
        }
        else
        {
            lock.exit();
            return ElementType();
        }
    }

    /** Removes an item from the array.

        This will remove the first occurrence of the given element from the array.
        If the item isn't found, no action is taken.

        @param valueToRemove   the object to try to remove
        @see remove, removeRange
    */
    void removeValue (const ElementType valueToRemove) throw()
    {
        lock.enter();
        ElementType* e = this->elements;

        for (int i = numUsed; --i >= 0;)
        {
            if (valueToRemove == *e)
            {
                remove ((int) (e - this->elements));
                break;
            }

            ++e;
        }

        lock.exit();
    }

    /** Removes a range of elements from the array.

        This will remove a set of elements, starting from the given index,
        and move subsequent elements down to close the gap.

        If the range extends beyond the bounds of the array, it will
        be safely clipped to the size of the array.

        @param startIndex       the index of the first element to remove
        @param numberToRemove   how many elements should be removed
        @see remove, removeValue
    */
    void removeRange (int startIndex,
                      const int numberToRemove) throw()
    {
        lock.enter();
        const int endIndex = jlimit (0, numUsed, startIndex + numberToRemove);
        startIndex = jlimit (0, numUsed, startIndex);

        if (endIndex > startIndex)
        {
            const int rangeSize = endIndex - startIndex;
            ElementType* e = this->elements + startIndex;
            int numToShift = numUsed - endIndex;
            numUsed -= rangeSize;

            while (--numToShift >= 0)
            {
                *e = e [rangeSize];
                ++e;
            }

            if ((numUsed << 1) < this->numAllocated)
                minimiseStorageOverheads();
        }

        lock.exit();
    }

    /** Removes the last n elements from the array.

        @param howManyToRemove   how many elements to remove from the end of the array
        @see remove, removeValue, removeRange
    */
    void removeLast (const int howManyToRemove = 1) throw()
    {
        lock.enter();
        numUsed = jmax (0, numUsed - howManyToRemove);

        if ((numUsed << 1) < this->numAllocated)
            minimiseStorageOverheads();

        lock.exit();
    }

    /** Removes any elements which are also in another array.

        @param otherArray   the other array in which to look for elements to remove
        @see removeValuesNotIn, remove, removeValue, removeRange
    */
    template <class OtherArrayType>
    void removeValuesIn (const OtherArrayType& otherArray) throw()
    {
        otherArray.lockArray();
        lock.enter();

        if (this == &otherArray)
        {
            clear();
        }
        else
        {
            if (otherArray.size() > 0)
            {
                for (int i = numUsed; --i >= 0;)
                    if (otherArray.contains (this->elements [i]))
                        remove (i);
            }
        }

        lock.exit();
        otherArray.unlockArray();
    }

    /** Removes any elements which are not found in another array.

        Only elements which occur in this other array will be retained.

        @param otherArray    the array in which to look for elements NOT to remove
        @see removeValuesIn, remove, removeValue, removeRange
    */
    template <class OtherArrayType>
    void removeValuesNotIn (const OtherArrayType& otherArray) throw()
    {
        otherArray.lockArray();
        lock.enter();

        if (this != &otherArray)
        {
            if (otherArray.size() <= 0)
            {
                clear();
            }
            else
            {
                for (int i = numUsed; --i >= 0;)
                    if (! otherArray.contains (this->elements [i]))
                        remove (i);
            }
        }

        lock.exit();
        otherArray.unlockArray();
    }

    /** Swaps over two elements in the array.

        This swaps over the elements found at the two indexes passed in.
        If either index is out-of-range, this method will do nothing.

        @param index1   index of one of the elements to swap
        @param index2   index of the other element to swap
    */
    void swap (const int index1,
               const int index2) throw()
    {
        lock.enter();

        if (((unsigned int) index1) < (unsigned int) numUsed
            && ((unsigned int) index2) < (unsigned int) numUsed)
        {
            swapVariables (this->elements [index1],
                           this->elements [index2]);
        }

        lock.exit();
    }

    /** Moves one of the values to a different position.

        This will move the value to a specified index, shuffling along
        any intervening elements as required.

        So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
        move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.

        @param currentIndex     the index of the value to be moved. If this isn't a
                                valid index, then nothing will be done
        @param newIndex         the index at which you'd like this value to end up. If this
                                is less than zero, the value will be moved to the end
                                of the array
    */
    void move (const int currentIndex,
               int newIndex) throw()
    {
        if (currentIndex != newIndex)
        {
            lock.enter();

            if (((unsigned int) currentIndex) < (unsigned int) numUsed)
            {
                if (((unsigned int) newIndex) >= (unsigned int) numUsed)
                    newIndex = numUsed - 1;

                const ElementType value = this->elements [currentIndex];

                if (newIndex > currentIndex)
                {
                    memmove (this->elements + currentIndex,
                             this->elements + currentIndex + 1,
                             (newIndex - currentIndex) * sizeof (ElementType));
                }
                else
                {
                    memmove (this->elements + newIndex + 1,
                             this->elements + newIndex,
                             (currentIndex - newIndex) * sizeof (ElementType));
                }

                this->elements [newIndex] = value;
            }

            lock.exit();
        }
    }

    /** Reduces the amount of storage being used by the array.

        Arrays typically allocate slightly more storage than they need, and after
        removing elements, they may have quite a lot of unused space allocated.
        This method will reduce the amount of allocated storage to a minimum.
    */
    void minimiseStorageOverheads() throw()
    {
        lock.enter();

        if (numUsed == 0)
        {
            this->setAllocatedSize (0);
        }
        else
        {
            const int newAllocation = this->granularity * (numUsed / this->granularity + 1);

            if (newAllocation < this->numAllocated)
                this->setAllocatedSize (newAllocation);
        }

        lock.exit();
    }

    /** Increases the array's internal storage to hold a minimum number of elements.

        Calling this before adding a large known number of elements means that
        the array won't have to keep dynamically resizing itself as the elements
        are added, and it'll therefore be more efficient.
    */
    void ensureStorageAllocated (const int minNumElements) throw()
    {
        this->ensureAllocatedSize (minNumElements);
    }

    /** Sorts the elements in the array.

        This will use a comparator object to sort the elements into order. The object
        passed must have a method of the form:
        @code
        int compareElements (ElementType first, ElementType second);
        @endcode

        ..and this method must return:
          - a value of < 0 if the first comes before the second
          - a value of 0 if the two objects are equivalent
          - a value of > 0 if the second comes before the first

        To improve performance, the compareElements() method can be declared as static or const.

        @param comparator   the comparator to use for comparing elements.
        @param retainOrderOfEquivalentItems     if this is true, then items
                            which the comparator says are equivalent will be
                            kept in the order in which they currently appear
                            in the array. This is slower to perform, but may
                            be important in some cases. If it's false, a faster
                            algorithm is used, but equivalent elements may be
                            rearranged.

        @see addSorted, indexOfSorted, sortArray
    */
    template <class ElementComparator>
    void sort (ElementComparator& comparator,
               const bool retainOrderOfEquivalentItems = false) const throw()
    {
        (void) comparator;  // if you pass in an object with a static compareElements() method, this
                            // avoids getting warning messages about the parameter being unused
        lock.enter();
        sortArray (comparator, this->elements, 0, size() - 1, retainOrderOfEquivalentItems);
        lock.exit();
    }

    /** Locks the array's CriticalSection.

        Of course if the type of section used is a DummyCriticalSection, this won't
        have any effect.

        @see unlockArray
    */
    void lockArray() const throw()
    {
        lock.enter();
    }

    /** Unlocks the array's CriticalSection.

        Of course if the type of section used is a DummyCriticalSection, this won't
        have any effect.

        @see lockArray
    */
    void unlockArray() const throw()
    {
        lock.exit();
    }

    juce_UseDebuggingNewOperator

private:
    int numUsed;
    TypeOfCriticalSectionToUse lock;
};

#endif   // __JUCE_ARRAY_JUCEHEADER__
/********* End of inlined file: juce_Array.h *********/

/**
    A typedef for an Array of void*'s.

    VoidArrays are used in various places throughout the library instead of
    more strongly-typed arrays, to keep code-size low.
*/
typedef Array <void*> VoidArray;

#endif   // __JUCE_VOIDARRAY_JUCEHEADER__
/********* End of inlined file: juce_VoidArray.h *********/

#ifndef DOXYGEN
 // (used in StringArray::appendNumbersToDuplicates)
 static const tchar* const defaultPreNumberString  = JUCE_T(" (");
 static const tchar* const defaultPostNumberString = JUCE_T(")");
#endif

/**
    A special array for holding a list of strings.

    @see String, StringPairArray
*/
class JUCE_API  StringArray
{
public:

    /** Creates an empty string array */
    StringArray() throw();

    /** Creates a copy of another string array */
    StringArray (const StringArray& other) throw();

    /** Creates a copy of an array of string literals.

        @param strings          an array of strings to add. Null pointers in the array will be
                                treated as empty strings
        @param numberOfStrings  how many items there are in the array
    */
    StringArray (const juce_wchar** const strings,
                 const int numberOfStrings) throw();

    /** Creates a copy of an array of string literals.

        @param strings          an array of strings to add. Null pointers in the array will be
                                treated as empty strings
        @param numberOfStrings  how many items there are in the array
    */
    StringArray (const char** const strings,
                 const int numberOfStrings) throw();

    /** Creates a copy of a null-terminated array of string literals.

        Each item from the array passed-in is added, until it encounters a null pointer,
        at which point it stops.
    */
    StringArray (const juce_wchar** const strings) throw();

    /** Creates a copy of a null-terminated array of string literals.

        Each item from the array passed-in is added, until it encounters a null pointer,
        at which point it stops.
    */
    StringArray (const char** const strings) throw();

    /** Destructor. */
    virtual ~StringArray() throw();

    /** Copies the contents of another string array into this one */
    const StringArray& operator= (const StringArray& other) throw();

    /** Compares two arrays.

        Comparisons are case-sensitive.

        @returns    true only if the other array contains exactly the same strings in the same order
    */
    bool operator== (const StringArray& other) const throw();

    /** Compares two arrays.

        Comparisons are case-sensitive.

        @returns    false if the other array contains exactly the same strings in the same order
    */
    bool operator!= (const StringArray& other) const throw();

    /** Returns the number of strings in the array */
    inline int size() const throw()                                     { return strings.size(); };

    /** Returns one of the strings from the array.

        If the index is out-of-range, an empty string is returned.

        Obviously the reference returned shouldn't be stored for later use, as the
        string it refers to may disappear when the array changes.
    */
    const String& operator[] (const int index) const throw();

    /** Searches for a string in the array.

        The comparison will be case-insensitive if the ignoreCase parameter is true.

        @returns    true if the string is found inside the array
    */
    bool contains (const String& stringToLookFor,
                   const bool ignoreCase = false) const throw();

    /** Searches for a string in the array.

        The comparison will be case-insensitive if the ignoreCase parameter is true.

        @param stringToLookFor  the string to try to find
        @param ignoreCase       whether the comparison should be case-insensitive
        @param startIndex       the first index to start searching from
        @returns                the index of the first occurrence of the string in this array,
                                or -1 if it isn't found.
    */
    int indexOf (const String& stringToLookFor,
                 const bool ignoreCase = false,
                 int startIndex = 0) const throw();

    /** Appends a string at the end of the array. */
    void add (const String& stringToAdd) throw();

    /** Inserts a string into the array.

        This will insert a string into the array at the given index, moving
        up the other elements to make room for it.
        If the index is less than zero or greater than the size of the array,
        the new string will be added to the end of the array.
    */
    void insert (const int index,
                 const String& stringToAdd) throw();

    /** Adds a string to the array as long as it's not already in there.

        The search can optionally be case-insensitive.
    */
    void addIfNotAlreadyThere (const String& stringToAdd,
                               const bool ignoreCase = false) throw();

    /** Replaces one of the strings in the array with another one.

        If the index is higher than the array's size, the new string will be
        added to the end of the array; if it's less than zero nothing happens.
    */
    void set (const int index,
              const String& newString) throw();

    /** Appends some strings from another array to the end of this one.

        @param other                the array to add
        @param startIndex           the first element of the other array to add
        @param numElementsToAdd     the maximum number of elements to add (if this is
                                    less than zero, they are all added)
    */
    void addArray (const StringArray& other,
                   int startIndex = 0,
                   int numElementsToAdd = -1) throw();

    /** Breaks up a string into tokens and adds them to this array.

        This will tokenise the given string using whitespace characters as the
        token delimiters, and will add these tokens to the end of the array.

        @returns    the number of tokens added
    */
    int addTokens (const tchar* const stringToTokenise,
                   const bool preserveQuotedStrings) throw();

    /** Breaks up a string into tokens and adds them to this array.

        This will tokenise the given string (using the string passed in to define the
        token delimiters), and will add these tokens to the end of the array.

        @param stringToTokenise     the string to tokenise
        @param breakCharacters      a string of characters, any of which will be considered
                                    to be a token delimiter.
        @param quoteCharacters      if this string isn't empty, it defines a set of characters
                                    which are treated as quotes. Any text occurring
                                    between quotes is not broken up into tokens.
        @returns    the number of tokens added
    */
    int addTokens (const tchar* const stringToTokenise,
                   const tchar* breakCharacters,
                   const tchar* quoteCharacters) throw();

    /** Breaks up a string into lines and adds them to this array.

        This breaks a string down into lines separated by \\n or \\r\\n, and adds each line
        to the array. Line-break characters are omitted from the strings that are added to
        the array.
    */
    int addLines (const tchar* stringToBreakUp) throw();

    /** Removes all elements from the array. */
    void clear() throw();

    /** Removes a string from the array.

        If the index is out-of-range, no action will be taken.
    */
    void remove (const int index) throw();

    /** Finds a string in the array and removes it.

        This will remove the first occurrence of the given string from the array. The
        comparison may be case-insensitive depending on the ignoreCase parameter.
    */
    void removeString (const String& stringToRemove,
                       const bool ignoreCase = false) throw();

    /** Removes any duplicated elements from the array.

        If any string appears in the array more than once, only the first occurrence of
        it will be retained.

        @param ignoreCase   whether to use a case-insensitive comparison
    */
    void removeDuplicates (const bool ignoreCase) throw();

    /** Removes empty strings from the array.

        @param removeWhitespaceStrings  if true, strings that only contain whitespace
                                        characters will also be removed
    */
    void removeEmptyStrings (const bool removeWhitespaceStrings = true) throw();

    /** Moves one of the strings to a different position.

        This will move the string to a specified index, shuffling along
        any intervening elements as required.

        So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
        move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.

        @param currentIndex     the index of the value to be moved. If this isn't a
                                valid index, then nothing will be done
        @param newIndex         the index at which you'd like this value to end up. If this
                                is less than zero, the value will be moved to the end
                                of the array
    */
    void move (const int currentIndex, int newIndex) throw();

    /** Deletes any whitespace characters from the starts and ends of all the strings. */
    void trim() throw();

    /** Adds numbers to the strings in the array, to make each string unique.

        This will add numbers to the ends of groups of similar strings.
        e.g. if there are two "moose" strings, they will become "moose (1)" and "moose (2)"

        @param ignoreCaseWhenComparing      whether the comparison used is case-insensitive
        @param appendNumberToFirstInstance  whether the first of a group of similar strings
                                            also has a number appended to it.
        @param preNumberString              when adding a number, this string is added before the number
        @param postNumberString             this string is appended after any numbers that are added
    */
    void appendNumbersToDuplicates (const bool ignoreCaseWhenComparing,
                                    const bool appendNumberToFirstInstance,
                                    const tchar* const preNumberString = defaultPreNumberString,
                                    const tchar* const postNumberString = defaultPostNumberString) throw();

    /** Joins the strings in the array together into one string.

        This will join a range of elements from the array into a string, separating
        them with a given string.

        e.g. joinIntoString (",") will turn an array of "a" "b" and "c" into "a,b,c".

        @param separatorString      the string to insert between all the strings
        @param startIndex           the first element to join
        @param numberOfElements     how many elements to join together. If this is less
                                    than zero, all available elements will be used.
    */
    const String joinIntoString (const String& separatorString,
                                 int startIndex = 0,
                                 int numberOfElements = -1) const throw();

    /** Sorts the array into alphabetical order.

        @param ignoreCase       if true, the comparisons used will be case-sensitive.
    */
    void sort (const bool ignoreCase) throw();

    /** Reduces the amount of storage being used by the array.

        Arrays typically allocate slightly more storage than they need, and after
        removing elements, they may have quite a lot of unused space allocated.
        This method will reduce the amount of allocated storage to a minimum.
    */
    void minimiseStorageOverheads() throw();

    juce_UseDebuggingNewOperator

private:
    VoidArray strings;
};

#endif   // __JUCE_STRINGARRAY_JUCEHEADER__
/********* End of inlined file: juce_StringArray.h *********/

/********* Start of inlined file: juce_MemoryBlock.h *********/
#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__
#define __JUCE_MEMORYBLOCK_JUCEHEADER__

/**
    A class to hold a resizable block of raw data.

*/
class JUCE_API  MemoryBlock
{
public:

    /** Create an uninitialised block with 0 size. */
    MemoryBlock() throw();

    /** Creates a memory block with a given initial size.

        @param initialSize          the size of block to create
        @param initialiseToZero     whether to clear the memory or just leave it uninitialised
    */
    MemoryBlock (const int initialSize,
                 const bool initialiseToZero = false) throw();

    /** Creates a copy of another memory block. */
    MemoryBlock (const MemoryBlock& other) throw();

    /** Creates a memory block using a copy of a block of data.

        @param dataToInitialiseFrom     some data to copy into this block
        @param sizeInBytes              how much space to use
    */
    MemoryBlock (const void* const dataToInitialiseFrom,
                 const int sizeInBytes) throw();

    /** Destructor. */
    ~MemoryBlock() throw();

    /** Copies another memory block onto this one.

        This block will be resized and copied to exactly match the other one.
    */
    const MemoryBlock& operator= (const MemoryBlock& other) throw();

    /** Compares two memory blocks.

        @returns true only if the two blocks are the same size and have identical contents.
    */
    bool operator== (const MemoryBlock& other) const throw();

    /** Compares two memory blocks.

        @returns true if the two blocks are different sizes or have different contents.
    */
    bool operator!= (const MemoryBlock& other) const throw();

    /** Returns a pointer to the data, casting it to any type of primitive data required.

        Note that the pointer returned will probably become invalid when the
        block is resized.
    */
    template <class DataType>
    operator DataType*() const throw()                              { return (DataType*) data; }

    /** Returns a void pointer to the data.

        Note that the pointer returned will probably become invalid when the
        block is resized.
    */
    void* getData() const throw()                                   { return data; }

    /** Returns a byte from the memory block.

        This returns a reference, so you can also use it to set a byte.
    */
    char& operator[] (const int offset) const throw()               { return data [offset]; }

    /** Returns the block's current allocated size, in bytes. */
    int getSize() const throw()                                     { return size; }

    /** Resizes the memory block.

        This will try to keep as much of the block's current content as it can,
        and can optionally be made to clear any new space that gets allocated at
        the end of the block.

        @param newSize                      the new desired size for the block
        @param initialiseNewSpaceToZero     if the block gets enlarged, this determines
                                            whether to clear the new section or just leave it
                                            uninitialised
        @see ensureSize
    */
    void setSize (const int newSize,
                  const bool initialiseNewSpaceToZero = false) throw();

    /** Increases the block's size only if it's smaller than a given size.

        @param minimumSize                  if the block is already bigger than this size, no action
                                            will be taken; otherwise it will be increased to this size
        @param initialiseNewSpaceToZero     if the block gets enlarged, this determines
                                            whether to clear the new section or just leave it
                                            uninitialised
        @see setSize
    */
    void ensureSize (const int minimumSize,
                     const bool initialiseNewSpaceToZero = false) throw();

    /** Fills the entire memory block with a repeated byte value.

        This is handy for clearing a block of memory to zero.
    */
    void fillWith (const uint8 valueToUse) throw();

    /** Adds another block of data to the end of this one.

        This block's size will be increased accordingly.
    */
    void append (const void* const data,
                 const int numBytes) throw();

    /** Copies data into this MemoryBlock from a memory address.

        @param srcData              the memory location of the data to copy into this block
        @param destinationOffset    the offset in this block at which the data being copied should begin
        @param numBytes             how much to copy in (if this goes beyond the size of the memory block,
                                    it will be clipped so not to do anything nasty)
    */
    void copyFrom (const void* srcData,
                   int destinationOffset,
                   int numBytes) throw();

    /** Copies data from this MemoryBlock to a memory address.

        @param destData         the memory location to write to
        @param sourceOffset     the offset within this block from which the copied data will be read
        @param numBytes         how much to copy (if this extends beyond the limits of the memory block,
                                zeros will be used for that portion of the data)
    */
    void copyTo (void* destData,
                 int sourceOffset,
                 int numBytes) const throw();

    /** Chops out a section  of the block.

        This will remove a section of the memory block and close the gap around it,
        shifting any subsequent data downwards and reducing the size of the block.

        If the range specified goes beyond the size of the block, it will be clipped.
    */
    void removeSection (int startByte, int numBytesToRemove) throw();

    /** Attempts to parse the contents of the block as a zero-terminated string of 8-bit
        characters in the system's default encoding. */
    const String toString() const throw();

    /** Parses a string of hexadecimal numbers and writes this data into the memory block.

        The block will be resized to the number of valid bytes read from the string.
        Non-hex characters in the string will be ignored.

        @see String::toHexString()
    */
    void loadFromHexString (const String& sourceHexString) throw();

    /** Sets a number of bits in the memory block, treating it as a long binary sequence. */
    void setBitRange (int bitRangeStart,
                      int numBits,
                      int binaryNumberToApply) throw();

    /** Reads a number of bits from the memory block, treating it as one long binary sequence */
    int getBitRange (int bitRangeStart,
                     int numBitsToRead) const throw();

    /** Returns a string of characters that represent the binary contents of this block.

        Uses a 64-bit encoding system to allow binary data to be turned into a string
        of simple non-extended characters, e.g. for storage in XML.

        @see fromBase64Encoding
    */
    const String toBase64Encoding() const throw();

    /** Takes a string of encoded characters and turns it into binary data.

        The string passed in must have been created by to64BitEncoding(), and this
        block will be resized to recreate the original data block.

        @see toBase64Encoding
    */
    bool fromBase64Encoding  (const String& encodedString) throw();

    juce_UseDebuggingNewOperator

private:

    char* data;
    int size;
};

#endif   // __JUCE_MEMORYBLOCK_JUCEHEADER__
/********* End of inlined file: juce_MemoryBlock.h *********/

class FileInputStream;
class FileOutputStream;

/**
    Represents a local file or directory.

    This class encapsulates the absolute pathname of a file or directory, and
    has methods for finding out about the file and changing its properties.

    To read or write to the file, there are methods for returning an input or
    output stream.

    @see FileInputStream, FileOutputStream
*/
class JUCE_API  File
{
public:

    /** Creates an (invalid) file object.

        The file is initially set to an empty path, so getFullPath() will return
        an empty string, and comparing the file to File::nonexistent will return
        true.

        You can use its operator= method to point it at a proper file.
    */
    File() throw()   {}

    /** Creates a file from an absolute path.

        If the path supplied is a relative path, it is taken to be relative
        to the current working directory (see File::getCurrentWorkingDirectory()),
        but this isn't a recommended way of creating a file, because you
        never know what the CWD is going to be.

        On the Mac/Linux, the path can include "~" notation for referring to
        user home directories.
    */
    File (const String& path) throw();

    /** Creates a copy of another file object. */
    File (const File& other) throw();

    /** Destructor. */
    ~File() throw()  {}

    /** Sets the file based on an absolute pathname.

        If the path supplied is a relative path, it is taken to be relative
        to the current working directory (see File::getCurrentWorkingDirectory()),
        but this isn't a recommended way of creating a file, because you
        never know what the CWD is going to be.

        On the Mac/Linux, the path can include "~" notation for referring to
        user home directories.
    */
    const File& operator= (const String& newFilePath) throw();

    /** Copies from another file object. */
    const File& operator= (const File& otherFile) throw();

    /** This static constant is used for referring to an 'invalid' file. */
    static const File nonexistent;

    /** Checks whether the file actually exists.

        @returns    true if the file exists, either as a file or a directory.
        @see existsAsFile, isDirectory
    */
    bool exists() const throw();

    /** Checks whether the file exists and is a file rather than a directory.

        @returns    true only if this is a real file, false if it's a directory
                    or doesn't exist
        @see exists, isDirectory
    */
    bool existsAsFile() const throw();

    /** Checks whether the file is a directory that exists.

        @returns    true only if the file is a directory which actually exists, so
                    false if it's a file or doesn't exist at all
        @see exists, existsAsFile
    */
    bool isDirectory() const throw();

    /** Returns the size of the file in bytes.

        @returns    the number of bytes in the file, or 0 if it doesn't exist.
    */
    int64 getSize() const throw();

    /** Utility function to convert a file size in bytes to a neat string description.

        So for example 100 would return "100 bytes", 2000 would return "2 KB",
        2000000 would produce "2 MB", etc.
    */
    static const String descriptionOfSizeInBytes (const int64 bytes);

    /** Returns the complete, absolute path of this file.

        This includes the filename and all its parent folders. On Windows it'll
        also include the drive letter prefix; on Mac or Linux it'll be a complete
        path starting from the root folder.

        If you just want the file's name, you should use getFileName() or
        getFileNameWithoutExtension().

        @see getFileName, getRelativePathFrom
    */
    const String& getFullPathName() const throw()    { return fullPath; }

    /** Returns the last section of the pathname.

        Returns just the final part of the path - e.g. if the whole path
        is "/moose/fish/foo.txt" this will return "foo.txt".

        For a directory, it returns the final part of the path - e.g. for the
        directory "/moose/fish" it'll return "fish".

        If the filename begins with a dot, it'll return the whole filename, e.g. for
        "/moose/.fish", it'll return ".fish"

        @see getFullPathName, getFileNameWithoutExtension
    */
    const String getFileName() const throw();

    /** Creates a relative path that refers to a file relatively to a given directory.

        e.g. File ("/moose/foo.txt").getRelativePathFrom ("/moose/fish/haddock")
             would return "../../foo.txt".

        If it's not possible to navigate from one file to the other, an absolute
        path is returned. If the paths are invalid, an empty string may also be
        returned.

        @param directoryToBeRelativeTo  the directory which the resultant string will
                                        be relative to. If this is actually a file rather than
                                        a directory, its parent directory will be used instead.
                                        If it doesn't exist, it's assumed to be a directory.
        @see getChildFile, isAbsolutePath
    */
    const String getRelativePathFrom (const File& directoryToBeRelativeTo) const throw();

    /** Returns the file's extension.

        Returns the file extension of this file, also including the dot.

        e.g. "/moose/fish/foo.txt" would return ".txt"

        @see hasFileExtension, withFileExtension, getFileNameWithoutExtension
    */
    const String getFileExtension() const throw();

    /** Checks whether the file has a given extension.

        @param extensionToTest  the extension to look for - it doesn't matter whether or
                                not this string has a dot at the start, so ".wav" and "wav"
                                will have the same effect. The comparison used is
                                case-insensitve.

        @see getFileExtension, withFileExtension, getFileNameWithoutExtension
    */
    bool hasFileExtension (const String& extensionToTest) const throw();

    /** Returns a version of this file with a different file extension.

        e.g. File ("/moose/fish/foo.txt").withFileExtension ("html") returns "/moose/fish/foo.html"

        @param newExtension     the new extension, either with or without a dot at the start (this
                                doesn't make any difference). To get remove a file's extension altogether,
                                pass an empty string into this function.

        @see getFileName, getFileExtension, hasFileExtension, getFileNameWithoutExtension
    */
    const File withFileExtension (const String& newExtension) const throw();

    /** Returns the last part of the filename, without its file extension.

        e.g. for "/moose/fish/foo.txt" this will return "foo".

        @see getFileName, getFileExtension, hasFileExtension, withFileExtension
    */
    const String getFileNameWithoutExtension() const throw();

    /** Returns a 32-bit hash-code that identifies this file.

        This is based on the filename. Obviously it's possible, although unlikely, that
        two files will have the same hash-code.
    */
    int hashCode() const throw();

    /** Returns a 64-bit hash-code that identifies this file.

        This is based on the filename. Obviously it's possible, although unlikely, that
        two files will have the same hash-code.
    */
    int64 hashCode64() const throw();

    /** Returns a file based on a relative path.

        This will find a child file or directory of the current object.

        e.g.
            File ("/moose/fish").getChildFile ("foo.txt") will produce "/moose/fish/foo.txt".
            File ("/moose/fish").getChildFile ("../foo.txt") will produce "/moose/foo.txt".

        If the string is actually an absolute path, it will be treated as such, e.g.
            File ("/moose/fish").getChildFile ("/foo.txt") will produce "/foo.txt"

        @see getSiblingFile, getParentDirectory, getRelativePathFrom, isAChildOf
    */
    const File getChildFile (String relativePath) const throw();

    /** Returns a file which is in the same directory as this one.

        This is equivalent to getParentDirectory().getChildFile (name).

        @see getChildFile, getParentDirectory
    */
    const File getSiblingFile (const String& siblingFileName) const throw();

    /** Returns the directory that contains this file or directory.

        e.g. for "/moose/fish/foo.txt" this will return "/moose/fish".
    */
    const File getParentDirectory() const throw();

    /** Checks whether a file is somewhere inside a directory.

        Returns true if this file is somewhere inside a subdirectory of the directory
        that is passed in. Neither file actually has to exist, because the function
        just checks the paths for similarities.

        e.g. File ("/moose/fish/foo.txt").isAChildOf ("/moose") is true.
             File ("/moose/fish/foo.txt").isAChildOf ("/moose/fish") is also true.
    */
    bool isAChildOf (const File& potentialParentDirectory) const throw();

    /** Chooses a filename relative to this one that doesn't already exist.

        If this file is a directory, this will return a child file of this
        directory that doesn't exist, by adding numbers to a prefix and suffix until
        it finds one that isn't already there.

        If the prefix + the suffix doesn't exist, it won't bother adding a number.

        e.g. File ("/moose/fish").getNonexistentChildFile ("foo", ".txt", true) might
             return "/moose/fish/foo(2).txt" if there's already a file called "foo.txt".

        @param prefix                   the string to use for the filename before the number
        @param suffix                   the string to add to the filename after the number
        @param putNumbersInBrackets     if true, this will create filenames in the
                                        format "prefix(number)suffix", if false, it will leave the
                                        brackets out.
    */
    const File getNonexistentChildFile (const String& prefix,
                                        const String& suffix,
                                        bool putNumbersInBrackets = true) const throw();

    /** Chooses a filename for a sibling file to this one that doesn't already exist.

        If this file doesn't exist, this will just return itself, otherwise it
        will return an appropriate sibling that doesn't exist, e.g. if a file
        "/moose/fish/foo.txt" exists, this might return "/moose/fish/foo(2).txt".

        @param putNumbersInBrackets     whether to add brackets around the numbers that
                                        get appended to the new filename.
    */
    const File getNonexistentSibling (const bool putNumbersInBrackets = true) const throw();

    /** Compares the pathnames for two files. */
    bool operator== (const File& otherFile) const throw();
    /** Compares the pathnames for two files. */
    bool operator!= (const File& otherFile) const throw();

    /** Checks whether a file can be created or written to.

        @returns    true if it's possible to create and write to this file. If the file
                    doesn't already exist, this will check its parent directory to
                    see if writing is allowed.
        @see setReadOnly
    */
    bool hasWriteAccess() const throw();

    /** Changes the write-permission of a file or directory.

        @param shouldBeReadOnly     whether to add or remove write-permission
        @param applyRecursively     if the file is a directory and this is true, it will
                                    recurse through all the subfolders changing the permissions
                                    of all files
        @returns    true if it manages to change the file's permissions.
        @see hasWriteAccess
    */
    bool setReadOnly (const bool shouldBeReadOnly,
                      const bool applyRecursively = false) const throw();

    /** Returns true if this file is a hidden or system file.

        The criteria for deciding whether a file is hidden are platform-dependent.
    */
    bool isHidden() const throw();

    /** If this file is a link, this returns the file that it points to.

        If this file isn't actually link, it'll just return itself.
    */
    const File getLinkedTarget() const throw();

    /** Returns the last modification time of this file.

        @returns    the time, or an invalid time if the file doesn't exist.
        @see setLastModificationTime, getLastAccessTime, getCreationTime
    */
    const Time getLastModificationTime() const throw();

    /** Returns the last time this file was accessed.

        @returns    the time, or an invalid time if the file doesn't exist.
        @see setLastAccessTime, getLastModificationTime, getCreationTime
    */
    const Time getLastAccessTime() const throw();

    /** Returns the time that this file was created.

        @returns    the time, or an invalid time if the file doesn't exist.
        @see getLastModificationTime, getLastAccessTime
    */
    const Time getCreationTime() const throw();

    /** Changes the modification time for this file.

        @param newTime  the time to apply to the file
        @returns true if it manages to change the file's time.
        @see getLastModificationTime, setLastAccessTime, setCreationTime
    */
    bool setLastModificationTime (const Time& newTime) const throw();

    /** Changes the last-access time for this file.

        @param newTime  the time to apply to the file
        @returns true if it manages to change the file's time.
        @see getLastAccessTime, setLastModificationTime, setCreationTime
    */
    bool setLastAccessTime (const Time& newTime) const throw();

    /** Changes the creation date for this file.

        @param newTime  the time to apply to the file
        @returns true if it manages to change the file's time.
        @see getCreationTime, setLastModificationTime, setLastAccessTime
    */
    bool setCreationTime (const Time& newTime) const throw();

    /** If possible, this will try to create a version string for the given file.

        The OS may be able to look at the file and give a version for it - e.g. with
        executables, bundles, dlls, etc. If no version is available, this will
        return an empty string.
    */
    const String getVersion() const throw();

    /** Creates an empty file if it doesn't already exist.

        If the file that this object refers to doesn't exist, this will create a file
        of zero size.

        If it already exists or is a directory, this method will do nothing.

        @returns    true if the file has been created (or if it already existed).
        @see createDirectory
    */
    bool create() const throw();

    /** Creates a new directory for this filename.

        This will try to create the file as a directory, and fill also create
        any parent directories it needs in order to complete the operation.

        @returns    true if the directory has been created successfully, (or if it
                    already existed beforehand).
        @see create
    */
    bool createDirectory() const throw();

    /** Deletes a file.

        If this file is actually a directory, it may not be deleted correctly if it
        contains files. See deleteRecursively() as a better way of deleting directories.

        @returns    true if the file has been successfully deleted (or if it didn't exist to
                    begin with).
        @see deleteRecursively
    */
    bool deleteFile() const throw();

    /** Deletes a file or directory and all its subdirectories.

        If this file is a directory, this will try to delete it and all its subfolders. If
        it's just a file, it will just try to delete the file.

        @returns    true if the file and all its subfolders have been successfully deleted
                    (or if it didn't exist to begin with).
        @see deleteFile
    */
    bool deleteRecursively() const throw();

    /** Moves this file or folder to the trash.

        @returns true if the operation succeeded. It could fail if the trash is full, or
                 if the file is write-protected, so you should check the return value
                 and act appropriately.
    */
    bool moveToTrash() const throw();

    /** Moves or renames a file.

        Tries to move a file to a different location.
        If the target file already exists, this will attempt to delete it first, and
        will fail if this can't be done.

        Note that the destination file isn't the directory to put it in, it's the actual
        filename that you want the new file to have.

        @returns    true if the operation succeeds
    */
    bool moveFileTo (const File& targetLocation) const throw();

    /** Copies a file.

        Tries to copy a file to a different location.
        If the target file already exists, this will attempt to delete it first, and
        will fail if this can't be done.

        @returns    true if the operation succeeds
    */
    bool copyFileTo (const File& targetLocation) const throw();

    /** Copies a directory.

        Tries to copy an entire directory, recursively.

        If this file isn't a directory or if any target files can't be created, this
        will return false.

        @param newDirectory    the directory that this one should be copied to. Note that this
                               is the name of the actual directory to create, not the directory
                               into which the new one should be placed, so there must be enough
                               write privileges to create it if it doesn't exist. Any files inside
                               it will be overwritten by similarly named ones that are copied.
    */
    bool copyDirectoryTo (const File& newDirectory) const throw();

    /** Used in file searching, to specify whether to return files, directories, or both.
    */
    enum TypesOfFileToFind
    {
        findDirectories             = 1,    /**< Use this flag to indicate that you want to find directories. */
        findFiles                   = 2,    /**< Use this flag to indicate that you want to find files. */
        findFilesAndDirectories     = 3,    /**< Use this flag to indicate that you want to find both files and directories. */
        ignoreHiddenFiles           = 4     /**< Add this flag to avoid returning any hidden files in the results. */
    };

    /** Searches inside a directory for files matching a wildcard pattern.

        Assuming that this file is a directory, this method will search it
        for either files or subdirectories whose names match a filename pattern.

        @param results                  an array to which File objects will be added for the
                                        files that the search comes up with
        @param whatToLookFor            a value from the TypesOfFileToFind enum, specifying whether to
                                        return files, directories, or both. If the ignoreHiddenFiles flag
                                        is also added to this value, hidden files won't be returned
        @param searchRecursively        if true, all subdirectories will be recursed into to do
                                        an exhaustive search
        @param wildCardPattern          the filename pattern to search for, e.g. "*.txt"
        @returns                        the number of results that have been found

        @see getNumberOfChildFiles, DirectoryIterator
    */
    int findChildFiles (OwnedArray<File>& results,
                        const int whatToLookFor,
                        const bool searchRecursively,
                        const String& wildCardPattern = JUCE_T("*")) const throw();

    /** Searches inside a directory and counts how many files match a wildcard pattern.

        Assuming that this file is a directory, this method will search it
        for either files or subdirectories whose names match a filename pattern,
        and will return the number of matches found.

        This isn't a recursive call, and will only search this directory, not
        its children.

        @param whatToLookFor    a value from the TypesOfFileToFind enum, specifying whether to
                                count files, directories, or both. If the ignoreHiddenFiles flag
                                is also added to this value, hidden files won't be counted
        @param wildCardPattern  the filename pattern to search for, e.g. "*.txt"
        @returns                the number of matches found
        @see findChildFiles, DirectoryIterator
    */
    int getNumberOfChildFiles (const int whatToLookFor,
                               const String& wildCardPattern = JUCE_T("*")) const throw();

    /** Returns true if this file is a directory that contains one or more subdirectories.
        @see isDirectory, findChildFiles
    */
    bool containsSubDirectories() const throw();

    /** Creates a stream to read from this file.

        @returns    a stream that will read from this file (initially positioned at the
                    start of the file), or 0 if the file can't be opened for some reason
        @see createOutputStream, loadFileAsData
    */
    FileInputStream* createInputStream() const throw();

    /** Creates a stream to write to this file.

        If the file exists, the stream that is returned will be positioned ready for
        writing at the end of the file, so you might want to use deleteFile() first
        to write to an empty file.

        @returns    a stream that will write to this file (initially positioned at the
                    end of the file), or 0 if the file can't be opened for some reason
        @see createInputStream, printf, appendData, appendText
    */
    FileOutputStream* createOutputStream (const int bufferSize = 0x8000) const throw();

    /** Loads a file's contents into memory as a block of binary data.

        Of course, trying to load a very large file into memory will blow up, so
        it's better to check first.

        @param result   the data block to which the file's contents should be appended - note
                        that if the memory block might already contain some data, you
                        might want to clear it first
        @returns        true if the file could all be read into memory
    */
    bool loadFileAsData (MemoryBlock& result) const throw();

    /** Reads a file into memory as a string.

        Attempts to load the entire file as a zero-terminated string.

        This makes use of InputStream::readEntireStreamAsString, which should
        automatically cope with unicode/acsii file formats.
    */
    const String loadFileAsString() const throw();

    /** Writes text to the end of the file.

        This will try to do a printf to the file.

        @returns  false if it can't write to the file for some reason
    */
    bool printf (const tchar* format, ...) const throw();

    /** Appends a block of binary data to the end of the file.

        This will try to write the given buffer to the end of the file.

        @returns false if it can't write to the file for some reason
    */
    bool appendData (const void* const dataToAppend,
                     const int numberOfBytes) const throw();

    /** Replaces this file's contents with a given block of data.

        This will delete the file and replace it with the given data.

        A nice feature of this method is that it's safe - instead of deleting
        the file first and then re-writing it, it creates a new temporary file,
        writes the data to that, and then moves the new file to replace the existing
        file. This means that if the power gets pulled out or something crashes,
        you're a lot less likely to end up with an empty file..

        Returns true if the operation succeeds, or false if it fails.

        @see appendText
    */
    bool replaceWithData (const void* const dataToWrite,
                          const int numberOfBytes) const throw();

    /** Appends a string to the end of the file.

        This will try to append a text string to the file, as either 16-bit unicode
        or 8-bit characters in the default system encoding.

        It can also write the 'ff fe' unicode header bytes before the text to indicate
        the endianness of the file.

        Any single \\n characters in the string are replaced with \\r\\n before it is written.

        @see replaceWithText
    */
    bool appendText (const String& textToAppend,
                     const bool asUnicode = false,
                     const bool writeUnicodeHeaderBytes = false) const throw();

    /** Replaces this file's contents with a given text string.

        This will delete the file and replace it with the given text.

        A nice feature of this method is that it's safe - instead of deleting
        the file first and then re-writing it, it creates a new temporary file,
        writes the text to that, and then moves the new file to replace the existing
        file. This means that if the power gets pulled out or something crashes,
        you're a lot less likely to end up with an empty file..

        For an explanation of the parameters here, see the appendText() method.

        Returns true if the operation succeeds, or false if it fails.

        @see appendText
    */
    bool replaceWithText (const String& textToWrite,
                          const bool asUnicode = false,
                          const bool writeUnicodeHeaderBytes = false) const throw();

    /** Creates a set of files to represent each file root.

        e.g. on Windows this will create files for "c:\", "d:\" etc according
        to which ones are available. On the Mac/Linux, this will probably
        just add a single entry for "/".
    */
    static void findFileSystemRoots (OwnedArray<File>& results) throw();

    /** Finds the name of the drive on which this file lives.

        @returns the volume label of the drive, or an empty string if this isn't possible
    */
    const String getVolumeLabel() const throw();

    /** Returns the serial number of the volume on which this file lives.

        @returns the serial number, or zero if there's a problem doing this
    */
    int getVolumeSerialNumber() const throw();

    /** Returns the number of bytes free on the drive that this file lives on.

        @returns the number of bytes free, or 0 if there's a problem finding this out
        @see getVolumeTotalSize
    */
    int64 getBytesFreeOnVolume() const throw();

    /** Returns the total size of the drive that contains this file.

        @returns the total number of bytes that the volume can hold
        @see getBytesFreeOnVolume
    */
    int64 getVolumeTotalSize() const throw();

    /** Returns true if this file is on a CD or DVD drive. */
    bool isOnCDRomDrive() const throw();

    /** Returns true if this file is on a hard disk.

        This will fail if it's a network drive, but will still be true for
        removable hard-disks.
    */
    bool isOnHardDisk() const throw();

    /** Returns true if this file is on a removable disk drive.

        This might be a usb-drive, a CD-rom, or maybe a network drive.
    */
    bool isOnRemovableDrive() const throw();

    /** Launches the file as a process.

        - if the file is executable, this will run it.

        - if it's a document of some kind, it will launch the document with its
        default viewer application.

        - if it's a folder, it will be opened in Explorer, Finder, or equivalent.
    */
    bool startAsProcess (const String& parameters = String::empty) const throw();

    /** A set of types of location that can be passed to the getSpecialLocation() method.
    */
    enum SpecialLocationType
    {
        /** The user's home folder. This is the same as using File ("~"). */
        userHomeDirectory,

        /** The user's default documents folder. On Windows, this might be the user's
            "My Documents" folder. On the Mac it'll be their "Documents" folder. Linux
            doesn't tend to have one of these, so it might just return their home folder.
        */
        userDocumentsDirectory,

        /** The folder that contains the user's desktop objects. */
        userDesktopDirectory,

        /** The folder in which applications store their persistent user-specific settings.
            On Windows, this might be "\Documents and Settings\username\Application Data".
            On the Mac, it might be "~/Library". If you're going to store your settings in here,
            always create your own sub-folder to put them in, to avoid making a mess.
        */
        userApplicationDataDirectory,

        /** An equivalent of the userApplicationDataDirectory folder that is shared by all users
            of the computer, rather than just the current user.

            On the Mac it'll be "/Library", on Windows, it could be something like
            "\Documents and Settings\All Users\Application Data".

            Depending on the setup, this folder may be read-only.
        */
        commonApplicationDataDirectory,

        /** The folder that should be used for temporary files.

            Always delete them when you're finished, to keep the user's computer tidy!
        */
        tempDirectory,

        /** Returns this application's executable file.

            If running as a plug-in or DLL, this will (where possible) be the DLL rather than the
            host app.

            On the mac this will return the unix binary, not the package folder - see
            currentApplicationFile for that.
        */
        currentExecutableFile,

        /** Returns this application's location.

            If running as a plug-in or DLL, this will (where possible) be the DLL rather than the
            host app.

            On the mac this will return the package folder (if it's in one), not the unix binary
            that's inside it - compare with currentExecutableFile.
        */
        currentApplicationFile,

        /** The directory in which applications normally get installed.

            So on windows, this would be something like "c:\program files", on the
            Mac "/Applications", or "/usr" on linux.
        */
        globalApplicationsDirectory,

        /** The most likely place where a user might store their music files.
        */
        userMusicDirectory,

        /** The most likely place where a user might store their movie files.
        */
        userMoviesDirectory,
    };

    /** Finds the location of a special type of file or directory, such as a home folder or
        documents folder.

        @see SpecialLocationType
    */
    static const File JUCE_CALLTYPE getSpecialLocation (const SpecialLocationType type);

    /** Returns a temporary file in the system's temp directory.

        This will try to return the name of a non-existent temp file.

        To get the temp folder, you can use getSpecialLocation (File::tempDirectory).
    */
    static const File createTempFile (const String& fileNameEnding) throw();

    /** Returns the current working directory.

        @see setAsCurrentWorkingDirectory
    */
    static const File getCurrentWorkingDirectory() throw();

    /** Sets the current working directory to be this file.

        For this to work the file must point to a valid directory.

        @returns true if the current directory has been changed.
        @see getCurrentWorkingDirectory
    */
    bool setAsCurrentWorkingDirectory() const throw();

    /** The system-specific file separator character.

        On Windows, this will be '\', on Mac/Linux, it'll be '/'
    */
    static const tchar separator;

    /** The system-specific file separator character, as a string.

        On Windows, this will be '\', on Mac/Linux, it'll be '/'
    */
    static const tchar* separatorString;

    /** Removes illegal characters from a filename.

        This will return a copy of the given string after removing characters
        that are not allowed in a legal filename, and possibly shortening the
        string if it's too long.

        Because this will remove slashes, don't use it on an absolute pathname.

        @see createLegalPathName
    */
    static const String createLegalFileName (const String& fileNameToFix) throw();

    /** Removes illegal characters from a pathname.

        Similar to createLegalFileName(), but this won't remove slashes, so can
        be used on a complete pathname.

        @see createLegalFileName
    */
    static const String createLegalPathName (const String& pathNameToFix) throw();

    /** Indicates whether filenames are case-sensitive on the current operating system.
    */
    static bool areFileNamesCaseSensitive();

    /** Returns true if the string seems to be a fully-specified absolute path.
    */
    static bool isAbsolutePath (const String& path) throw();

    juce_UseDebuggingNewOperator

private:

    String fullPath;

    // internal way of contructing a file without checking the path
    friend class DirectoryIterator;
    File (const String&, int) throw();
    const String getPathUpToLastSlash() const throw();
};

#endif   // __JUCE_FILE_JUCEHEADER__
/********* End of inlined file: juce_File.h *********/

/**
    A simple implemenation of a Logger that writes to a file.

    @see Logger
*/
class JUCE_API  FileLogger  : public Logger
{
public:

    /** Creates a FileLogger for a given file.

        @param fileToWriteTo    the file that to use - new messages will be appended
                                to the file. If the file doesn't exist, it will be created,
                                along with any parent directories that are needed.
        @param welcomeMessage   when opened, the logger will write a header to the log, along
                                with the current date and time, and this welcome message
        @param maxInitialFileSizeBytes  if this is zero or greater, then if the file already exists
                                but is larger than this number of bytes, then the start of the
                                file will be truncated to keep the size down. This prevents a log
                                file getting ridiculously large over time. The file will be truncated
                                at a new-line boundary. If this value is less than zero, no size limit
                                will be imposed; if it's zero, the file will always be deleted. Note that
                                the size is only checked once when this object is created - any logging
                                that is done later will be appended without any checking
    */
    FileLogger (const File& fileToWriteTo,
                const String& welcomeMessage,
                const int maxInitialFileSizeBytes = 128 * 1024);

    /** Destructor. */
    ~FileLogger();

    void logMessage (const String& message);

    /** Helper function to create a log file in the correct place for this platform.

        On Windows this will return a logger with a path such as:
        c:\\Documents and Settings\\username\\Application Data\\[logFileSubDirectoryName]\\[logFileName]

        On the Mac it'll create something like:
        ~/Library/Logs/[logFileName]

        The method might return 0 if the file can't be created for some reason.

        @param logFileSubDirectoryName      if a subdirectory is needed, this is what it will be called -
                                            it's best to use the something like the name of your application here.
        @param logFileName                  the name of the file to create, e.g. "MyAppLog.txt". Don't just
                                            call it "log.txt" because if it goes in a directory with logs
                                            from other applications (as it will do on the Mac) then no-one
                                            will know which one is yours!
        @param welcomeMessage               a message that will be written to the log when it's opened.
        @param maxInitialFileSizeBytes      (see the FileLogger constructor for more info on this)
    */
    static FileLogger* createDefaultAppLogger (const String& logFileSubDirectoryName,
                                               const String& logFileName,
                                               const String& welcomeMessage,
                                               const int maxInitialFileSizeBytes = 128 * 1024);

    juce_UseDebuggingNewOperator

private:
    File logFile;
    CriticalSection logLock;
    FileOutputStream* logStream;

    void trimFileSize (int maxFileSizeBytes) const;

    FileLogger (const FileLogger&);
    const FileLogger& operator= (const FileLogger&);
};

#endif   // __JUCE_FILELOGGER_JUCEHEADER__
/********* End of inlined file: juce_FileLogger.h *********/

#endif
#ifndef __JUCE_INITIALISATION_JUCEHEADER__

/********* Start of inlined file: juce_Initialisation.h *********/
#ifndef __JUCE_INITIALISATION_JUCEHEADER__
#define __JUCE_INITIALISATION_JUCEHEADER__

/** Initialises Juce's GUI classes.

    If you're embedding Juce into an application that uses its own event-loop rather
    than using the START_JUCE_APPLICATION macro, call this function before making any
    Juce calls, to make sure things are initialised correctly.

    Note that if you're creating a Juce DLL for Windows, you may also need to call the
    PlatformUtilities::setCurrentModuleInstanceHandle() method.

    @see shutdownJuce_GUI(), initialiseJuce_NonGUI()
*/
void JUCE_PUBLIC_FUNCTION  initialiseJuce_GUI();

/** Clears up any static data being used by Juce's GUI classes.

    If you're embedding Juce into an application that uses its own event-loop rather
    than using the START_JUCE_APPLICATION macro, call this function in your shutdown
    code to clean up any juce objects that might be lying around.

    @see initialiseJuce_GUI(), initialiseJuce_NonGUI()
*/
void JUCE_PUBLIC_FUNCTION  shutdownJuce_GUI();

/** Initialises the core parts of Juce.

    If you're embedding Juce into either a command-line program, call this function
    at the start of your main() function to make sure that Juce is initialised correctly.

    Note that if you're creating a Juce DLL for Windows, you may also need to call the
    PlatformUtilities::setCurrentModuleInstanceHandle() method.

    @see shutdownJuce_NonGUI, initialiseJuce_GUI
*/
void JUCE_PUBLIC_FUNCTION  initialiseJuce_NonGUI();

/** Clears up any static data being used by Juce's non-gui core classes.

    If you're embedding Juce into either a command-line program, call this function
    at the end of your main() function if you want to make sure any Juce objects are
    cleaned up correctly.

    @see initialiseJuce_NonGUI, initialiseJuce_GUI
*/
void JUCE_PUBLIC_FUNCTION  shutdownJuce_NonGUI();

#endif   // __JUCE_INITIALISATION_JUCEHEADER__
/********* End of inlined file: juce_Initialisation.h *********/

#endif
#ifndef __JUCE_LOGGER_JUCEHEADER__

#endif
#ifndef __JUCE_MATHSFUNCTIONS_JUCEHEADER__

#endif
#ifndef __JUCE_MEMORY_JUCEHEADER__

#endif
#ifndef __JUCE_PLATFORMDEFS_JUCEHEADER__

#endif
#ifndef __JUCE_RANDOM_JUCEHEADER__

/********* Start of inlined file: juce_Random.h *********/
#ifndef __JUCE_RANDOM_JUCEHEADER__
#define __JUCE_RANDOM_JUCEHEADER__

/********* Start of inlined file: juce_BitArray.h *********/
#ifndef __JUCE_BITARRAY_JUCEHEADER__
#define __JUCE_BITARRAY_JUCEHEADER__

class MemoryBlock;

/**
    An array of on/off bits, also usable to store large binary integers.

    A BitArray acts like an arbitrarily large integer whose bits can be set or
    cleared, and some basic mathematical operations can be done on the number as
    a whole.
*/
class JUCE_API  BitArray
{
public:

    /** Creates an empty BitArray */
    BitArray() throw();

    /** Creates a BitArray containing an integer value in its low bits.

        The low 32 bits of the array are initialised with this value.
    */
    BitArray (const unsigned int value) throw();

    /** Creates a BitArray containing an integer value in its low bits.

        The low 32 bits of the array are initialised with the absolute value
        passed in, and its sign is set to reflect the sign of the number.
    */
    BitArray (const int value) throw();

    /** Creates a BitArray containing an integer value in its low bits.

        The low 64 bits of the array are initialised with the absolute value
        passed in, and its sign is set to reflect the sign of the number.
    */
    BitArray (int64 value) throw();

    /** Creates a copy of another BitArray. */
    BitArray (const BitArray& other) throw();

    /** Destructor. */
    ~BitArray() throw();

    /** Copies another BitArray onto this one. */
    const BitArray& operator= (const BitArray& other) throw();

    /** Two arrays are the same if the same bits are set. */
    bool operator== (const BitArray& other) const throw();
    /** Two arrays are the same if the same bits are set. */
    bool operator!= (const BitArray& other) const throw();

    /** Clears all bits in the BitArray to 0. */
    void clear() throw();

    /** Clears a particular bit in the array. */
    void clearBit (const int bitNumber) throw();

    /** Sets a specified bit to 1.

        If the bit number is high, this will grow the array to accomodate it.
    */
    void setBit (const int bitNumber) throw();

    /** Sets or clears a specified bit. */
    void setBit (const int bitNumber,
                 const bool shouldBeSet) throw();

    /** Sets a range of bits to be either on or off.

        @param startBit     the first bit to change
        @param numBits      the number of bits to change
        @param shouldBeSet  whether to turn these bits on or off
    */
    void setRange (int startBit,
                   int numBits,
                   const bool shouldBeSet) throw();

    /** Inserts a bit an a given position, shifting up any bits above it. */
    void insertBit (const int bitNumber,
                    const bool shouldBeSet) throw();

    /** Returns the value of a specified bit in the array.

        If the index is out-of-range, the result will be false.
    */
    bool operator[] (const int bit) const throw();

    /** Returns true if no bits are set. */
    bool isEmpty() const throw();

    /** Returns a range of bits in the array as a new BitArray.

        e.g. getBitRangeAsInt (0, 64) would return the lowest 64 bits.
        @see getBitRangeAsInt
    */
    const BitArray getBitRange (int startBit, int numBits) const throw();

    /** Returns a range of bits in the array as an integer value.

        e.g. getBitRangeAsInt (0, 32) would return the lowest 32 bits.

        Asking for more than 32 bits isn't allowed (obviously) - for that, use
        getBitRange().
    */
    int getBitRangeAsInt (int startBit, int numBits) const throw();

    /** Sets a range of bits in the array based on an integer value.

        Copies the given integer into the array, starting at startBit,
        and only using up to numBits of the available bits.
    */
    void setBitRangeAsInt (int startBit, int numBits,
                           unsigned int valueToSet) throw();

    /** Performs a bitwise OR with another BitArray.

        The result ends up in this array.
    */
    void orWith (const BitArray& other) throw();

    /** Performs a bitwise AND with another BitArray.

        The result ends up in this array.
    */
    void andWith (const BitArray& other) throw();

    /** Performs a bitwise XOR with another BitArray.

        The result ends up in this array.
    */
    void xorWith (const BitArray& other) throw();

    /** Adds another BitArray's value to this one.

        Treating the two arrays as large positive integers, this
        adds them up and puts the result in this array.
    */
    void add (const BitArray& other) throw();

    /** Subtracts another BitArray's value from this one.

        Treating the two arrays as large positive integers, this
        subtracts them and puts the result in this array.

        Note that if the result should be negative, this won't be
        handled correctly.
    */
    void subtract (const BitArray& other) throw();

    /** Multiplies another BitArray's value with this one.

        Treating the two arrays as large positive integers, this
        multiplies them and puts the result in this array.
    */
    void multiplyBy (const BitArray& other) throw();

    /** Divides another BitArray's value into this one and also produces a remainder.

        Treating the two arrays as large positive integers, this
        divides this value by the other, leaving the quotient in this
        array, and the remainder is copied into the other BitArray passed in.
    */
    void divideBy (const BitArray& divisor, BitArray& remainder) throw();

    /** Returns the largest value that will divide both this value and the one
        passed-in.
    */
    const BitArray findGreatestCommonDivisor (BitArray other) const throw();

    /** Performs a modulo operation on this value.

        The result is stored in this value.
    */
    void modulo (const BitArray& divisor) throw();

    /** Performs a combined exponent and modulo operation.

        This BitArray's value becomes (this ^ exponent) % modulus.
    */
    void exponentModulo (const BitArray& exponent, const BitArray& modulus) throw();

    /** Performs an inverse modulo on the value.

        i.e. the result is (this ^ -1) mod (modulus).
    */
    void inverseModulo (const BitArray& modulus) throw();

    /** Shifts a section of bits left or right.

        @param howManyBitsLeft  how far to move the bits (+ve numbers shift it left, -ve numbers shift it right).
        @param startBit         the first bit to affect - if this is > 0, only bits above that index will be affected.
    */
    void shiftBits (int howManyBitsLeft,
                    int startBit = 0) throw();

    /** Does a signed comparison of two BitArrays.

        Return values are:
            - 0 if the numbers are the same
            - < 0 if this number is smaller than the other
            - > 0 if this number is bigger than the other
    */
    int compare (const BitArray& other) const throw();

    /** Compares the magnitudes of two BitArrays, ignoring their signs.

        Return values are:
            - 0 if the numbers are the same
            - < 0 if this number is smaller than the other
            - > 0 if this number is bigger than the other
    */
    int compareAbsolute (const BitArray& other) const throw();

    /** Returns true if the value is less than zero.

        @see setNegative, negate
    */
    bool isNegative() const throw();

    /** Changes the sign of the number to be positive or negative.

        @see isNegative, negate
    */
    void setNegative (const bool shouldBeNegative) throw();

    /** Inverts the sign of the number.

        @see isNegative, setNegative
    */
    void negate() throw();

    /** Counts the total number of set bits in the array. */
    int countNumberOfSetBits() const throw();

    /** Looks for the index of the next set bit after a given starting point.

        searches from startIndex (inclusive) upwards for the first set bit,
        and returns its index.

        If no set bits are found, it returns -1.
    */
    int findNextSetBit (int startIndex = 0) const throw();

    /** Looks for the index of the next clear bit after a given starting point.

        searches from startIndex (inclusive) upwards for the first clear bit,
        and returns its index.
    */
    int findNextClearBit (int startIndex = 0) const throw();

    /** Returns the index of the highest set bit in the array.

        If the array is empty, this will return -1.
    */
    int getHighestBit() const throw();

    /** Converts the array to a number string.

        Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).

        If minuimumNumCharacters is greater than 0, the returned string will be
        padded with leading zeros to reach at least that length.
    */
    const String toString (const int base, const int minimumNumCharacters = 1) const throw();

    /** Converts a number string to an array.

        Any non-valid characters will be ignored.

        Specify a base such as 2 (binary), 8 (octal), 10 (decimal), 16 (hex).
    */
    void parseString (const String& text,
                      const int base) throw();

    /** Turns the array into a block of binary data.

        The data is arranged as little-endian, so the first byte of data is the low 8 bits
        of the array, and so on.

        @see loadFromMemoryBlock
    */
    const MemoryBlock toMemoryBlock() const throw();

    /** Copies a block of raw data onto this array.

        The data is arranged as little-endian, so the first byte of data is the low 8 bits
        of the array, and so on.

        @see toMemoryBlock
    */
    void loadFromMemoryBlock (const MemoryBlock& data) throw();

    juce_UseDebuggingNewOperator

private:
    void ensureSize (const int numVals) throw();
    unsigned int* values;
    int numValues, highestBit;
    bool negative;
};

#endif   // __JUCE_BITARRAY_JUCEHEADER__
/********* End of inlined file: juce_BitArray.h *********/

/**
    A simple pseudo-random number generator.
*/
class JUCE_API  Random
{
public:

    /** Creates a Random object based on a seed value.

        For a given seed value, the subsequent numbers generated by this object
        will be predictable, so a good idea is to set this value based
        on the time, e.g.

        new Random (Time::currentTimeMillis())
    */
    Random (const int64 seedValue) throw();

    /** Destructor. */
    ~Random() throw();

    /** Returns the next random 32 bit integer.

        @returns a random integer from the full range 0x80000000 to 0x7fffffff
    */
    int nextInt() throw();

    /** Returns the next random number, limited to a given range.

        @returns a random integer between 0 (inclusive) and maxValue (exclusive).
    */
    int nextInt (const int maxValue) throw();

    /** Returns the next 64-bit random number.

        @returns a random integer from the full range 0x8000000000000000 to 0x7fffffffffffffff
    */
    int64 nextInt64() throw();

    /** Returns the next random floating-point number.

        @returns a random value in the range 0 to 1.0
    */
    float nextFloat() throw();

    /** Returns the next random floating-point number.

        @returns a random value in the range 0 to 1.0
    */
    double nextDouble() throw();

    /** Returns the next random boolean value.
    */
    bool nextBool() throw();

    /** Returns a BitArray containing a random number.

        @returns a random value in the range 0 to (maximumValue - 1).
    */
    const BitArray nextLargeNumber (const BitArray& maximumValue) throw();

    /** Sets a range of bits in a BitArray to random values. */
    void fillBitsRandomly (BitArray& arrayToChange, int startBit, int numBits) throw();

    /** To avoid the overhead of having to create a new Random object whenever
        you need a number, this is a shared application-wide object that
        can be used.

        It's not thread-safe though, so threads should use their own Random object.
    */
    static Random& getSystemRandom() throw();

    /** Resets this Random object to a given seed value. */
    void setSeed (const int64 newSeed) throw();

    /** Reseeds this generator using a value generated from various semi-random system
        properties like the current time, etc.

        Because this function convolves the time with the last seed value, calling
        it repeatedly will increase the randomness of the final result.
    */
    void setSeedRandomly();

    juce_UseDebuggingNewOperator

private:
    int64 seed;
};

#endif   // __JUCE_RANDOM_JUCEHEADER__
/********* End of inlined file: juce_Random.h *********/

#endif
#ifndef __JUCE_TIME_JUCEHEADER__

#endif
#ifndef __JUCE_RELATIVETIME_JUCEHEADER__

#endif
#ifndef __JUCE_SINGLETON_JUCEHEADER__

/********* Start of inlined file: juce_Singleton.h *********/
#ifndef __JUCE_SINGLETON_JUCEHEADER__
#define __JUCE_SINGLETON_JUCEHEADER__

/********* Start of inlined file: juce_ScopedLock.h *********/
#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__
#define __JUCE_SCOPEDLOCK_JUCEHEADER__

/**
    Automatically locks and unlocks a CriticalSection object.

    Use one of these as a local variable to control access to a CriticalSection.

    e.g. @code

    CriticalSection myCriticalSection;

    for (;;)
    {
        const ScopedLock myScopedLock (myCriticalSection);
        // myCriticalSection is now locked

        ...do some stuff...

        // myCriticalSection gets unlocked here.
    }
    @endcode

    @see CriticalSection, ScopedUnlock
*/
class JUCE_API  ScopedLock
{
public:

    /** Creates a ScopedLock.

        As soon as it is created, this will lock the CriticalSection, and
        when the ScopedLock object is deleted, the CriticalSection will
        be unlocked.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen! Best just to use it
        as a local stack object, rather than creating one with the new() operator.
    */
    inline ScopedLock (const CriticalSection& lock) throw()     : lock_ (lock) { lock.enter(); }

    /** Destructor.

        The CriticalSection will be unlocked when the destructor is called.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen!
    */
    inline ~ScopedLock() throw()                                { lock_.exit(); }

private:

    const CriticalSection& lock_;

    ScopedLock (const ScopedLock&);
    const ScopedLock& operator= (const ScopedLock&);
};

/**
    Automatically unlocks and re-locks a CriticalSection object.

    This is the reverse of a ScopedLock object - instead of locking the critical
    section for the lifetime of this object, it unlocks it.

    Make sure you don't try to unlock critical sections that aren't actually locked!

    e.g. @code

    CriticalSection myCriticalSection;

    for (;;)
    {
        const ScopedLock myScopedLock (myCriticalSection);
        // myCriticalSection is now locked

        ... do some stuff with it locked ..

        while (xyz)
        {
            ... do some stuff with it locked ..

            const ScopedUnlock unlocker (myCriticalSection);

            // myCriticalSection is now unlocked for the remainder of this block,
            // and re-locked at the end.

            ...do some stuff with it unlocked ...
        }

        // myCriticalSection gets unlocked here.
    }
    @endcode

    @see CriticalSection, ScopedLock
*/
class ScopedUnlock
{
public:

    /** Creates a ScopedUnlock.

        As soon as it is created, this will unlock the CriticalSection, and
        when the ScopedLock object is deleted, the CriticalSection will
        be re-locked.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen! Best just to use it
        as a local stack object, rather than creating one with the new() operator.
    */
    inline ScopedUnlock (const CriticalSection& lock) throw()     : lock_ (lock) { lock.exit(); }

    /** Destructor.

        The CriticalSection will be unlocked when the destructor is called.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen!
    */
    inline ~ScopedUnlock() throw()                                { lock_.enter(); }

private:

    const CriticalSection& lock_;

    ScopedUnlock (const ScopedLock&);
    const ScopedUnlock& operator= (const ScopedUnlock&);
};

#endif   // __JUCE_SCOPEDLOCK_JUCEHEADER__
/********* End of inlined file: juce_ScopedLock.h *********/

/**
    Macro to declare member variables and methods for a singleton class.

    To use this, add the line juce_DeclareSingleton (MyClass, allowOnlyOneInstance)
    to the class's definition.

    If allowOnlyOneInstance == true, it won't allow the object to be created
    more than once in the process's lifetime.

    Then put a macro juce_ImplementSingleton (MyClass) along with the class's
    implementation code.

    Clients can then call the static MyClass::getInstance() to get a pointer to the
    singleton, or MyClass::getInstanceWithoutCreating() which may return 0 if no instance
    is currently extant

    it's a very good idea to also add the call clearSingletonInstance() to the
    destructor of the class, in case it is deleted by other means than deleteInstance()

    e.g. @code

        class MySingleton
        {
        public:
            MySingleton()
            {
            }

            ~MySingleton()
            {
                // this ensures that no dangling pointers are left when the
                // singleton is deleted.
                clearSingletonInstance();
            }

            juce_DeclareSingleton (MySingleton, false)
        };

        juce_ImplementSingleton (MySingleton)

        // example of usage:
        MySingleton* m = MySingleton::getInstance(); // creates the singleton if there isn't already one.

        ...

        MySingleton::deleteInstance(); // safely deletes the singleton (if it's been created).

    @endcode

    If you know that your object will only be created and deleted by a single thread, you
    can use the slightly more efficient juce_DeclareSingleton_SingleThreaded() macro instead
    of this one.

    @see juce_ImplementSingleton, juce_DeclareSingleton_SingleThreaded
*/
#define juce_DeclareSingleton(classname, allowOnlyOneInstance) \
\
    static classname* _singletonInstance;  \
    static JUCE_NAMESPACE::CriticalSection _singletonLock; \
\
    static classname* getInstance() \
    { \
        if (_singletonInstance == 0) \
        {\
            const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \
\
            if (_singletonInstance == 0) \
            { \
                static bool alreadyInside = false; \
                static bool createdOnceAlready = false; \
\
                const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \
                jassert (! problem); \
                if (! problem) \
                { \
                    createdOnceAlready = true; \
                    alreadyInside = true; \
                    classname* newObject = new classname();  /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \
                    alreadyInside = false; \
\
                    _singletonInstance = newObject; \
                } \
            } \
        } \
\
        return _singletonInstance; \
    } \
\
    static inline classname* getInstanceWithoutCreating() throw() \
    { \
        return _singletonInstance; \
    } \
\
    static void deleteInstance() \
    { \
        const JUCE_NAMESPACE::ScopedLock sl (_singletonLock); \
        if (_singletonInstance != 0) \
        { \
            classname* const old = _singletonInstance; \
            _singletonInstance = 0; \
            delete old; \
        } \
    } \
\
    void clearSingletonInstance() throw() \
    { \
        if (_singletonInstance == this) \
            _singletonInstance = 0; \
    }

/** This is a counterpart to the juce_DeclareSingleton macro.

    After adding the juce_DeclareSingleton to the class definition, this macro has
    to be used in the cpp file.
*/
#define juce_ImplementSingleton(classname) \
\
    classname* classname::_singletonInstance = 0; \
    JUCE_NAMESPACE::CriticalSection classname::_singletonLock;

/**
    Macro to declare member variables and methods for a singleton class.

    This is exactly the same as juce_DeclareSingleton, but doesn't use a critical
    section to make access to it thread-safe. If you know that your object will
    only ever be created or deleted by a single thread, then this is a
    more efficient version to use.

    See the documentation for juce_DeclareSingleton for more information about
    how to use it, the only difference being that you have to use
    juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton.

    @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton, juce_DeclareSingleton_SingleThreaded_Minimal
*/
#define juce_DeclareSingleton_SingleThreaded(classname, allowOnlyOneInstance) \
\
    static classname* _singletonInstance;  \
\
    static classname* getInstance() \
    { \
        if (_singletonInstance == 0) \
        { \
            static bool alreadyInside = false; \
            static bool createdOnceAlready = false; \
\
            const bool problem = alreadyInside || ((allowOnlyOneInstance) && createdOnceAlready); \
            jassert (! problem); \
            if (! problem) \
            { \
                createdOnceAlready = true; \
                alreadyInside = true; \
                classname* newObject = new classname();  /* (use a stack variable to avoid setting the newObject value before the class has finished its constructor) */ \
                alreadyInside = false; \
\
                _singletonInstance = newObject; \
            } \
        } \
\
        return _singletonInstance; \
    } \
\
    static inline classname* getInstanceWithoutCreating() throw() \
    { \
        return _singletonInstance; \
    } \
\
    static void deleteInstance() \
    { \
        if (_singletonInstance != 0) \
        { \
            classname* const old = _singletonInstance; \
            _singletonInstance = 0; \
            delete old; \
        } \
    } \
\
    void clearSingletonInstance() throw() \
    { \
        if (_singletonInstance == this) \
            _singletonInstance = 0; \
    }

/**
    Macro to declare member variables and methods for a singleton class.

    This is like juce_DeclareSingleton_SingleThreaded, but doesn't do any checking
    for recursion or repeated instantiation. It's intended for use as a lightweight
    version of a singleton, where you're using it in very straightforward
    circumstances and don't need the extra checking.

    Juce use the normal juce_ImplementSingleton_SingleThreaded as the counterpart
    to this declaration, as you would with juce_DeclareSingleton_SingleThreaded.

    See the documentation for juce_DeclareSingleton for more information about
    how to use it, the only difference being that you have to use
    juce_ImplementSingleton_SingleThreaded instead of juce_ImplementSingleton.

    @see juce_ImplementSingleton_SingleThreaded, juce_DeclareSingleton
*/
#define juce_DeclareSingleton_SingleThreaded_Minimal(classname) \
\
    static classname* _singletonInstance;  \
\
    static classname* getInstance() \
    { \
        if (_singletonInstance == 0) \
            _singletonInstance = new classname(); \
\
        return _singletonInstance; \
    } \
\
    static inline classname* getInstanceWithoutCreating() throw() \
    { \
        return _singletonInstance; \
    } \
\
    static void deleteInstance() \
    { \
        if (_singletonInstance != 0) \
        { \
            classname* const old = _singletonInstance; \
            _singletonInstance = 0; \
            delete old; \
        } \
    } \
\
    void clearSingletonInstance() throw() \
    { \
        if (_singletonInstance == this) \
            _singletonInstance = 0; \
    }

/** This is a counterpart to the juce_DeclareSingleton_SingleThreaded macro.

    After adding juce_DeclareSingleton_SingleThreaded or juce_DeclareSingleton_SingleThreaded_Minimal
    to the class definition, this macro has to be used somewhere in the cpp file.
*/
#define juce_ImplementSingleton_SingleThreaded(classname) \
\
    classname* classname::_singletonInstance = 0;

#endif   // __JUCE_SINGLETON_JUCEHEADER__
/********* End of inlined file: juce_Singleton.h *********/

#endif
#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__

/********* Start of inlined file: juce_SystemStats.h *********/
#ifndef __JUCE_SYSTEMSTATS_JUCEHEADER__
#define __JUCE_SYSTEMSTATS_JUCEHEADER__

/**
    Contains methods for finding out about the current hardware and OS configuration.
*/
class JUCE_API  SystemStats
{
public:

    /** Returns the current version of JUCE,

        (just in case you didn't already know at compile-time.)

        See also the JUCE_VERSION, JUCE_MAJOR_VERSION and JUCE_MINOR_VERSION macros.
    */
    static const String getJUCEVersion() throw();

    /** The set of possible results of the getOperatingSystemType() method.
    */
    enum OperatingSystemType
    {
        UnknownOS   = 0,

        MacOSX      = 0x1000,
        Linux       = 0x2000,

        Win95       = 0x4001,
        Win98       = 0x4002,
        WinNT351    = 0x4103,
        WinNT40     = 0x4104,
        Win2000     = 0x4105,
        WinXP       = 0x4106,
        WinVista    = 0x4107,

        Windows     = 0x4000,   /**< To test whether any version of Windows is running,
                                     you can use the expression ((getOperatingSystemType() & Windows) != 0). */
        WindowsNT   = 0x0100,   /**< To test whether the platform is Windows NT or later (i.e. not Win95 or 98),
                                     you can use the expression ((getOperatingSystemType() & WindowsNT) != 0). */
    };

    /** Returns the type of operating system we're running on.

        @returns one of the values from the OperatingSystemType enum.
        @see getOperatingSystemName
    */
    static OperatingSystemType getOperatingSystemType() throw();

    /** Returns the name of the type of operating system we're running on.

        @returns a string describing the OS type.
        @see getOperatingSystemType
    */
    static const String getOperatingSystemName() throw();

    /** Returns true if the OS is 64-bit, or false for a 32-bit OS.
    */
    static bool isOperatingSystem64Bit() throw();

    // CPU and memory information..

    /** Returns the approximate CPU speed.

        @returns    the speed in megahertz, e.g. 1500, 2500, 32000 (depending on
                    what year you're reading this...)
    */
    static int getCpuSpeedInMegaherz() throw();

    /** Returns a string to indicate the CPU vendor.

        Might not be known on some systems.
    */
    static const String getCpuVendor() throw();

    /** Checks whether Intel MMX instructions are available. */
    static bool hasMMX() throw();

    /** Checks whether Intel SSE instructions are available. */
    static bool hasSSE() throw();

    /** Checks whether Intel SSE2 instructions are available. */
    static bool hasSSE2() throw();

    /** Checks whether AMD 3DNOW instructions are available. */
    static bool has3DNow() throw();

    /** Returns the number of CPUs.
    */
    static int getNumCpus() throw();

    /** Returns a clock-cycle tick counter, if available.

        If the machine can do it, this will return a tick-count
        where each tick is one cpu clock cycle - used for profiling
        code.

        @returns    the tick count, or zero if not available.
    */
    static int64 getClockCycleCounter() throw();

    /** Finds out how much RAM is in the machine.

        @returns    the approximate number of megabytes of memory, or zero if
                    something goes wrong when finding out.
    */
    static int getMemorySizeInMegabytes() throw();

    /** Returns the system page-size.

        This is only used by programmers with beards.
    */
    static int getPageSize() throw();

    /** Returns a list of MAC addresses found on this machine.

        @param  addresses   an array into which the MAC addresses should be copied
        @param  maxNum      the number of elements in this array
        @param littleEndian the endianness of the numbers to return. Note that
                            the default values of this parameter are different on
                            Mac/PC to avoid breaking old software that was written
                            before this parameter was added (when the two systems
                            defaulted to using different endiannesses). In newer
                            software you probably want to specify an explicit value
                            for this.
        @returns            the number of MAC addresses that were found
    */
    static int getMACAddresses (int64* addresses, int maxNum,
#if JUCE_MAC
                                const bool littleEndian = true) throw();
#else
                                const bool littleEndian = false) throw();
#endif

    // not-for-public-use platform-specific method gets called at startup to initialise things.
    static void initialiseStats() throw();
};

#endif   // __JUCE_SYSTEMSTATS_JUCEHEADER__
/********* End of inlined file: juce_SystemStats.h *********/

#endif
#ifndef __JUCE_DATACONVERSIONS_JUCEHEADER__

#endif
#ifndef __JUCE_STANDARDHEADER_JUCEHEADER__

#endif
#ifndef __JUCE_ARRAYALLOCATIONBASE_JUCEHEADER__

#endif
#ifndef __JUCE_ARRAY_JUCEHEADER__

#endif
#ifndef __JUCE_BITARRAY_JUCEHEADER__

#endif
#ifndef __JUCE_ELEMENTCOMPARATOR_JUCEHEADER__

#endif
#ifndef __JUCE_MEMORYBLOCK_JUCEHEADER__

#endif
#ifndef __JUCE_PROPERTYSET_JUCEHEADER__

/********* Start of inlined file: juce_PropertySet.h *********/
#ifndef __JUCE_PROPERTYSET_JUCEHEADER__
#define __JUCE_PROPERTYSET_JUCEHEADER__

/********* Start of inlined file: juce_StringPairArray.h *********/
#ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__
#define __JUCE_STRINGPAIRARRAY_JUCEHEADER__

/**
    A container for holding a set of strings which are keyed by another string.

    @see StringArray
*/
class JUCE_API  StringPairArray
{
public:

    /** Creates an empty array */
    StringPairArray (const bool ignoreCaseWhenComparingKeys = true) throw();

    /** Creates a copy of another array */
    StringPairArray (const StringPairArray& other) throw();

    /** Destructor. */
    ~StringPairArray() throw();

    /** Copies the contents of another string array into this one */
    const StringPairArray& operator= (const StringPairArray& other) throw();

    /** Compares two arrays.

        Comparisons are case-sensitive.

        @returns    true only if the other array contains exactly the same strings with the same keys
    */
    bool operator== (const StringPairArray& other) const throw();

    /** Compares two arrays.

        Comparisons are case-sensitive.

        @returns    false if the other array contains exactly the same strings with the same keys
    */
    bool operator!= (const StringPairArray& other) const throw();

    /** Finds the value corresponding to a key string.

        If no such key is found, this will just return an empty string. To check whether
        a given key actually exists (because it might actually be paired with an empty string), use
        the getAllKeys() method to obtain a list.

        Obviously the reference returned shouldn't be stored for later use, as the
        string it refers to may disappear when the array changes.

        @see getValue
    */
    const String& operator[] (const String& key) const throw();

    /** Finds the value corresponding to a key string.

        If no such key is found, this will just return the value provided as a default.

        @see operator[]
    */
    const String getValue (const String& key, const String& defaultReturnValue) const;

    /** Returns a list of all keys in the array. */
    const StringArray& getAllKeys() const throw()       { return keys; }

    /** Returns a list of all values in the array. */
    const StringArray& getAllValues() const throw()     { return values; }

    /** Returns the number of strings in the array */
    inline int size() const throw()                     { return keys.size(); };

    /** Adds or amends a key/value pair.

        If a value already exists with this key, its value will be overwritten,
        otherwise the key/value pair will be added to the array.
    */
    void set (const String& key,
              const String& value) throw();

    /** Adds the items from another array to this one.

        This is equivalent to using set() to add each of the pairs from the other array.
    */
    void addArray (const StringPairArray& other);

    /** Removes all elements from the array. */
    void clear() throw();

    /** Removes a string from the array based on its key.

        If the key isn't found, nothing will happen.
    */
    void remove (const String& key) throw();

    /** Removes a string from the array based on its index.

        If the index is out-of-range, no action will be taken.
    */
    void remove (const int index) throw();

    /** Indicates whether to use a case-insensitive search when looking up a key string.
    */
    void setIgnoresCase (const bool shouldIgnoreCase) throw();

    /** Returns a descriptive string containing the items.

        This is handy for dumping the contents of an array.
    */
    const String getDescription() const;

    /** Reduces the amount of storage being used by the array.

        Arrays typically allocate slightly more storage than they need, and after
        removing elements, they may have quite a lot of unused space allocated.
        This method will reduce the amount of allocated storage to a minimum.
    */
    void minimiseStorageOverheads() throw();

    juce_UseDebuggingNewOperator

private:
    StringArray keys, values;
    bool ignoreCase;
};

#endif   // __JUCE_STRINGPAIRARRAY_JUCEHEADER__
/********* End of inlined file: juce_StringPairArray.h *********/

/********* Start of inlined file: juce_XmlElement.h *********/
#ifndef __JUCE_XMLELEMENT_JUCEHEADER__
#define __JUCE_XMLELEMENT_JUCEHEADER__

/********* Start of inlined file: juce_OutputStream.h *********/
#ifndef __JUCE_OUTPUTSTREAM_JUCEHEADER__
#define __JUCE_OUTPUTSTREAM_JUCEHEADER__

/********* Start of inlined file: juce_InputStream.h *********/
#ifndef __JUCE_INPUTSTREAM_JUCEHEADER__
#define __JUCE_INPUTSTREAM_JUCEHEADER__

/** The base class for streams that read data.

    Input and output streams are used throughout the library - subclasses can override
    some or all of the virtual functions to implement their behaviour.

    @see OutputStream, MemoryInputStream, BufferedInputStream, FileInputStream
*/
class JUCE_API  InputStream
{
public:
    /** Destructor. */
    virtual ~InputStream()  {}

    /** Returns the total number of bytes available for reading in this stream.

        Note that this is the number of bytes available from the start of the
        stream, not from the current position.

        If the size of the stream isn't actually known, this may return -1.
    */
    virtual int64 getTotalLength() = 0;

    /** Returns true if the stream has no more data to read. */
    virtual bool isExhausted() = 0;

    /** Reads a set of bytes from the stream into a memory buffer.

        This is the only read method that subclasses actually need to implement, as the
        InputStream base class implements the other read methods in terms of this one (although
        it's often more efficient for subclasses to implement them directly).

        @param destBuffer       the destination buffer for the data
        @param maxBytesToRead   the maximum number of bytes to read - make sure the
                                memory block passed in is big enough to contain this
                                many bytes.

        @returns    the actual number of bytes that were read, which may be less than
                    maxBytesToRead if the stream is exhausted before it gets that far
    */
    virtual int read (void* destBuffer,
                      int maxBytesToRead) = 0;

    /** Reads a byte from the stream.

        If the stream is exhausted, this will return zero.

        @see OutputStream::writeByte
    */
    virtual char readByte();

    /** Reads a boolean from the stream.

        The bool is encoded as a single byte - 1 for true, 0 for false.

        If the stream is exhausted, this will return false.

        @see OutputStream::writeBool
    */
    virtual bool readBool();

    /** Reads two bytes from the stream as a little-endian 16-bit value.

        If the next two bytes read are byte1 and byte2, this returns
        (byte1 | (byte2 << 8)).

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeShort, readShortBigEndian
    */
    virtual short readShort();

    /** Reads two bytes from the stream as a little-endian 16-bit value.

        If the next two bytes read are byte1 and byte2, this returns
        (byte2 | (byte1 << 8)).

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeShortBigEndian, readShort
    */
    virtual short readShortBigEndian();

    /** Reads four bytes from the stream as a little-endian 32-bit value.

        If the next four bytes are byte1 to byte4, this returns
        (byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24)).

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeInt, readIntBigEndian
    */
    virtual int readInt();

    /** Reads four bytes from the stream as a big-endian 32-bit value.

        If the next four bytes are byte1 to byte4, this returns
        (byte4 | (byte3 << 8) | (byte2 << 16) | (byte1 << 24)).

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeIntBigEndian, readInt
    */
    virtual int readIntBigEndian();

    /** Reads eight bytes from the stream as a little-endian 64-bit value.

        If the next eight bytes are byte1 to byte8, this returns
        (byte1 | (byte2 << 8) | (byte3 << 16) | (byte4 << 24) | (byte5 << 32) | (byte6 << 40) | (byte7 << 48) | (byte8 << 56)).

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeInt64, readInt64BigEndian
    */
    virtual int64 readInt64();

    /** Reads eight bytes from the stream as a big-endian 64-bit value.

        If the next eight bytes are byte1 to byte8, this returns
        (byte8 | (byte7 << 8) | (byte6 << 16) | (byte5 << 24) | (byte4 << 32) | (byte3 << 40) | (byte2 << 48) | (byte1 << 56)).

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeInt64BigEndian, readInt64
    */
    virtual int64 readInt64BigEndian();

    /** Reads four bytes as a 32-bit floating point value.

        The raw 32-bit encoding of the float is read from the stream as a little-endian int.

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeFloat, readDouble
    */
    virtual float readFloat();

    /** Reads four bytes as a 32-bit floating point value.

        The raw 32-bit encoding of the float is read from the stream as a big-endian int.

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeFloatBigEndian, readDoubleBigEndian
    */
    virtual float readFloatBigEndian();

    /** Reads eight bytes as a 64-bit floating point value.

        The raw 64-bit encoding of the double is read from the stream as a little-endian int64.

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeDouble, readFloat
    */
    virtual double readDouble();

    /** Reads eight bytes as a 64-bit floating point value.

        The raw 64-bit encoding of the double is read from the stream as a big-endian int64.

        If the stream is exhausted partway through reading the bytes, this will return zero.

        @see OutputStream::writeDoubleBigEndian, readFloatBigEndian
    */
    virtual double readDoubleBigEndian();

    /** Reads an encoded 32-bit number from the stream using a space-saving compressed format.

        For small values, this is more space-efficient than using readInt() and OutputStream::writeInt()

        The format used is: number of significant bytes + up to 4 bytes in little-endian order.

        @see OutputStream::writeCompressedInt()
    */
    virtual int readCompressedInt();

    /** Reads a string from the stream, up to the next linefeed or carriage return.

        The stream is treated as 8-bit characters encoded with the system's default encoding,
        and this will read up to the next "\n" or "\r\n" or end-of-stream.

        After this call, the stream's position will be left pointing to the character
        following the line-feed, but the linefeeds aren't included in the string that
        is returned.
    */
    virtual const String readNextLine();

    /** Reads a zero-terminated string from the stream.

        This will read characters from the stream until it hits a zero character or
        end-of-stream.

        @see OutputStream::writeString, readEntireStreamAsString
    */
    virtual const String readString();

    /** Tries to read the whole stream and turn it into a string.

        This will read from the stream's current position until the end-of-stream, and
        will try to make an educated guess about whether it's unicode or an 8-bit encoding.
    */
    virtual const String readEntireStreamAsString();

    /** Reads from the stream and appends the data to a MemoryBlock.

        @param destBlock            the block to append the data onto
        @param maxNumBytesToRead    if this is a positive value, it sets a limit to the number
                                    of bytes that will be read - if it's negative, data
                                    will be read until the stream is exhausted.
        @returns the number of bytes that were added to the memory block
    */
    virtual int readIntoMemoryBlock (MemoryBlock& destBlock,
                                     int maxNumBytesToRead = -1);

    /** Returns the offset of the next byte that will be read from the stream.

        @see setPosition
    */
    virtual int64 getPosition() = 0;

    /** Tries to move the current read position of the stream.

        The position is an absolute number of bytes from the stream's start.

        Some streams might not be able to do this, in which case they should do
        nothing and return false. Others might be able to manage it by resetting
        themselves and skipping to the correct position, although this is
        obviously a bit slow.

        @returns  true if the stream manages to reposition itself correctly
        @see getPosition
    */
    virtual bool setPosition (int64 newPosition) = 0;

    /** Reads and discards a number of bytes from the stream.

        Some input streams might implement this efficiently, but the base
        class will just keep reading data until the requisite number of bytes
        have been done.
    */
    virtual void skipNextBytes (int64 numBytesToSkip);

    juce_UseDebuggingNewOperator

protected:

    InputStream() throw()  {}
};

#endif   // __JUCE_INPUTSTREAM_JUCEHEADER__
/********* End of inlined file: juce_InputStream.h *********/

/**
    The base class for streams that write data to some kind of destination.

    Input and output streams are used throughout the library - subclasses can override
    some or all of the virtual functions to implement their behaviour.

    @see InputStream, MemoryOutputStream, FileOutputStream
*/
class JUCE_API  OutputStream
{
public:
    /** Destructor.

        Some subclasses might want to do things like call flush() during their
        destructors.
    */
    virtual ~OutputStream();

    /** If the stream is using a buffer, this will ensure it gets written
        out to the destination. */
    virtual void flush() = 0;

    /** Tries to move the stream's output position.

        Not all streams will be able to seek to a new position - this will return
        false if it fails to work.

        @see getPosition
    */
    virtual bool setPosition (int64 newPosition) = 0;

    /** Returns the stream's current position.

        @see setPosition
    */
    virtual int64 getPosition() = 0;

    /** Writes a block of data to the stream.

        When creating a subclass of OutputStream, this is the only write method
        that needs to be overloaded - the base class has methods for writing other
        types of data which use this to do the work.

        @returns false if the write operation fails for some reason
    */
    virtual bool write (const void* dataToWrite,
                        int howManyBytes) = 0;

    /** Writes a single byte to the stream.

        @see InputStream::readByte
    */
    virtual void writeByte (char byte);

    /** Writes a boolean to the stream.

        This is encoded as a byte - either 1 or 0.

        @see InputStream::readBool
    */
    virtual void writeBool (bool boolValue);

    /** Writes a 16-bit integer to the stream in a little-endian byte order.

        This will write two bytes to the stream: (value & 0xff), then (value >> 8).

        @see InputStream::readShort
    */
    virtual void writeShort (short value);

    /** Writes a 16-bit integer to the stream in a big-endian byte order.

        This will write two bytes to the stream: (value >> 8), then (value & 0xff).

        @see InputStream::readShortBigEndian
    */
    virtual void writeShortBigEndian (short value);

    /** Writes a 32-bit integer to the stream in a little-endian byte order.

        @see InputStream::readInt
    */
    virtual void writeInt (int value);

    /** Writes a 32-bit integer to the stream in a big-endian byte order.

        @see InputStream::readIntBigEndian
    */
    virtual void writeIntBigEndian (int value);

    /** Writes a 64-bit integer to the stream in a little-endian byte order.

        @see InputStream::readInt64
    */
    virtual void writeInt64 (int64 value);

    /** Writes a 64-bit integer to the stream in a big-endian byte order.

        @see InputStream::readInt64BigEndian
    */
    virtual void writeInt64BigEndian (int64 value);

    /** Writes a 32-bit floating point value to the stream.

        The binary 32-bit encoding of the float is written as a little-endian int.

        @see InputStream::readFloat
    */
    virtual void writeFloat (float value);

    /** Writes a 32-bit floating point value to the stream.

        The binary 32-bit encoding of the float is written as a big-endian int.

        @see InputStream::readFloatBigEndian
    */
    virtual void writeFloatBigEndian (float value);

    /** Writes a 64-bit floating point value to the stream.

        The eight raw bytes of the double value are written out as a little-endian 64-bit int.

        @see InputStream::readDouble
    */
    virtual void writeDouble (double value);

    /** Writes a 64-bit floating point value to the stream.

        The eight raw bytes of the double value are written out as a big-endian 64-bit int.

        @see InputStream::readDoubleBigEndian
    */
    virtual void writeDoubleBigEndian (double value);

    /** Writes a condensed encoding of a 32-bit integer.

        If you're storing a lot of integers which are unlikely to have very large values,
        this can save a lot of space, because values under 0xff will only take up 2 bytes,
        under 0xffff only 3 bytes, etc.

        The format used is: number of significant bytes + up to 4 bytes in little-endian order.

        @see InputStream::readCompressedInt
    */
    virtual void writeCompressedInt (int value);

    /** Stores a string in the stream.

        This isn't the method to use if you're trying to append text to the end of a
        text-file! It's intended for storing a string for later retrieval
        by InputStream::readString.

        For appending text to a file, instead use writeText, printf, or operator<<

        @see InputStream::readString, writeText, printf, operator<<
    */
    virtual void writeString (const String& text);

    /** Writes a string of text to the stream.

        It can either write it as 8-bit system-encoded characters, or as unicode, and
        can also add unicode header bytes (0xff, 0xfe) to indicate the endianness (this
        should only be done at the start of a file).

        The method also replaces '\\n' characters in the text with '\\r\\n'.
    */
    virtual void writeText (const String& text,
                            const bool asUnicode,
                            const bool writeUnicodeHeaderBytes);

    /** Writes a string of text to the stream.

        @see writeText
    */
    virtual void printf (const char* format, ...);

    /** Reads data from an input stream and writes it to this stream.

        @param source               the stream to read from
        @param maxNumBytesToWrite   the number of bytes to read from the stream (if this is
                                    less than zero, it will keep reading until the input
                                    is exhausted)
    */
    virtual int writeFromInputStream (InputStream& source,
                                      int maxNumBytesToWrite);

    /** Writes a number to the stream as 8-bit characters in the default system encoding. */
    virtual OutputStream& operator<< (const int number);

    /** Writes a number to the stream as 8-bit characters in the default system encoding. */
    virtual OutputStream& operator<< (const double number);

    /** Writes a character to the stream. */
    virtual OutputStream& operator<< (const char character);

    /** Writes a null-terminated string to the stream. */
    virtual OutputStream& operator<< (const char* const text);

    /** Writes a null-terminated unicode text string to the stream, converting it
        to 8-bit characters in the default system encoding. */
    virtual OutputStream& operator<< (const juce_wchar* const text);

    /** Writes a string to the stream as 8-bit characters in the default system encoding. */
    virtual OutputStream& operator<< (const String& text);

    juce_UseDebuggingNewOperator

protected:

    OutputStream() throw();
};

#endif   // __JUCE_OUTPUTSTREAM_JUCEHEADER__
/********* End of inlined file: juce_OutputStream.h *********/

/** A handy macro to make it easy to iterate all the child elements in an XmlElement.

    The parentXmlElement should be a reference to the parent XML, and the childElementVariableName
    will be the name of a pointer to each child element.

    E.g. @code
    XmlElement* myParentXml = createSomeKindOfXmlDocument();

    forEachXmlChildElement (*myParentXml, child)
    {
        if (child->hasTagName ("FOO"))
            doSomethingWithXmlElement (child);
    }

    @endcode

    @see forEachXmlChildElementWithTagName
*/
#define forEachXmlChildElement(parentXmlElement, childElementVariableName) \
\
    for (XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \
         childElementVariableName != 0; \
         childElementVariableName = childElementVariableName->getNextElement())

/** A macro that makes it easy to iterate all the child elements of an XmlElement
    which have a specified tag.

    This does the same job as the forEachXmlChildElement macro, but only for those
    elements that have a particular tag name.

    The parentXmlElement should be a reference to the parent XML, and the childElementVariableName
    will be the name of a pointer to each child element. The requiredTagName is the
    tag name to match.

    E.g. @code
    XmlElement* myParentXml = createSomeKindOfXmlDocument();

    forEachXmlChildElementWithTagName (*myParentXml, child, T("MYTAG"))
    {
        // the child object is now guaranteed to be a <MYTAG> element..
        doSomethingWithMYTAGElement (child);
    }

    @endcode

    @see forEachXmlChildElement
*/
#define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \
\
    for (XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \
         childElementVariableName != 0; \
         childElementVariableName = childElementVariableName->getNextElementWithTagName (requiredTagName))

/** Used to build a tree of elements representing an XML document.

    An XML document can be parsed into a tree of XmlElements, each of which
    represents an XML tag structure, and which may itself contain other
    nested elements.

    An XmlElement can also be converted back into a text document, and has
    lots of useful methods for manipulating its attributes and sub-elements,
    so XmlElements can actually be used as a handy general-purpose data
    structure.

    Here's an example of parsing some elements: @code
    // check we're looking at the right kind of document..
    if (myElement->hasTagName ("ANIMALS"))
    {
        // now we'll iterate its sub-elements looking for 'giraffe' elements..
        forEachXmlChildElement (*myElement, e)
        {
            if (e->hasTagName ("GIRAFFE"))
            {
                // found a giraffe, so use some of its attributes..

                String giraffeName  = e->getStringAttribute ("name");
                int giraffeAge      = e->getIntAttribute ("age");
                bool isFriendly     = e->getBoolAttribute ("friendly");
            }
        }
    }
    @endcode

    And here's an example of how to create an XML document from scratch: @code
    // create an outer node called "ANIMALS"
    XmlElement animalsList ("ANIMALS");

    for (int i = 0; i < numAnimals; ++i)
    {
        // create an inner element..
        XmlElement* giraffe = new XmlElement ("GIRAFFE");

        giraffe->setAttribute ("name", "nigel");
        giraffe->setAttribute ("age", 10);
        giraffe->setAttribute ("friendly", true);

        // ..and add our new element to the parent node
        animalsList.addChildElement (giraffe);
    }

    // now we can turn the whole thing into a text document..
    String myXmlDoc = animalsList.createDocument (String::empty);
    @endcode

    @see XmlDocument
*/
class JUCE_API  XmlElement
{
public:

    /** Creates an XmlElement with this tag name. */
    XmlElement (const String& tagName) throw();

    /** Creates a (deep) copy of another element. */
    XmlElement (const XmlElement& other) throw();

    /** Creates a (deep) copy of another element. */
    const XmlElement& operator= (const XmlElement& other) throw();

    /** Deleting an XmlElement will also delete all its child elements. */
    ~XmlElement() throw();

    /** Compares two XmlElements to see if they contain the same text and attiributes.

        The elements are only considered equivalent if they contain the same attiributes
        with the same values, and have the same sub-nodes.

        @param other                    the other element to compare to
        @param ignoreOrderOfAttributes  if true, this means that two elements with the
                                        same attributes in a different order will be
                                        considered the same; if false, the attributes must
                                        be in the same order as well
    */
    bool isEquivalentTo (const XmlElement* const other,
                         const bool ignoreOrderOfAttributes) const throw();

    /** Returns an XML text document that represents this element.

        The string returned can be parsed to recreate the same XmlElement that
        was used to create it.

        @param dtdToUse         the DTD to add to the document
        @param allOnOneLine     if true, this means that the document will not contain any
                                linefeeds, so it'll be smaller but not very easy to read.
        @param includeXmlHeader whether to add the "<?xml version..etc" line at the start of the
                                document
        @param encodingType     the character encoding format string to put into the xml
                                header
        @param lineWrapLength   the line length that will be used before items get placed on
                                a new line. This isn't an absolute maximum length, it just
                                determines how lists of attributes get broken up
        @see writeToFile
    */
    const String createDocument (const String& dtdToUse,
                                 const bool allOnOneLine = false,
                                 const bool includeXmlHeader = true,
                                 const tchar* const encodingType = JUCE_T("UTF-8"),
                                 const int lineWrapLength = 60) const throw();

    /** Writes the element to a file as an XML document.

        To improve safety in case something goes wrong while writing the file, this
        will actually write the document to a new temporary file in the same
        directory as the destination file, and if this succeeds, it will rename this
        new file as the destination file (overwriting any existing file that was there).

        @param destinationFile  the file to write to. If this already exists, it will be
                                overwritten.
        @param dtdToUse         the DTD to add to the document
        @param encodingType     the character encoding format string to put into the xml
                                header
        @param lineWrapLength   the line length that will be used before items get placed on
                                a new line. This isn't an absolute maximum length, it just
                                determines how lists of attributes get broken up
        @returns    true if the file is written successfully; false if something goes wrong
                    in the process
        @see createDocument
    */
    bool writeToFile (const File& destinationFile,
                      const String& dtdToUse,
                      const tchar* const encodingType = JUCE_T("UTF-8"),
                      const int lineWrapLength = 60) const throw();

    /** Returns this element's tag type name.

        E.g. for an element such as \<MOOSE legs="4" antlers="2">, this would return
        "MOOSE".

        @see hasTagName
    */
    inline const String& getTagName() const throw()  { return tagName; }

    /** Tests whether this element has a particular tag name.

        @param possibleTagName  the tag name you're comparing it with

        @see getTagName
    */
    bool hasTagName (const tchar* const possibleTagName) const throw();

    /** Returns the number of XML attributes this element contains.

        E.g. for an element such as \<MOOSE legs="4" antlers="2">, this would
        return 2.
    */
    int getNumAttributes() const throw();

    /** Returns the name of one of the elements attributes.

        E.g. for an element such as \<MOOSE legs="4" antlers="2">, then
        getAttributeName(1) would return "antlers".

        @see getAttributeValue, getStringAttribute
    */
    const String& getAttributeName (const int attributeIndex) const throw();

    /** Returns the value of one of the elements attributes.

        E.g. for an element such as \<MOOSE legs="4" antlers="2">, then
        getAttributeName(1) would return "2".

        @see getAttributeName, getStringAttribute
    */
    const String& getAttributeValue (const int attributeIndex) const throw();

    // Attribute-handling methods..

    /** Checks whether the element contains an attribute with a certain name. */
    bool hasAttribute (const tchar* const attributeName) const throw();

    /** Returns the value of a named attribute.

        @param attributeName        the name of the attribute to look up
        @param defaultReturnValue   a value to return if the element doesn't have an attribute
                                    with this name
    */
    const String getStringAttribute (const tchar* const attributeName,
                                     const tchar* const defaultReturnValue = 0) const throw();

    /** Compares the value of a named attribute with a value passed-in.

        @param attributeName            the name of the attribute to look up
        @param stringToCompareAgainst   the value to compare it with
        @param ignoreCase               whether the comparison should be case-insensitive
        @returns    true if the value of the attribute is the same as the string passed-in;
                    false if it's different (or if no such attribute exists)
    */
    bool compareAttribute (const tchar* const attributeName,
                           const tchar* const stringToCompareAgainst,
                           const bool ignoreCase = false) const throw();

    /** Returns the value of a named attribute as an integer.

        This will try to find the attribute and convert it to an integer (using
        the String::getIntValue() method).

        @param attributeName        the name of the attribute to look up
        @param defaultReturnValue   a value to return if the element doesn't have an attribute
                                    with this name
        @see setAttribute (const tchar* const, int)
    */
    int getIntAttribute (const tchar* const attributeName,
                         const int defaultReturnValue = 0) const throw();

    /** Returns the value of a named attribute as floating-point.

        This will try to find the attribute and convert it to an integer (using
        the String::getDoubleValue() method).

        @param attributeName        the name of the attribute to look up
        @param defaultReturnValue   a value to return if the element doesn't have an attribute
                                    with this name
        @see setAttribute (const tchar* const, double)
    */
    double getDoubleAttribute (const tchar* const attributeName,
                               const double defaultReturnValue = 0.0) const throw();

    /** Returns the value of a named attribute as a boolean.

        This will try to find the attribute and interpret it as a boolean. To do this,
        it'll return true if the value is "1", "true", "y", etc, or false for other
        values.

        @param attributeName        the name of the attribute to look up
        @param defaultReturnValue   a value to return if the element doesn't have an attribute
                                    with this name
    */
    bool getBoolAttribute (const tchar* const attributeName,
                           const bool defaultReturnValue = false) const throw();

    /** Adds a named attribute to the element.

        If the element already contains an attribute with this name, it's value will
        be updated to the new value. If there's no such attribute yet, a new one will
        be added.

        Note that there are other setAttribute() methods that take integers,
        doubles, etc. to make it easy to store numbers.

        @param attributeName        the name of the attribute to set
        @param newValue             the value to set it to
        @see removeAttribute
    */
    void setAttribute (const tchar* const attributeName,
                       const String& newValue) throw();

    /** Adds a named attribute to the element.

        If the element already contains an attribute with this name, it's value will
        be updated to the new value. If there's no such attribute yet, a new one will
        be added.

        Note that there are other setAttribute() methods that take integers,
        doubles, etc. to make it easy to store numbers.

        @param attributeName        the name of the attribute to set
        @param newValue             the value to set it to
    */
    void setAttribute (const tchar* const attributeName,
                       const tchar* const newValue) throw();

    /** Adds a named attribute to the element, setting it to an integer value.

        If the element already contains an attribute with this name, it's value will
        be updated to the new value. If there's no such attribute yet, a new one will
        be added.

        Note that there are other setAttribute() methods that take integers,
        doubles, etc. to make it easy to store numbers.

        @param attributeName        the name of the attribute to set
        @param newValue             the value to set it to
    */
    void setAttribute (const tchar* const attributeName,
                       const int newValue) throw();

    /** Adds a named attribute to the element, setting it to a floating-point value.

        If the element already contains an attribute with this name, it's value will
        be updated to the new value. If there's no such attribute yet, a new one will
        be added.

        Note that there are other setAttribute() methods that take integers,
        doubles, etc. to make it easy to store numbers.

        @param attributeName        the name of the attribute to set
        @param newValue             the value to set it to
    */
    void setAttribute (const tchar* const attributeName,
                       const double newValue) throw();

    /** Removes a named attribute from the element.

        @param attributeName    the name of the attribute to remove
        @see removeAllAttributes
    */
    void removeAttribute (const tchar* const attributeName) throw();

    /** Removes all attributes from this element.
    */
    void removeAllAttributes() throw();

    // Child element methods..

    /** Returns the first of this element's sub-elements.

        see getNextElement() for an example of how to iterate the sub-elements.

        @see forEachXmlChildElement
    */
    XmlElement* getFirstChildElement() const throw()    { return firstChildElement; }

    /** Returns the next of this element's siblings.

        This can be used for iterating an element's sub-elements, e.g.
        @code
        XmlElement* child = myXmlDocument->getFirstChildElement();

        while (child != 0)
        {
            ...do stuff with this child..

            child = child->getNextElement();
        }
        @endcode

        Note that when iterating the child elements, some of them might be
        text elements as well as XML tags - use isTextElement() to work this
        out.

        Also, it's much easier and neater to use this method indirectly via the
        forEachXmlChildElement macro.

        @returns    the sibling element that follows this one, or zero if this is the last
                    element in its parent

        @see getNextElement, isTextElement, forEachXmlChildElement
    */
    inline XmlElement* getNextElement() const throw()   { return nextElement; }

    /** Returns the next of this element's siblings which has the specified tag
        name.

        This is like getNextElement(), but will scan through the list until it
        finds an element with the given tag name.

        @see getNextElement, forEachXmlChildElementWithTagName
    */
    XmlElement* getNextElementWithTagName (const tchar* const requiredTagName) const;

    /** Returns the number of sub-elements in this element.

        @see getChildElement
    */
    int getNumChildElements() const throw();

    /** Returns the sub-element at a certain index.

        It's not very efficient to iterate the sub-elements by index - see
        getNextElement() for an example of how best to iterate.

        @returns the n'th child of this element, or 0 if the index is out-of-range
        @see getNextElement, isTextElement, getChildByName
    */
    XmlElement* getChildElement (const int index) const throw();

    /** Returns the first sub-element with a given tag-name.

        @param tagNameToLookFor     the tag name of the element you want to find
        @returns the first element with this tag name, or 0 if none is found
        @see getNextElement, isTextElement, getChildElement
    */
    XmlElement* getChildByName (const tchar* const tagNameToLookFor) const throw();

    /** Appends an element to this element's list of children.

        Child elements are deleted automatically when their parent is deleted, so
        make sure the object that you pass in will not be deleted by anything else,
        and make sure it's not already the child of another element.

        @see getFirstChildElement, getNextElement, getNumChildElements,
             getChildElement, removeChildElement
    */
    void addChildElement (XmlElement* const newChildElement) throw();

    /** Inserts an element into this element's list of children.

        Child elements are deleted automatically when their parent is deleted, so
        make sure the object that you pass in will not be deleted by anything else,
        and make sure it's not already the child of another element.

        @param newChildNode     the element to add
        @param indexToInsertAt  the index at which to insert the new element - if this is
                                below zero, it will be added to the end of the list
        @see addChildElement, insertChildElement
    */
    void insertChildElement (XmlElement* const newChildNode,
                             int indexToInsertAt) throw();

    /** Replaces one of this element's children with another node.

        If the current element passed-in isn't actually a child of this element,
        this will return false and the new one won't be added. Otherwise, the
        existing element will be deleted, replaced with the new one, and it
        will return true.
    */
    bool replaceChildElement (XmlElement* const currentChildElement,
                              XmlElement* const newChildNode) throw();

    /** Removes a child element.

        @param childToRemove            the child to look for and remove
        @param shouldDeleteTheChild     if true, the child will be deleted, if false it'll
                                        just remove it
    */
    void removeChildElement (XmlElement* const childToRemove,
                             const bool shouldDeleteTheChild) throw();

    /** Deletes all the child elements in the element.

        @see removeChildElement, deleteAllChildElementsWithTagName
    */
    void deleteAllChildElements() throw();

    /** Deletes all the child elements with a given tag name.

        @see removeChildElement
    */
    void deleteAllChildElementsWithTagName (const tchar* const tagName) throw();

    /** Returns true if the given element is a child of this one. */
    bool containsChildElement (const XmlElement* const possibleChild) const throw();

    /** Recursively searches all sub-elements to find one that contains the specified
        child element.
    */
    XmlElement* findParentElementOf (const XmlElement* const elementToLookFor) throw();

    /** Sorts the child elements using a comparator.

        This will use a comparator object to sort the elements into order. The object
        passed must have a method of the form:
        @code
        int compareElements (const XmlElement* first, const XmlElement* second);
        @endcode

        ..and this method must return:
          - a value of < 0 if the first comes before the second
          - a value of 0 if the two objects are equivalent
          - a value of > 0 if the second comes before the first

        To improve performance, the compareElements() method can be declared as static or const.

        @param comparator   the comparator to use for comparing elements.
        @param retainOrderOfEquivalentItems     if this is true, then items
                            which the comparator says are equivalent will be
                            kept in the order in which they currently appear
                            in the array. This is slower to perform, but may
                            be important in some cases. If it's false, a faster
                            algorithm is used, but equivalent elements may be
                            rearranged.
    */
    template <class ElementComparator>
    void sortChildElements (ElementComparator& comparator,
                            const bool retainOrderOfEquivalentItems = false) throw()
    {
        const int num = getNumChildElements();

        if (num > 1)
        {
            XmlElement** const elems = getChildElementsAsArray (num);
            sortArray (comparator, elems, 0, num - 1, retainOrderOfEquivalentItems);
            reorderChildElements (elems, num);
            delete[] elems;
        }
    }

    /** Returns true if this element is a section of text.

        Elements can either be an XML tag element or a secton of text, so this
        is used to find out what kind of element this one is.

        @see getAllText, addTextElement, deleteAllTextElements
    */
    bool isTextElement() const throw();

    /** Returns the text for a text element.

        Note that if you have an element like this:

        @code<xyz>hello</xyz>@endcode

        then calling getText on the "xyz" element won't return "hello", because that is
        actually stored in a special text sub-element inside the xyz element. To get the
        "hello" string, you could either call getText on the (unnamed) sub-element, or
        use getAllSubText() to do this automatically.

        @see isTextElement, getAllSubText, getChildElementAllSubText
    */
    const String getText() const throw();

    /** Sets the text in a text element.

        Note that this is only a valid call if this element is a text element. If it's
        not, then no action will be performed.
    */
    void setText (const String& newText) throw();

    /** Returns all the text from this element's child nodes.

        This iterates all the child elements and when it finds text elements,
        it concatenates their text into a big string which it returns.

        E.g. @code<xyz> hello <x></x> there </xyz>@endcode
        if you called getAllSubText on the "xyz" element, it'd return "hello there".

        @see isTextElement, getChildElementAllSubText, getText, addTextElement
    */
    const String getAllSubText() const throw();

    /** Returns all the sub-text of a named child element.

        If there is a child element with the given tag name, this will return
        all of its sub-text (by calling getAllSubText() on it). If there is
        no such child element, this will return the default string passed-in.

        @see getAllSubText
    */
    const String getChildElementAllSubText (const tchar* const childTagName,
                                            const String& defaultReturnValue) const throw();

    /** Appends a section of text to this element.

        @see isTextElement, getText, getAllSubText
    */
    void addTextElement (const String& text) throw();

    /** Removes all the text elements from this element.

        @see isTextElement, getText, getAllSubText, addTextElement
    */
    void deleteAllTextElements() throw();

    /** Creates a text element that can be added to a parent element.
    */
    static XmlElement* createTextElement (const String& text) throw();

    juce_UseDebuggingNewOperator

private:
    friend class XmlDocument;

    String tagName;
    XmlElement* firstChildElement;
    XmlElement* nextElement;

    struct XmlAttributeNode
    {
        XmlAttributeNode (const XmlAttributeNode& other) throw();
        XmlAttributeNode (const String& name, const String& value) throw();

        String name, value;
        XmlAttributeNode* next;
    };

    XmlAttributeNode* attributes;

    XmlElement (int) throw(); // for internal use
    XmlElement (const tchar* const tagNameText, const int nameLen) throw();

    void copyChildrenAndAttributesFrom (const XmlElement& other) throw();

    void writeElementAsText (OutputStream& out,
                             const int indentationLevel,
                             const int lineWrapLength) const throw();

    XmlElement** getChildElementsAsArray (const int) const throw();
    void reorderChildElements (XmlElement** const, const int) throw();
};

#endif   // __JUCE_XMLELEMENT_JUCEHEADER__
/********* End of inlined file: juce_XmlElement.h *********/

/**
    A set of named property values, which can be strings, integers, floating point, etc.

    Effectively, this just wraps a StringPairArray in an interface that makes it easier
    to load and save types other than strings.

    See the PropertiesFile class for a subclass of this, which automatically broadcasts change
    messages and saves/loads the list from a file.
*/
class JUCE_API  PropertySet
{
public:

    /** Creates an empty PropertySet.

        @param ignoreCaseOfKeyNames         if true, the names of properties are compared in a
                                            case-insensitive way
    */
    PropertySet (const bool ignoreCaseOfKeyNames = false) throw();

    /** Creates a copy of another PropertySet.
    */
    PropertySet (const PropertySet& other) throw();

    /** Copies another PropertySet over this one.
    */
    const PropertySet& operator= (const PropertySet& other) throw();

    /** Destructor. */
    virtual ~PropertySet();

    /** Returns one of the properties as a string.

        If the value isn't found in this set, then this will look for it in a fallback
        property set (if you've specified one with the setFallbackPropertySet() method),
        and if it can't find one there, it'll return the default value passed-in.

        @param keyName              the name of the property to retrieve
        @param defaultReturnValue   a value to return if the named property doesn't actually exist
    */
    const String getValue (const String& keyName,
                           const String& defaultReturnValue = String::empty) const throw();

    /** Returns one of the properties as an integer.

        If the value isn't found in this set, then this will look for it in a fallback
        property set (if you've specified one with the setFallbackPropertySet() method),
        and if it can't find one there, it'll return the default value passed-in.

        @param keyName              the name of the property to retrieve
        @param defaultReturnValue   a value to return if the named property doesn't actually exist
    */
    int getIntValue (const String& keyName,
                     const int defaultReturnValue = 0) const throw();

    /** Returns one of the properties as an double.

        If the value isn't found in this set, then this will look for it in a fallback
        property set (if you've specified one with the setFallbackPropertySet() method),
        and if it can't find one there, it'll return the default value passed-in.

        @param keyName              the name of the property to retrieve
        @param defaultReturnValue   a value to return if the named property doesn't actually exist
    */
    double getDoubleValue (const String& keyName,
                           const double defaultReturnValue = 0.0) const throw();

    /** Returns one of the properties as an boolean.

        The result will be true if the string found for this key name can be parsed as a non-zero
        integer.

        If the value isn't found in this set, then this will look for it in a fallback
        property set (if you've specified one with the setFallbackPropertySet() method),
        and if it can't find one there, it'll return the default value passed-in.

        @param keyName              the name of the property to retrieve
        @param defaultReturnValue   a value to return if the named property doesn't actually exist
    */
    bool getBoolValue (const String& keyName,
                       const bool defaultReturnValue = false) const throw();

    /** Returns one of the properties as an XML element.

        The result will a new XMLElement object that the caller must delete. If may return 0 if the
        key isn't found, or if the entry contains an string that isn't valid XML.

        If the value isn't found in this set, then this will look for it in a fallback
        property set (if you've specified one with the setFallbackPropertySet() method),
        and if it can't find one there, it'll return the default value passed-in.

        @param keyName              the name of the property to retrieve
    */
    XmlElement* getXmlValue (const String& keyName) const;

    /** Sets a named property as a string.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param value        the new value to set it to
    */
    void setValue (const String& keyName, const String& value) throw();

    /** Sets a named property as a string.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param value        the new value to set it to
    */
    void setValue (const String& keyName, const tchar* const value) throw();

    /** Sets a named property to an integer.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param value        the new value to set it to
    */
    void setValue (const String& keyName, const int value) throw();

    /** Sets a named property to a double.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param value        the new value to set it to
    */
    void setValue (const String& keyName, const double value) throw();

    /** Sets a named property to a boolean.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param value        the new value to set it to
    */
    void setValue (const String& keyName, const bool value) throw();

    /** Sets a named property to an XML element.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param xml          the new element to set it to. If this is zero, the value will be set to
                            an empty string
        @see getXmlValue
    */
    void setValue (const String& keyName, const XmlElement* const xml);

    /** Deletes a property.

        @param keyName      the name of the property to delete. (This mustn't be an empty string)
    */
    void removeValue (const String& keyName) throw();

    /** Returns true if the properies include the given key. */
    bool containsKey (const String& keyName) const throw();

    /** Removes all values. */
    void clear();

    /** Returns the keys/value pair array containing all the properties. */
    StringPairArray& getAllProperties() throw()                         { return properties; }

    /** Returns the lock used when reading or writing to this set */
    const CriticalSection& getLock() const throw()                      { return lock; }

    /** Returns an XML element which encapsulates all the items in this property set.

        The string parameter is the tag name that should be used for the node.

        @see restoreFromXml
    */
    XmlElement* createXml (const String& nodeName) const throw();

    /** Reloads a set of properties that were previously stored as XML.

        The node passed in must have been created by the createXml() method.

        @see createXml
    */
    void restoreFromXml (const XmlElement& xml) throw();

    /** Sets up a second PopertySet that will be used to look up any values that aren't
        set in this one.

        If you set this up to be a pointer to a second property set, then whenever one
        of the getValue() methods fails to find an entry in this set, it will look up that
        value in the fallback set, and if it finds it, it will return that.

        Make sure that you don't delete the fallback set while it's still being used by
        another set! To remove the fallback set, just call this method with a null pointer.

        @see getFallbackPropertySet
    */
    void setFallbackPropertySet (PropertySet* fallbackProperties) throw();

    /** Returns the fallback property set.
        @see setFallbackPropertySet
    */
    PropertySet* getFallbackPropertySet() const throw()                 { return fallbackProperties; }

    juce_UseDebuggingNewOperator

protected:

    /** Subclasses can override this to be told when one of the properies has been changed.
    */
    virtual void propertyChanged();

private:

    StringPairArray properties;
    PropertySet* fallbackProperties;
    CriticalSection lock;
    bool ignoreCaseOfKeys;
};

#endif   // __JUCE_PROPERTYSET_JUCEHEADER__
/********* End of inlined file: juce_PropertySet.h *********/

#endif
#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__

/********* Start of inlined file: juce_ReferenceCountedObject.h *********/
#ifndef __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
#define __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__

/**
    Adds reference-counting to an object.

    To add reference-counting to a class, derive it from this class, and
    use the ReferenceCountedObjectPtr class to point to it.

    e.g. @code
    class MyClass : public ReferenceCountedObject
    {
        void foo();

        // This is a neat way of declaring a typedef for a pointer class,
        // rather than typing out the full templated name each time..
        typedef ReferenceCountedObjectPtr<MyClass> Ptr;
    };

    MyClass::Ptr p = new MyClass();
    MyClass::Ptr p2 = p;
    p = 0;
    p2->foo();
    @endcode

    Once a new ReferenceCountedObject has been assigned to a pointer, be
    careful not to delete the object manually.

    @see ReferenceCountedObjectPtr, ReferenceCountedArray
*/
class JUCE_API  ReferenceCountedObject
{
public:

    /** Increments the object's reference count.

        This is done automatically by the smart pointer, but is public just
        in case it's needed for nefarious purposes.
    */
    inline void incReferenceCount() throw()
    {
        atomicIncrement (refCounts);

        jassert (refCounts > 0);
    }

    /** Decreases the object's reference count.

        If the count gets to zero, the object will be deleted.
    */
    inline void decReferenceCount() throw()
    {
        jassert (refCounts > 0);

        if (atomicDecrementAndReturn (refCounts) == 0)
            delete this;
    }

    /** Returns the object's current reference count. */
    inline int getReferenceCount() const throw()
    {
        return refCounts;
    }

protected:

    /** Creates the reference-counted object (with an initial ref count of zero). */
    ReferenceCountedObject()
        : refCounts (0)
    {
    }

    /** Destructor. */
    virtual ~ReferenceCountedObject()
    {
        // it's dangerous to delete an object that's still referenced by something else!
        jassert (refCounts == 0);
    }

private:

    int refCounts;
};

/**
    Used to point to an object of type ReferenceCountedObject.

    It's wise to use a typedef instead of typing out the templated name
    each time - e.g.

    typedef ReferenceCountedObjectPtr<MyClass> MyClassPtr;

    @see ReferenceCountedObject, ReferenceCountedObjectArray
*/
template <class ReferenceCountedObjectClass>
class ReferenceCountedObjectPtr
{
public:

    /** Creates a pointer to a null object. */
    inline ReferenceCountedObjectPtr() throw()
        : referencedObject (0)
    {
    }

    /** Creates a pointer to an object.

        This will increment the object's reference-count if it is non-null.
    */
    inline ReferenceCountedObjectPtr (ReferenceCountedObjectClass* const refCountedObject) throw()
        : referencedObject (refCountedObject)
    {
        if (refCountedObject != 0)
            refCountedObject->incReferenceCount();
    }

    /** Copies another pointer.

        This will increment the object's reference-count (if it is non-null).
    */
    inline ReferenceCountedObjectPtr (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& other) throw()
        : referencedObject (other.referencedObject)
    {
        if (referencedObject != 0)
            referencedObject->incReferenceCount();
    }

    /** Changes this pointer to point at a different object.

        The reference count of the old object is decremented, and it might be
        deleted if it hits zero. The new object's count is incremented.
    */
    const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& operator= (const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& other)
    {
        ReferenceCountedObjectClass* const newObject = other.referencedObject;

        if (newObject != referencedObject)
        {
            if (newObject != 0)
                newObject->incReferenceCount();

            ReferenceCountedObjectClass* const oldObject = referencedObject;
            referencedObject = newObject;

            if (oldObject != 0)
                oldObject->decReferenceCount();
        }

        return *this;
    }

    /** Changes this pointer to point at a different object.

        The reference count of the old object is decremented, and it might be
        deleted if it hits zero. The new object's count is incremented.
    */
    const ReferenceCountedObjectPtr<ReferenceCountedObjectClass>& operator= (ReferenceCountedObjectClass* const newObject)
    {
        if (referencedObject != newObject)
        {
            if (newObject != 0)
                newObject->incReferenceCount();

            ReferenceCountedObjectClass* const oldObject = referencedObject;
            referencedObject = newObject;

            if (oldObject != 0)
                oldObject->decReferenceCount();
        }

        return *this;
    }

    /** Destructor.

        This will decrement the object's reference-count, and may delete it if it
        gets to zero.
    */
    inline ~ReferenceCountedObjectPtr()
    {
        if (referencedObject != 0)
            referencedObject->decReferenceCount();
    }

    /** Returns the object that this pointer references.

        The pointer returned may be zero, of course.
    */
    inline operator ReferenceCountedObjectClass*() const throw()
    {
        return referencedObject;
    }

    /** Returns true if this pointer refers to the given object. */
    inline bool operator== (ReferenceCountedObjectClass* const object) const throw()
    {
        return referencedObject == object;
    }

    /** Returns true if this pointer doesn't refer to the given object. */
    inline bool operator!= (ReferenceCountedObjectClass* const object) const throw()
    {
        return referencedObject != object;
    }

    // the -> operator is called on the referenced object
    inline ReferenceCountedObjectClass* operator->() const throw()
    {
        return referencedObject;
    }

private:

    ReferenceCountedObjectClass* referencedObject;
};

#endif   // __JUCE_REFERENCECOUNTEDOBJECT_JUCEHEADER__
/********* End of inlined file: juce_ReferenceCountedObject.h *********/

#endif
#ifndef __JUCE_SPARSESET_JUCEHEADER__

/********* Start of inlined file: juce_SparseSet.h *********/
#ifndef __JUCE_SPARSESET_JUCEHEADER__
#define __JUCE_SPARSESET_JUCEHEADER__

/**
    Holds a set of primitive values, storing them as a set of ranges.

    This container acts like a simple BitArray, but can efficiently hold large
    continguous ranges of values. It's quite a specialised class, mostly useful
    for things like keeping the set of selected rows in a listbox.

    The type used as a template paramter must be an integer type, such as int, short,
    int64, etc.
*/
template <class Type>
class SparseSet
{
public:

    /** Creates a new empty set. */
    SparseSet() throw()
    {
    }

    /** Creates a copy of another SparseSet. */
    SparseSet (const SparseSet<Type>& other) throw()
        : values (other.values)
    {
    }

    /** Destructor. */
    ~SparseSet() throw()
    {
    }

    /** Clears the set. */
    void clear() throw()
    {
        values.clear();
    }

    /** Checks whether the set is empty.

        This is much quicker than using (size() == 0).
    */
    bool isEmpty() const throw()
    {
        return values.size() == 0;
    }

    /** Returns the number of values in the set.

        Because of the way the data is stored, this method can take longer if there
        are a lot of items in the set. Use isEmpty() for a quick test of whether there
        are any items.
    */
    Type size() const throw()
    {
        Type num = 0;

        for (int i = 0; i < values.size(); i += 2)
            num += values[i + 1] - values[i];

        return num;
    }

    /** Returns one of the values in the set.

        @param index    the index of the value to retrieve, in the range 0 to (size() - 1).
        @returns        the value at this index, or 0 if it's out-of-range
    */
    Type operator[] (int index) const throw()
    {
        for (int i = 0; i < values.size(); i += 2)
        {
            const Type s = values.getUnchecked(i);
            const Type e = values.getUnchecked(i + 1);

            if (index < e - s)
                return s + index;

            index -= e - s;
        }

        return (Type) 0;
    }

    /** Checks whether a particular value is in the set. */
    bool contains (const Type valueToLookFor) const throw()
    {
        bool on = false;

        for (int i = 0; i < values.size(); ++i)
        {
            if (values.getUnchecked(i) > valueToLookFor)
                return on;

            on = ! on;
        }

        return false;
    }

    /** Returns the number of contiguous blocks of values.

        @see getRange
    */
    int getNumRanges() const throw()
    {
        return values.size() >> 1;
    }

    /** Returns one of the contiguous ranges of values stored.

        @param rangeIndex   the index of the range to look up, between 0
                            and (getNumRanges() - 1)
        @param startValue   on return, the value at the start of the range
        @param numValues    on return, the number of values in the range

        @see getTotalRange
    */
    bool getRange (const int rangeIndex,
                   Type& startValue,
                   Type& numValues) const throw()
    {
        if (((unsigned int) rangeIndex) < (unsigned int) getNumRanges())
        {
            startValue = values [rangeIndex << 1];
            numValues = values [(rangeIndex << 1) + 1] - startValue;

            return true;
        }

        return false;
    }

    /** Returns the lowest and highest values in the set.

        @see getRange
    */
    bool getTotalRange (Type& lowestValue,
                        Type& highestValue) const throw()
    {
        if (values.size() > 0)
        {
            lowestValue = values.getUnchecked (0);
            highestValue = values.getUnchecked (values.size() - 1);
            return true;
        }

        return false;
    }

    /** Adds a range of contiguous values to the set.

        e.g. addRange (10, 4) will add (10, 11, 12, 13) to the set.

        @param firstValue       the start of the range of values to add
        @param numValuesToAdd   how many values to add
    */
    void addRange (const Type firstValue,
                   const Type numValuesToAdd) throw()
    {
        jassert (numValuesToAdd >= 0);

        if (numValuesToAdd > 0)
        {
            removeRange (firstValue, numValuesToAdd);

            IntegerElementComparator<Type> sorter;
            values.addSorted (sorter, firstValue);
            values.addSorted (sorter, firstValue + numValuesToAdd);

            simplify();
        }
    }

    /** Removes a range of values from the set.

        e.g. removeRange (10, 4) will remove (10, 11, 12, 13) from the set.

        @param firstValue           the start of the range of values to remove
        @param numValuesToRemove    how many values to remove
    */
    void removeRange (const Type firstValue,
                      const Type numValuesToRemove) throw()
    {
        jassert (numValuesToRemove >= 0);

        if (numValuesToRemove >= 0
             && firstValue < values.getLast())
        {
            const bool onAtStart = contains (firstValue - 1);
            const Type lastValue = firstValue + jmin (numValuesToRemove, values.getLast() - firstValue);
            const bool onAtEnd = contains (lastValue);

            for (int i = values.size(); --i >= 0;)
            {
                if (values.getUnchecked(i) <= lastValue)
                {
                    while (values.getUnchecked(i) >= firstValue)
                    {
                        values.remove (i);

                        if (--i < 0)
                            break;
                    }

                    break;
                }
            }

            IntegerElementComparator<Type> sorter;

            if (onAtStart)
                values.addSorted (sorter, firstValue);

            if (onAtEnd)
                values.addSorted (sorter, lastValue);

            simplify();
        }
    }

    /** Does an XOR of the values in a given range. */
    void invertRange (const Type firstValue,
                      const Type numValues)
    {
        SparseSet newItems;
        newItems.addRange (firstValue, numValues);

        int i;
        for (i = getNumRanges(); --i >= 0;)
        {
            const int start = values [i << 1];
            const int end = values [(i << 1) + 1];

            newItems.removeRange (start, end);
        }

        removeRange (firstValue, numValues);

        for (i = newItems.getNumRanges(); --i >= 0;)
        {
            const int start = newItems.values [i << 1];
            const int end = newItems.values [(i << 1) + 1];

            addRange (start, end);
        }
    }

    /** Checks whether any part of a given range overlaps any part of this one. */
    bool overlapsRange (const Type firstValue,
                        const Type numValues) throw()
    {
        jassert (numValues >= 0);

        if (numValues > 0)
        {
            for (int i = getNumRanges(); --i >= 0;)
            {
                if (firstValue >= values.getUnchecked ((i << 1) + 1))
                    return false;

                if (firstValue + numValues > values.getUnchecked (i << 1))
                    return true;
            }
        }

        return false;
    }

    /** Checks whether the whole of a given range is contained within this one. */
    bool containsRange (const Type firstValue,
                        const Type numValues) throw()
    {
        jassert (numValues >= 0);

        if (numValues > 0)
        {
            for (int i = getNumRanges(); --i >= 0;)
            {
                if (firstValue >= values.getUnchecked ((i << 1) + 1))
                    return false;

                if (firstValue >= values.getUnchecked (i << 1)
                     && firstValue + numValues <= values.getUnchecked ((i << 1) + 1))
                    return true;
            }
        }

        return false;
    }

    bool operator== (const SparseSet<Type>& other) throw()
    {
        return values == other.values;
    }

    bool operator!= (const SparseSet<Type>& other) throw()
    {
        return values != other.values;
    }

    juce_UseDebuggingNewOperator

private:
    // alternating start/end values of ranges of values that are present.
    Array<Type> values;

    void simplify() throw()
    {
        jassert ((values.size() & 1) == 0);

        for (int i = values.size(); --i > 0;)
            if (values.getUnchecked(i) == values.getUnchecked (i - 1))
                values.removeRange (i - 1, 2);
    }
};

#endif   // __JUCE_SPARSESET_JUCEHEADER__
/********* End of inlined file: juce_SparseSet.h *********/

#endif
#ifndef __JUCE_VOIDARRAY_JUCEHEADER__

#endif
#ifndef __JUCE_SORTEDSET_JUCEHEADER__

/********* Start of inlined file: juce_SortedSet.h *********/
#ifndef __JUCE_SORTEDSET_JUCEHEADER__
#define __JUCE_SORTEDSET_JUCEHEADER__

#if JUCE_MSVC
  #pragma warning (push)
  #pragma warning (disable: 4512)
#endif

/**
    Holds a set of unique primitive objects, such as ints or doubles.

    A set can only hold one item with a given value, so if for example it's a
    set of integers, attempting to add the same integer twice will do nothing
    the second time.

    Internally, the list of items is kept sorted (which means that whatever
    kind of primitive type is used must support the ==, <, >, <= and >= operators
    to determine the order), and searching the set for known values is very fast
    because it uses a binary-chop method.

    Note that if you're using a class or struct as the element type, it must be
    capable of being copied or moved with a straightforward memcpy, rather than
    needing construction and destruction code.

    To make all the set's methods thread-safe, pass in "CriticalSection" as the templated
    TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.

    @see Array, OwnedArray, ReferenceCountedArray, StringArray, CriticalSection
*/
template <class ElementType, class TypeOfCriticalSectionToUse = DummyCriticalSection>
class SortedSet   : private ArrayAllocationBase <ElementType>
{
public:

    /** Creates an empty set.

        @param granularity  this is the size of increment by which the internal storage
        used by the array will grow. Only change it from the default if you know the
        array is going to be very big and needs to be able to grow efficiently.

        @see ArrayAllocationBase
    */
    SortedSet (const int granularity = juceDefaultArrayGranularity) throw()
       : ArrayAllocationBase <ElementType> (granularity),
         numUsed (0)
    {
    }

    /** Creates a copy of another set.
        @param other    the set to copy
    */
    SortedSet (const SortedSet<ElementType, TypeOfCriticalSectionToUse>& other) throw()
       : ArrayAllocationBase <ElementType> (other.granularity)
    {
        other.lockSet();
        numUsed = other.numUsed;
        setAllocatedSize (other.numUsed);
        memcpy (this->elements, other.elements, numUsed * sizeof (ElementType));
        other.unlockSet();
    }

    /** Destructor. */
    ~SortedSet() throw()
    {
    }

    /** Copies another set over this one.
        @param other    the set to copy
    */
    const SortedSet <ElementType, TypeOfCriticalSectionToUse>& operator= (const SortedSet <ElementType, TypeOfCriticalSectionToUse>& other) throw()
    {
        if (this != &other)
        {
            other.lockSet();
            lock.enter();

            this->granularity = other.granularity;
            ensureAllocatedSize (other.size());
            numUsed = other.numUsed;
            memcpy (this->elements, other.elements, numUsed * sizeof (ElementType));
            minimiseStorageOverheads();

            lock.exit();
            other.unlockSet();
        }

        return *this;
    }

    /** Compares this set to another one.

        Two sets are considered equal if they both contain the same set of
        elements.

        @param other    the other set to compare with
    */
    bool operator== (const SortedSet<ElementType>& other) const throw()
    {
        lock.enter();

        if (numUsed != other.numUsed)
        {
            lock.exit();
            return false;
        }

        for (int i = numUsed; --i >= 0;)
        {
            if (this->elements [i] != other.elements [i])
            {
                lock.exit();
                return false;
            }
        }

        lock.exit();
        return true;
    }

    /** Compares this set to another one.

        Two sets are considered equal if they both contain the same set of
        elements.

        @param other    the other set to compare with
    */
    bool operator!= (const SortedSet<ElementType>& other) const throw()
    {
        return ! operator== (other);
    }

    /** Removes all elements from the set.

        This will remove all the elements, and free any storage that the set is
        using. To clear it without freeing the storage, use the clearQuick()
        method instead.

        @see clearQuick
    */
    void clear() throw()
    {
        lock.enter();
        this->setAllocatedSize (0);
        numUsed = 0;
        lock.exit();
    }

    /** Removes all elements from the set without freeing the array's allocated storage.

        @see clear
    */
    void clearQuick() throw()
    {
        lock.enter();
        numUsed = 0;
        lock.exit();
    }

    /** Returns the current number of elements in the set.
    */
    inline int size() const throw()
    {
        return numUsed;
    }

    /** Returns one of the elements in the set.

        If the index passed in is beyond the range of valid elements, this
        will return zero.

        If you're certain that the index will always be a valid element, you
        can call getUnchecked() instead, which is faster.

        @param index    the index of the element being requested (0 is the first element in the set)
        @see getUnchecked, getFirst, getLast
    */
    inline ElementType operator[] (const int index) const throw()
    {
        lock.enter();
        const ElementType result = (((unsigned int) index) < (unsigned int) numUsed)
                                        ? this->elements [index]
                                        : (ElementType) 0;
        lock.exit();

        return result;
    }

    /** Returns one of the elements in the set, without checking the index passed in.
        Unlike the operator[] method, this will try to return an element without
        checking that the index is within the bounds of the set, so should only
        be used when you're confident that it will always be a valid index.

        @param index    the index of the element being requested (0 is the first element in the set)
        @see operator[], getFirst, getLast
    */
    inline ElementType getUnchecked (const int index) const throw()
    {
        lock.enter();
        jassert (((unsigned int) index) < (unsigned int) numUsed);
        const ElementType result = this->elements [index];
        lock.exit();

        return result;
    }

    /** Returns the first element in the set, or 0 if the set is empty.

        @see operator[], getUnchecked, getLast
    */
    inline ElementType getFirst() const throw()
    {
        lock.enter();
        const ElementType result = (numUsed > 0) ? this->elements [0]
                                                 : (ElementType) 0;
        lock.exit();

        return result;
    }

    /** Returns the last element in the set, or 0 if the set is empty.

        @see operator[], getUnchecked, getFirst
    */
    inline ElementType getLast() const throw()
    {
        lock.enter();
        const ElementType result = (numUsed > 0) ? this->elements [numUsed - 1]
                                                 : (ElementType) 0;
        lock.exit();

        return result;
    }

    /** Finds the index of the first element which matches the value passed in.

        This will search the set for the given object, and return the index
        of its first occurrence. If the object isn't found, the method will return -1.

        @param elementToLookFor   the value or object to look for
        @returns                  the index of the object, or -1 if it's not found
    */
    int indexOf (const ElementType elementToLookFor) const throw()
    {
        lock.enter();

        int start = 0;
        int end = numUsed;

        for (;;)
        {
            if (start >= end)
            {
                lock.exit();
                return -1;
            }
            else if (elementToLookFor == this->elements [start])
            {
                lock.exit();
                return start;
            }
            else
            {
                const int halfway = (start + end) >> 1;

                if (halfway == start)
                {
                    lock.exit();
                    return -1;
                }
                else if (elementToLookFor >= this->elements [halfway])
                    start = halfway;
                else
                    end = halfway;
            }
        }
    }

    /** Returns true if the set contains at least one occurrence of an object.

        @param elementToLookFor     the value or object to look for
        @returns                    true if the item is found
    */
    bool contains (const ElementType elementToLookFor) const throw()
    {
        lock.enter();

        int start = 0;
        int end = numUsed;

        for (;;)
        {
            if (start >= end)
            {
                lock.exit();
                return false;
            }
            else if (elementToLookFor == this->elements [start])
            {
                lock.exit();
                return true;
            }
            else
            {
                const int halfway = (start + end) >> 1;

                if (halfway == start)
                {
                    lock.exit();
                    return false;
                }
                else if (elementToLookFor >= this->elements [halfway])
                    start = halfway;
                else
                    end = halfway;
            }
        }
    }

    /** Adds a new element to the set, (as long as it's not already in there).

        @param newElement       the new object to add to the set
        @see set, insert, addIfNotAlreadyThere, addSorted, addSet, addArray
    */
    void add (const ElementType newElement) throw()
    {
        lock.enter();

        int start = 0;
        int end = numUsed;

        for (;;)
        {
            if (start >= end)
            {
                jassert (start <= end);
                insertInternal (start, newElement);
                break;
            }
            else if (newElement == this->elements [start])
            {
                break;
            }
            else
            {
                const int halfway = (start + end) >> 1;

                if (halfway == start)
                {
                    if (newElement >= this->elements [halfway])
                        insertInternal (start + 1, newElement);
                    else
                        insertInternal (start, newElement);

                    break;
                }
                else if (newElement >= this->elements [halfway])
                    start = halfway;
                else
                    end = halfway;
            }
        }

        lock.exit();
    }

    /** Adds elements from an array to this set.

        @param elementsToAdd        the array of elements to add
        @param numElementsToAdd     how many elements are in this other array
        @see add
    */
    void addArray (const ElementType* elementsToAdd,
                   int numElementsToAdd) throw()
    {
        lock.enter();

        while (--numElementsToAdd >= 0)
            add (*elementsToAdd++);

        lock.exit();
    }

    /** Adds elements from another set to this one.

        @param setToAddFrom         the set from which to copy the elements
        @param startIndex           the first element of the other set to start copying from
        @param numElementsToAdd     how many elements to add from the other set. If this
                                    value is negative or greater than the number of available elements,
                                    all available elements will be copied.
        @see add
    */
    template <class OtherSetType>
    void addSet (const OtherSetType& setToAddFrom,
                 int startIndex = 0,
                 int numElementsToAdd = -1) throw()
    {
        setToAddFrom.lockSet();
        lock.enter();
        jassert (this != &setToAddFrom);

        if (this != &setToAddFrom)
        {
            if (startIndex < 0)
            {
                jassertfalse
                startIndex = 0;
            }

            if (numElementsToAdd < 0 || startIndex + numElementsToAdd > setToAddFrom.size())
                numElementsToAdd = setToAddFrom.size() - startIndex;

            addArray (setToAddFrom.elements + startIndex, numElementsToAdd);
        }

        lock.exit();
        setToAddFrom.unlockSet();
    }

    /** Removes an element from the set.

        This will remove the element at a given index.
        If the index passed in is out-of-range, nothing will happen.

        @param indexToRemove    the index of the element to remove
        @returns                the element that has been removed
        @see removeValue, removeRange
    */
    ElementType remove (const int indexToRemove) throw()
    {
        lock.enter();

        if (((unsigned int) indexToRemove) < (unsigned int) numUsed)
        {
            --numUsed;

            ElementType* const e = this->elements + indexToRemove;
            ElementType const removed = *e;
            const int numberToShift = numUsed - indexToRemove;

            if (numberToShift > 0)
                memmove (e, e + 1, numberToShift * sizeof (ElementType));

            if ((numUsed << 1) < this->numAllocated)
                minimiseStorageOverheads();

            lock.exit();
            return removed;
        }
        else
        {
            lock.exit();
            return 0;
        }
    }

    /** Removes an item from the set.

        This will remove the given element from the set, if it's there.

        @param valueToRemove   the object to try to remove
        @see remove, removeRange
    */
    void removeValue (const ElementType valueToRemove) throw()
    {
        lock.enter();
        remove (indexOf (valueToRemove));
        lock.exit();
    }

    /** Removes any elements which are also in another set.

        @param otherSet   the other set in which to look for elements to remove
        @see removeValuesNotIn, remove, removeValue, removeRange
    */
    template <class OtherSetType>
    void removeValuesIn (const OtherSetType& otherSet) throw()
    {
        otherSet.lockSet();
        lock.enter();

        if (this == &otherSet)
        {
            clear();
        }
        else
        {
            if (otherSet.size() > 0)
            {
                for (int i = numUsed; --i >= 0;)
                    if (otherSet.contains (this->elements [i]))
                        remove (i);
            }
        }

        lock.exit();
        otherSet.unlockSet();
    }

    /** Removes any elements which are not found in another set.

        Only elements which occur in this other set will be retained.

        @param otherSet    the set in which to look for elements NOT to remove
        @see removeValuesIn, remove, removeValue, removeRange
    */
    template <class OtherSetType>
    void removeValuesNotIn (const OtherSetType& otherSet) throw()
    {
        otherSet.lockSet();
        lock.enter();

        if (this != &otherSet)
        {
            if (otherSet.size() <= 0)
            {
                clear();
            }
            else
            {
                for (int i = numUsed; --i >= 0;)
                    if (! otherSet.contains (this->elements [i]))
                        remove (i);
            }
        }

        lock.exit();
        otherSet.lockSet();
    }

    /** Reduces the amount of storage being used by the set.

        Sets typically allocate slightly more storage than they need, and after
        removing elements, they may have quite a lot of unused space allocated.
        This method will reduce the amount of allocated storage to a minimum.
    */
    void minimiseStorageOverheads() throw()
    {
        lock.enter();

        if (numUsed == 0)
        {
            this->setAllocatedSize (0);
        }
        else
        {
            const int newAllocation = this->granularity * (numUsed / this->granularity + 1);

            if (newAllocation < this->numAllocated)
                this->setAllocatedSize (newAllocation);
        }

        lock.exit();
    }

    /** Locks the set's CriticalSection.

        Of course if the type of section used is a DummyCriticalSection, this won't
        have any effect.

        @see unlockSet
    */
    void lockSet() const throw()
    {
        lock.enter();
    }

    /** Unlocks the set's CriticalSection.

        Of course if the type of section used is a DummyCriticalSection, this won't
        have any effect.

        @see lockSet
    */
    void unlockSet() const throw()
    {
        lock.exit();
    }

    juce_UseDebuggingNewOperator

private:
    int numUsed;
    TypeOfCriticalSectionToUse lock;

    void insertInternal (const int indexToInsertAt, const ElementType newElement) throw()
    {
        this->ensureAllocatedSize (numUsed + 1);

        ElementType* const insertPos = this->elements + indexToInsertAt;
        const int numberToMove = numUsed - indexToInsertAt;

        if (numberToMove > 0)
            memmove (insertPos + 1, insertPos, numberToMove * sizeof (ElementType));

        *insertPos = newElement;
        ++numUsed;
    }
};

#if JUCE_MSVC
  #pragma warning (pop)
#endif

#endif   // __JUCE_SORTEDSET_JUCEHEADER__
/********* End of inlined file: juce_SortedSet.h *********/

#endif
#ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__

/********* Start of inlined file: juce_ReferenceCountedArray.h *********/
#ifndef __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__
#define __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__

/**
    Holds a list of objects derived from ReferenceCountedObject.

    A ReferenceCountedArray holds objects derived from ReferenceCountedObject,
    and takes care of incrementing and decrementing their ref counts when they
    are added and removed from the array.

    To make all the array's methods thread-safe, pass in "CriticalSection" as the templated
    TypeOfCriticalSectionToUse parameter, instead of the default DummyCriticalSection.

    @see Array, OwnedArray, StringArray
*/
template <class ObjectClass, class TypeOfCriticalSectionToUse = DummyCriticalSection>
class ReferenceCountedArray   : private ArrayAllocationBase <ObjectClass*>
{
public:

    /** Creates an empty array.

        @param granularity  this is the size of increment by which the internal storage
        used by the array will grow. Only change it from the default if you know the
        array is going to be very big and needs to be able to grow efficiently.

        @see ReferenceCountedObject, ArrayAllocationBase, Array, OwnedArray
    */
    ReferenceCountedArray (const int granularity = juceDefaultArrayGranularity) throw()
        : ArrayAllocationBase <ObjectClass*> (granularity),
          numUsed (0)
    {
    }

    /** Creates a copy of another array */
    ReferenceCountedArray (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) throw()
        : ArrayAllocationBase <ObjectClass*> (other.granularity),
          numUsed (other.numUsed)
    {
        other.lockArray();
        this->setAllocatedSize (numUsed);
        memcpy (this->elements, other.elements, numUsed * sizeof (ObjectClass*));

        for (int i = numUsed; --i >= 0;)
            if (this->elements[i] != 0)
                this->elements[i]->incReferenceCount();

        other.unlockArray();
    }

    /** Copies another array into this one.

        Any existing objects in this array will first be released.
    */
    const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& operator= (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) throw()
    {
        if (this != &other)
        {
            other.lockArray();
            lock.enter();

            clear();

            this->granularity = other.granularity;
            this->ensureAllocatedSize (other.numUsed);
            numUsed = other.numUsed;
            memcpy (this->elements, other.elements, numUsed * sizeof (ObjectClass*));
            minimiseStorageOverheads();

            for (int i = numUsed; --i >= 0;)
                if (this->elements[i] != 0)
                    this->elements[i]->incReferenceCount();

            lock.exit();
            other.unlockArray();
        }

        return *this;
    }

    /** Destructor.

        Any objects in the array will be released, and may be deleted if not referenced from elsewhere.
    */
    ~ReferenceCountedArray()
    {
        clear();
    }

    /** Removes all objects from the array.

        Any objects in the array that are not referenced from elsewhere will be deleted.
    */
    void clear()
    {
        lock.enter();

        while (numUsed > 0)
            if (this->elements [--numUsed] != 0)
                this->elements [numUsed]->decReferenceCount();

        jassert (numUsed == 0);
        this->setAllocatedSize (0);

        lock.exit();
    }

    /** Returns the current number of objects in the array. */
    inline int size() const throw()
    {
        return numUsed;
    }

    /** Returns a pointer to the object at this index in the array.

        If the index is out-of-range, this will return a null pointer, (and
        it could be null anyway, because it's ok for the array to hold null
        pointers as well as objects).

        @see getUnchecked
    */
    inline const ReferenceCountedObjectPtr<ObjectClass> operator[] (const int index) const throw()
    {
        lock.enter();
        const ReferenceCountedObjectPtr<ObjectClass> result ((((unsigned int) index) < (unsigned int) numUsed)
                                                                ? this->elements [index]
                                                                : (ObjectClass*) 0);
        lock.exit();
        return result;
    }

    /** Returns a pointer to the object at this index in the array, without checking whether the index is in-range.

        This is a faster and less safe version of operator[] which doesn't check the index passed in, so
        it can be used when you're sure the index if always going to be legal.
    */
    inline const ReferenceCountedObjectPtr<ObjectClass> getUnchecked (const int index) const throw()
    {
        lock.enter();
        jassert (((unsigned int) index) < (unsigned int) numUsed);
        const ReferenceCountedObjectPtr<ObjectClass> result (this->elements [index]);
        lock.exit();
        return result;
    }

    /** Returns a pointer to the first object in the array.

        This will return a null pointer if the array's empty.
        @see getLast
    */
    inline const ReferenceCountedObjectPtr<ObjectClass> getFirst() const throw()
    {
        lock.enter();
        const ReferenceCountedObjectPtr<ObjectClass> result ((numUsed > 0) ? this->elements [0]
                                                                           : (ObjectClass*) 0);
        lock.exit();

        return result;
    }

    /** Returns a pointer to the last object in the array.

        This will return a null pointer if the array's empty.
        @see getFirst
    */
    inline const ReferenceCountedObjectPtr<ObjectClass> getLast() const throw()
    {
        lock.enter();
        const ReferenceCountedObjectPtr<ObjectClass> result ((numUsed > 0) ? this->elements [numUsed - 1]
                                                                           : (ObjectClass*) 0);
        lock.exit();

        return result;
    }

    /** Finds the index of the first occurrence of an object in the array.

        @param objectToLookFor    the object to look for
        @returns                  the index at which the object was found, or -1 if it's not found
    */
    int indexOf (const ObjectClass* const objectToLookFor) const throw()
    {
        int result = -1;

        lock.enter();
        ObjectClass** e = this->elements;

        for (int i = numUsed; --i >= 0;)
        {
            if (objectToLookFor == *e)
            {
                result = (int) (e - this->elements);
                break;
            }

            ++e;
        }

        lock.exit();
        return result;
    }

    /** Returns true if the array contains a specified object.

        @param objectToLookFor      the object to look for
        @returns                    true if the object is in the array
    */
    bool contains (const ObjectClass* const objectToLookFor) const throw()
    {
        lock.enter();
        ObjectClass** e = this->elements;

        for (int i = numUsed; --i >= 0;)
        {
            if (objectToLookFor == *e)
            {
                lock.exit();
                return true;
            }

            ++e;
        }

        lock.exit();
        return false;
    }

    /** Appends a new object to the end of the array.

        This will increase the new object's reference count.

        @param newObject       the new object to add to the array
        @see set, insert, addIfNotAlreadyThere, addSorted, addArray
    */
    void add (ObjectClass* const newObject) throw()
    {
        lock.enter();
        this->ensureAllocatedSize (numUsed + 1);
        this->elements [numUsed++] = newObject;

        if (newObject != 0)
            newObject->incReferenceCount();

        lock.exit();
    }

    /** Inserts a new object into the array at the given index.

        If the index is less than 0 or greater than the size of the array, the
        element will be added to the end of the array.
        Otherwise, it will be inserted into the array, moving all the later elements
        along to make room.

        This will increase the new object's reference count.

        @param indexToInsertAt      the index at which the new element should be inserted
        @param newObject            the new object to add to the array
        @see add, addSorted, addIfNotAlreadyThere, set
    */
    void insert (int indexToInsertAt,
                 ObjectClass* const newObject) throw()
    {
        if (indexToInsertAt >= 0)
        {
            lock.enter();

            if (indexToInsertAt > numUsed)
                indexToInsertAt = numUsed;

            this->ensureAllocatedSize (numUsed + 1);

            ObjectClass** const e = this->elements + indexToInsertAt;
            const int numToMove = numUsed - indexToInsertAt;

            if (numToMove > 0)
                memmove (e + 1, e, numToMove * sizeof (ObjectClass*));

            *e = newObject;

            if (newObject != 0)
                newObject->incReferenceCount();

            ++numUsed;
            lock.exit();
        }
        else
        {
            add (newObject);
        }
    }

    /** Appends a new object at the end of the array as long as the array doesn't
        already contain it.

        If the array already contains a matching object, nothing will be done.

        @param newObject   the new object to add to the array
    */
    void addIfNotAlreadyThere (ObjectClass* const newObject) throw()
    {
        lock.enter();

        if (! contains (newObject))
            add (newObject);

        lock.exit();
    }

    /** Replaces an object in the array with a different one.

        If the index is less than zero, this method does nothing.
        If the index is beyond the end of the array, the new object is added to the end of the array.

        The object being added has its reference count increased, and if it's replacing
        another object, then that one has its reference count decreased, and may be deleted.

        @param indexToChange        the index whose value you want to change
        @param newObject            the new value to set for this index.
        @see add, insert, remove
    */
    void set (const int indexToChange,
              ObjectClass* const newObject)
    {
        if (indexToChange >= 0)
        {
            lock.enter();

            if (newObject != 0)
                newObject->incReferenceCount();

            if (indexToChange < numUsed)
            {
                if (this->elements [indexToChange] != 0)
                    this->elements [indexToChange]->decReferenceCount();

                this->elements [indexToChange] = newObject;
            }
            else
            {
                this->ensureAllocatedSize (numUsed + 1);
                this->elements [numUsed++] = newObject;
            }

            lock.exit();
        }
    }

    /** Adds elements from another array to the end of this array.

        @param arrayToAddFrom       the array from which to copy the elements
        @param startIndex           the first element of the other array to start copying from
        @param numElementsToAdd     how many elements to add from the other array. If this
                                    value is negative or greater than the number of available elements,
                                    all available elements will be copied.
        @see add
    */
    void addArray (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& arrayToAddFrom,
                   int startIndex = 0,
                   int numElementsToAdd = -1) throw()
    {
        arrayToAddFrom.lockArray();
        lock.enter();

        if (startIndex < 0)
        {
            jassertfalse
            startIndex = 0;
        }

        if (numElementsToAdd < 0 || startIndex + numElementsToAdd > arrayToAddFrom.size())
            numElementsToAdd = arrayToAddFrom.size() - startIndex;

        if (numElementsToAdd > 0)
        {
            this->ensureAllocatedSize (numUsed + numElementsToAdd);

            while (--numElementsToAdd >= 0)
                add (arrayToAddFrom.getUnchecked (startIndex++));
        }

        lock.exit();
        arrayToAddFrom.unlockArray();
    }

    /** Inserts a new object into the array assuming that the array is sorted.

        This will use a comparator to find the position at which the new object
        should go. If the array isn't sorted, the behaviour of this
        method will be unpredictable.

        @param comparator       the comparator object to use to compare the elements - see the
                                sort() method for details about this object's form
        @param newObject        the new object to insert to the array
        @see add, sort
    */
    template <class ElementComparator>
    void addSorted (ElementComparator& comparator,
                    ObjectClass* newObject) throw()
    {
        lock.enter();
        insert (findInsertIndexInSortedArray (comparator, this->elements, newObject, 0, numUsed), newObject);
        lock.exit();
    }

    /** Inserts or replaces an object in the array, assuming it is sorted.

        This is similar to addSorted, but if a matching element already exists, then it will be
        replaced by the new one, rather than the new one being added as well.
    */
    template <class ElementComparator>
    void addOrReplaceSorted (ElementComparator& comparator,
                             ObjectClass* newObject) throw()
    {
        lock.enter();
        const int index = findInsertIndexInSortedArray (comparator, this->elements, newObject, 0, numUsed);

        if (index > 0 && comparator.compareElements (newObject, this->elements [index - 1]) == 0)
            set (index - 1, newObject); // replace an existing object that matches
        else
            insert (index, newObject);  // no match, so insert the new one

        lock.exit();
    }

    /** Removes an object from the array.

        This will remove the object at a given index and move back all the
        subsequent objects to close the gap.

        If the index passed in is out-of-range, nothing will happen.

        The object that is removed will have its reference count decreased,
        and may be deleted if not referenced from elsewhere.

        @param indexToRemove    the index of the element to remove
        @see removeObject, removeRange
    */
    void remove (const int indexToRemove)
    {
        lock.enter();

        if (((unsigned int) indexToRemove) < (unsigned int) numUsed)
        {
            ObjectClass** const e = this->elements + indexToRemove;

            if (*e != 0)
                (*e)->decReferenceCount();

            --numUsed;
            const int numberToShift = numUsed - indexToRemove;

            if (numberToShift > 0)
                memmove (e, e + 1, numberToShift * sizeof (ObjectClass*));

            if ((numUsed << 1) < this->numAllocated)
                minimiseStorageOverheads();
        }

        lock.exit();
    }

    /** Removes the first occurrence of a specified object from the array.

        If the item isn't found, no action is taken. If it is found, it is
        removed and has its reference count decreased.

        @param objectToRemove   the object to try to remove
        @see remove, removeRange
    */
    void removeObject (ObjectClass* const objectToRemove)
    {
        lock.enter();
        remove (indexOf (objectToRemove));
        lock.exit();
    }

    /** Removes a range of objects from the array.

        This will remove a set of objects, starting from the given index,
        and move any subsequent elements down to close the gap.

        If the range extends beyond the bounds of the array, it will
        be safely clipped to the size of the array.

        The objects that are removed will have their reference counts decreased,
        and may be deleted if not referenced from elsewhere.

        @param startIndex       the index of the first object to remove
        @param numberToRemove   how many objects should be removed
        @see remove, removeObject
    */
    void removeRange (const int startIndex,
                      const int numberToRemove)
    {
        lock.enter();

        const int start = jlimit (0, numUsed, startIndex);
        const int end   = jlimit (0, numUsed, startIndex + numberToRemove);

        if (end > start)
        {
            int i;
            for (i = start; i < end; ++i)
            {
                if (this->elements[i] != 0)
                {
                    this->elements[i]->decReferenceCount();
                    this->elements[i] = 0; // (in case one of the destructors accesses this array and hits a dangling pointer)
                }
            }

            const int rangeSize = end - start;
            ObjectClass** e = this->elements + start;
            i = numUsed - end;
            numUsed -= rangeSize;

            while (--i >= 0)
            {
                *e = e [rangeSize];
                ++e;
            }

            if ((numUsed << 1) < this->numAllocated)
                minimiseStorageOverheads();
        }

        lock.exit();
    }

    /** Removes the last n objects from the array.

        The objects that are removed will have their reference counts decreased,
        and may be deleted if not referenced from elsewhere.

        @param howManyToRemove   how many objects to remove from the end of the array
        @see remove, removeObject, removeRange
    */
    void removeLast (int howManyToRemove = 1)
    {
        lock.enter();

        if (howManyToRemove > numUsed)
            howManyToRemove = numUsed;

        while (--howManyToRemove >= 0)
            remove (numUsed - 1);

        lock.exit();
    }

    /** Swaps a pair of objects in the array.

        If either of the indexes passed in is out-of-range, nothing will happen,
        otherwise the two objects at these positions will be exchanged.
    */
    void swap (const int index1,
               const int index2) throw()
    {
        lock.enter();

        if (((unsigned int) index1) < (unsigned int) numUsed
             && ((unsigned int) index2) < (unsigned int) numUsed)
        {
            swapVariables (this->elements [index1],
                           this->elements [index2]);
        }

        lock.exit();
    }

    /** Moves one of the objects to a different position.

        This will move the object to a specified index, shuffling along
        any intervening elements as required.

        So for example, if you have the array { 0, 1, 2, 3, 4, 5 } then calling
        move (2, 4) would result in { 0, 1, 3, 4, 2, 5 }.

        @param currentIndex     the index of the object to be moved. If this isn't a
                                valid index, then nothing will be done
        @param newIndex         the index at which you'd like this object to end up. If this
                                is less than zero, it will be moved to the end of the array
    */
    void move (const int currentIndex,
               int newIndex) throw()
    {
        if (currentIndex != newIndex)
        {
            lock.enter();

            if (((unsigned int) currentIndex) < (unsigned int) numUsed)
            {
                if (((unsigned int) newIndex) >= (unsigned int) numUsed)
                    newIndex = numUsed - 1;

                ObjectClass* const value = this->elements [currentIndex];

                if (newIndex > currentIndex)
                {
                    memmove (this->elements + currentIndex,
                             this->elements + currentIndex + 1,
                             (newIndex - currentIndex) * sizeof (ObjectClass*));
                }
                else
                {
                    memmove (this->elements + newIndex + 1,
                             this->elements + newIndex,
                             (currentIndex - newIndex) * sizeof (ObjectClass*));
                }

                this->elements [newIndex] = value;
            }

            lock.exit();
        }
    }

    /** Compares this array to another one.

        @returns true only if the other array contains the same objects in the same order
    */
    bool operator== (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const throw()
    {
        other.lockArray();
        lock.enter();

        bool result = numUsed == other.numUsed;

        if (result)
        {
            for (int i = numUsed; --i >= 0;)
            {
                if (this->elements [i] != other.elements [i])
                {
                    result = false;
                    break;
                }
            }
        }

        lock.exit();
        other.unlockArray();

        return result;
    }

    /** Compares this array to another one.

        @see operator==
    */
    bool operator!= (const ReferenceCountedArray<ObjectClass, TypeOfCriticalSectionToUse>& other) const throw()
    {
        return ! operator== (other);
    }

    /** Sorts the elements in the array.

        This will use a comparator object to sort the elements into order. The object
        passed must have a method of the form:
        @code
        int compareElements (ElementType first, ElementType second);
        @endcode

        ..and this method must return:
          - a value of < 0 if the first comes before the second
          - a value of 0 if the two objects are equivalent
          - a value of > 0 if the second comes before the first

        To improve performance, the compareElements() method can be declared as static or const.

        @param comparator   the comparator to use for comparing elements.
        @param retainOrderOfEquivalentItems     if this is true, then items
                            which the comparator says are equivalent will be
                            kept in the order in which they currently appear
                            in the array. This is slower to perform, but may
                            be important in some cases. If it's false, a faster
                            algorithm is used, but equivalent elements may be
                            rearranged.

        @see sortArray
    */
    template <class ElementComparator>
    void sort (ElementComparator& comparator,
               const bool retainOrderOfEquivalentItems = false) const throw()
    {
        (void) comparator;  // if you pass in an object with a static compareElements() method, this
                            // avoids getting warning messages about the parameter being unused

        lock.enter();
        sortArray (comparator, this->elements, 0, size() - 1, retainOrderOfEquivalentItems);
        lock.exit();
    }

    /** Reduces the amount of storage being used by the array.

        Arrays typically allocate slightly more storage than they need, and after
        removing elements, they may have quite a lot of unused space allocated.
        This method will reduce the amount of allocated storage to a minimum.
    */
    void minimiseStorageOverheads() throw()
    {
        lock.enter();

        if (numUsed == 0)
        {
            this->setAllocatedSize (0);
        }
        else
        {
            const int newAllocation = this->granularity * (numUsed / this->granularity + 1);

            if (newAllocation < this->numAllocated)
                this->setAllocatedSize (newAllocation);
        }

        lock.exit();
    }

    /** Locks the array's CriticalSection.

        Of course if the type of section used is a DummyCriticalSection, this won't
        have any effect.

        @see unlockArray
    */
    void lockArray() const throw()
    {
        lock.enter();
    }

    /** Unlocks the array's CriticalSection.

        Of course if the type of section used is a DummyCriticalSection, this won't
        have any effect.

        @see lockArray
    */
    void unlockArray() const throw()
    {
        lock.exit();
    }

    juce_UseDebuggingNewOperator

private:
    int numUsed;
    TypeOfCriticalSectionToUse lock;
};

#endif   // __JUCE_REFERENCECOUNTEDARRAY_JUCEHEADER__
/********* End of inlined file: juce_ReferenceCountedArray.h *********/

#endif
#ifndef __JUCE_OWNEDARRAY_JUCEHEADER__

#endif
#ifndef __JUCE_VARIANT_JUCEHEADER__

/********* Start of inlined file: juce_Variant.h *********/
#ifndef __JUCE_VARIANT_JUCEHEADER__
#define __JUCE_VARIANT_JUCEHEADER__

class JUCE_API  DynamicObject;

/**
    A variant class, that can be used to hold a range of primitive values.

    A var object can hold a range of simple primitive values, strings, or
    a reference-counted pointer to a DynamicObject. The var class is intended
    to act like the values used in dynamic scripting languages.

    @see DynamicObject
*/
class JUCE_API  var
{
public:

    typedef const var (DynamicObject::*MethodFunction) (const var* arguments, int numArguments);

    /** Creates a void variant. */
    var() throw();

    /** Destructor. */
    ~var();

    var (const var& valueToCopy) throw();
    var (const int value) throw();
    var (const bool value) throw();
    var (const double value) throw();
    var (const char* const value) throw();
    var (const juce_wchar* const value) throw();
    var (const String& value) throw();
    var (DynamicObject* const object) throw();
    var (MethodFunction method) throw();

    const var& operator= (const var& valueToCopy) throw();
    const var& operator= (const int value) throw();
    const var& operator= (const bool value) throw();
    const var& operator= (const double value) throw();
    const var& operator= (const char* const value) throw();
    const var& operator= (const juce_wchar* const value) throw();
    const var& operator= (const String& value) throw();
    const var& operator= (DynamicObject* const object) throw();
    const var& operator= (MethodFunction method) throw();

    operator int() const throw();
    operator bool() const throw();
    operator double() const throw();
    operator const String() const throw();
    const String toString() const throw();
    DynamicObject* getObject() const throw();

    bool isVoid() const throw()         { return type == voidType; }
    bool isInt() const throw()          { return type == intType; }
    bool isBool() const throw()         { return type == boolType; }
    bool isDouble() const throw()       { return type == doubleType; }
    bool isString() const throw()       { return type == stringType; }
    bool isObject() const throw()       { return type == objectType; }
    bool isMethod() const throw()       { return type == methodType; }

    class JUCE_API  identifier
    {
    public:
        identifier (const char* const name) throw();
        identifier (const String& name) throw();
        ~identifier() throw();

        bool operator== (const identifier& other) const throw()   { return hashCode == other.hashCode; }

        String name;
        int hashCode;
    };

    /** If this variant is an object, this returns one of its properties. */
    const var operator[] (const identifier& propertyName) const throw();

    /** If this variant is an object, this invokes one of its methods with no arguments. */
    const var call (const identifier& method) const;
    /** If this variant is an object, this invokes one of its methods with one argument. */
    const var call (const identifier& method, const var& arg1) const;
    /** If this variant is an object, this invokes one of its methods with 2 arguments. */
    const var call (const identifier& method, const var& arg1, const var& arg2) const;
    /** If this variant is an object, this invokes one of its methods with 3 arguments. */
    const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3);
    /** If this variant is an object, this invokes one of its methods with 4 arguments. */
    const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4) const;
    /** If this variant is an object, this invokes one of its methods with 5 arguments. */
    const var call (const identifier& method, const var& arg1, const var& arg2, const var& arg3, const var& arg4, const var& arg5) const;

    /** If this variant is an object, this invokes one of its methods with a list of arguments. */
    const var invoke (const identifier& method, const var* arguments, int numArguments) const;

    /** If this variant is a method pointer, this invokes it on a target object. */
    const var invoke (const var& targetObject, const var* arguments, int numArguments) const;

    juce_UseDebuggingNewOperator

private:
    enum Type
    {
        voidType = 0,
        intType,
        boolType,
        doubleType,
        stringType,
        objectType,
        methodType
    };

    Type type;

    union
    {
        int intValue;
        bool boolValue;
        double doubleValue;
        String* stringValue;
        DynamicObject* objectValue;
        MethodFunction methodValue;
    } value;

    void releaseValue() throw();
};

/**
    Represents a dynamically implemented object.

    An instance of this class can be used to store named properties, and
    by subclassing hasMethod() and invokeMethod(), you can give your object
    methods.

    This is intended for use as a wrapper for scripting language objects.
*/
class JUCE_API  DynamicObject  : public ReferenceCountedObject
{
public:

    DynamicObject();

    /** Destructor. */
    virtual ~DynamicObject();

    /** Returns true if the object has a property with this name.
        Note that if the property is actually a method, this will return false.
    */
    virtual bool hasProperty (const var::identifier& propertyName) const;

    /** Returns a named property.

        This returns a void if no such property exists.
    */
    virtual const var getProperty (const var::identifier& propertyName) const;

    /** Sets a named property. */
    virtual void setProperty (const var::identifier& propertyName, const var& newValue);

    /** Removes a named property. */
    virtual void removeProperty (const var::identifier& propertyName);

    /** Checks whether this object has the specified method.

        The default implementation of this just checks whether there's a property
        with this name that's actually a method, but this can be overridden for
        building objects with dynamic invocation.
    */
    virtual bool hasMethod (const var::identifier& methodName) const;

    /** Invokes a named method on this object.

        The default implementation looks up the named property, and if it's a method
        call, then it invokes it.

        This method is virtual to allow more dynamic invocation to used for objects
        where the methods may not already be set as properies.
    */
    virtual const var invokeMethod (const var::identifier& methodName,
                                    const var* parameters,
                                    int numParameters);

    /** Sets up a method.

        This is basically the same as calling setProperty (methodName, (var::MethodFunction) myFunction), but
        helps to avoid accidentally invoking the wrong type of var constructor. It also makes
        the code easier to read,

        The compiler will probably force you to use an explicit cast your method to a (var::MethodFunction), e.g.
        @code
        setMethod ("doSomething", (var::MethodFunction) &MyClass::doSomething);
        @endcode
    */
    void setMethod (const var::identifier& methodName,
                    var::MethodFunction methodFunction);

    juce_UseDebuggingNewOperator

private:
    Array <int> propertyIds;
    OwnedArray <var> propertyValues;
};

#endif   // __JUCE_VARIANT_JUCEHEADER__
/********* End of inlined file: juce_Variant.h *********/

#endif
#ifndef __JUCE_INPUTSTREAM_JUCEHEADER__

#endif
#ifndef __JUCE_OUTPUTSTREAM_JUCEHEADER__

#endif
#ifndef __JUCE_DIRECTORYITERATOR_JUCEHEADER__

/********* Start of inlined file: juce_DirectoryIterator.h *********/
#ifndef __JUCE_DIRECTORYITERATOR_JUCEHEADER__
#define __JUCE_DIRECTORYITERATOR_JUCEHEADER__

/**
    Searches through a the files in a directory, returning each file that is found.

    A DirectoryIterator will search through a directory and its subdirectories using
    a wildcard filepattern match.

    If you may be finding a large number of files, this is better than
    using File::findChildFiles() because it doesn't block while it finds them
    all, and this is more memory-efficient.

    It can also guess how far it's got using a wildly inaccurate algorithm.
*/
class JUCE_API  DirectoryIterator
{
public:

    /** Creates a DirectoryIterator for a given directory.

        After creating one of these, call its next() method to get the
        first file - e.g. @code

        DirectoryIterator iter (File ("/animals/mooses"), true, "*.moose");

        while (iter.next())
        {
            File theFileItFound (iter.getFile());

            ... etc
        }
        @endcode

        @param directory    the directory to search in
        @param isRecursive  whether all the subdirectories should also be searched
        @param wildCard     the file pattern to match
        @param whatToLookFor    a value from the File::TypesOfFileToFind enum, specifying
                                whether to look for files, directories, or both.
    */
    DirectoryIterator (const File& directory,
                       bool isRecursive,
                       const String& wildCard = JUCE_T("*"),
                       const int whatToLookFor = File::findFiles) throw();

    /** Destructor. */
    ~DirectoryIterator() throw();

    /** Call this to move the iterator along to the next file.

        @returns    true if a file was found (you can then use getFile() to see what it was) - or
                    false if there are no more matching files.
    */
    bool next() throw();

    /** Returns the file that the iterator is currently pointing at.

        The result of this call is only valid after a call to next() has returned true.
    */
    const File getFile() const throw();

    /** Returns a guess of how far through the search the iterator has got.

        @returns    a value 0.0 to 1.0 to show the progress, although this won't be
                    very accurate.
    */
    float getEstimatedProgress() const throw();

    juce_UseDebuggingNewOperator

private:
    OwnedArray <File> filesFound;
    OwnedArray <File> dirsFound;
    String wildCard;
    int index;
    const int whatToLookFor;
    DirectoryIterator* subIterator;

    DirectoryIterator (const DirectoryIterator&);
    const DirectoryIterator& operator= (const DirectoryIterator&);
};

#endif   // __JUCE_DIRECTORYITERATOR_JUCEHEADER__
/********* End of inlined file: juce_DirectoryIterator.h *********/

#endif
#ifndef __JUCE_FILE_JUCEHEADER__

#endif
#ifndef __JUCE_FILEINPUTSTREAM_JUCEHEADER__

/********* Start of inlined file: juce_FileInputStream.h *********/
#ifndef __JUCE_FILEINPUTSTREAM_JUCEHEADER__
#define __JUCE_FILEINPUTSTREAM_JUCEHEADER__

/**
    An input stream that reads from a local file.

    @see InputStream, FileOutputStream, File::createInputStream
*/
class JUCE_API  FileInputStream  : public InputStream
{
public:

    /** Creates a FileInputStream.

        @param fileToRead   the file to read from - if the file can't be accessed for some
                            reason, then the stream will just contain no data
    */
    FileInputStream (const File& fileToRead);

    /** Destructor. */
    ~FileInputStream();

    const File& getFile() const throw()                     { return file; }

    int64 getTotalLength();
    int read (void* destBuffer, int maxBytesToRead);
    bool isExhausted();
    int64 getPosition();
    bool setPosition (int64 pos);

    juce_UseDebuggingNewOperator

private:
    File file;
    void* fileHandle;
    int64 currentPosition, totalSize;
    bool needToSeek;
};

#endif   // __JUCE_FILEINPUTSTREAM_JUCEHEADER__
/********* End of inlined file: juce_FileInputStream.h *********/

#endif
#ifndef __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__

/********* Start of inlined file: juce_FileOutputStream.h *********/
#ifndef __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__
#define __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__

/**
    An output stream that writes into a local file.

    @see OutputStream, FileInputStream, File::createOutputStream
*/
class JUCE_API  FileOutputStream  : public OutputStream
{
public:

    /** Creates a FileOutputStream.

        If the file doesn't exist, it will first be created. If the file can't be
        created or opened, the failedToOpen() method will return
        true.

        If the file already exists when opened, the stream's write-postion will
        be set to the end of the file. To overwrite an existing file,
        use File::deleteFile() before opening the stream, or use setPosition(0)
        after it's opened (although this won't truncate the file).

        It's better to use File::createOutputStream() to create one of these, rather
        than using the class directly.
    */
    FileOutputStream (const File& fileToWriteTo,
                      const int bufferSizeToUse = 16384);

    /** Destructor. */
    ~FileOutputStream();

    /** Returns the file that this stream is writing to.
    */
    const File& getFile() const throw()                 { return file; }

    /** Returns true if the stream couldn't be opened for some reason.
    */
    bool failedToOpen() const throw()                   { return fileHandle == 0; }

    void flush();
    int64 getPosition();
    bool setPosition (int64 pos);
    bool write (const void* data, int numBytes);

    juce_UseDebuggingNewOperator

private:
    File file;
    void* fileHandle;
    int64 currentPosition;
    int bufferSize, bytesInBuffer;
    char* buffer;
};

#endif   // __JUCE_FILEOUTPUTSTREAM_JUCEHEADER__
/********* End of inlined file: juce_FileOutputStream.h *********/

#endif
#ifndef __JUCE_FILESEARCHPATH_JUCEHEADER__

/********* Start of inlined file: juce_FileSearchPath.h *********/
#ifndef __JUCE_FILESEARCHPATH_JUCEHEADER__
#define __JUCE_FILESEARCHPATH_JUCEHEADER__

/**
    Encapsulates a set of folders that make up a search path.

    @see File
*/
class JUCE_API  FileSearchPath
{
public:

    /** Creates an empty search path. */
    FileSearchPath();

    /** Creates a search path from a string of pathnames.

        The path can be semicolon- or comma-separated, e.g.
        "/foo/bar;/foo/moose;/fish/moose"

        The separate folders are tokenised and added to the search path.
    */
    FileSearchPath (const String& path);

    /** Creates a copy of another search path. */
    FileSearchPath (const FileSearchPath& other);

    /** Destructor. */
    ~FileSearchPath();

    /** Uses a string containing a list of pathnames to re-initialise this list.

        This search path is cleared and the semicolon- or comma-separated folders
        in this string are added instead. e.g. "/foo/bar;/foo/moose;/fish/moose"
    */
    const FileSearchPath& operator= (const String& path);

    /** Returns the number of folders in this search path.

        @see operator[]
    */
    int getNumPaths() const;

    /** Returns one of the folders in this search path.

        The file returned isn't guaranteed to actually be a valid directory.

        @see getNumPaths
    */
    const File operator[] (const int index) const;

    /** Returns the search path as a semicolon-separated list of directories. */
    const String toString() const;

    /** Adds a new directory to the search path.

        The new directory is added to the end of the list if the insertIndex parameter is
        less than zero, otherwise it is inserted at the given index.
    */
    void add (const File& directoryToAdd,
              const int insertIndex = -1);

    /** Adds a new directory to the search path if it's not already in there. */
    void addIfNotAlreadyThere (const File& directoryToAdd);

    /** Removes a directory from the search path. */
    void remove (const int indexToRemove);

    /** Merges another search path into this one.

        This will remove any duplicate directories.
    */
    void addPath (const FileSearchPath& other);

    /** Removes any directories that are actually subdirectories of one of the other directories in the search path.

        If the search is intended to be recursive, there's no point having nested folders in the search
        path, because they'll just get searched twice and you'll get duplicate results.

        e.g. if the path is "c:\abc\de;c:\abc", this method will simplify it to "c:\abc"
    */
    void removeRedundantPaths();

    /** Removes any directories that don't actually exist. */
    void removeNonExistentPaths();

    /** Searches the path for a wildcard.

        This will search all the directories in the search path in order, adding any
        matching files to the results array.

        @param results                  an array to append the results to
        @param whatToLookFor            a value from the File::TypesOfFileToFind enum, specifying whether to
                                        return files, directories, or both.
        @param searchRecursively        whether to recursively search the subdirectories too
        @param wildCardPattern          a pattern to match against the filenames
        @returns the number of files added to the array
        @see File::findChildFiles
    */
    int findChildFiles (OwnedArray<File>& results,
                        const int whatToLookFor,
                        const bool searchRecursively,
                        const String& wildCardPattern = JUCE_T("*")) const;

    /** Finds out whether a file is inside one of the path's directories.

        This will return true if the specified file is a child of one of the
        directories specified by this path. Note that this doesn't actually do any
        searching or check that the files exist - it just looks at the pathnames
        to work out whether the file would be inside a directory.

        @param fileToCheck      the file to look for
        @param checkRecursively if true, then this will return true if the file is inside a
                                subfolder of one of the path's directories (at any depth). If false
                                it will only return true if the file is actually a direct child
                                of one of the directories.
        @see File::isAChildOf

    */
    bool isFileInPath (const File& fileToCheck,
                       const bool checkRecursively) const;

    juce_UseDebuggingNewOperator

private:
    StringArray directories;

    void init (const String& path);
};

#endif   // __JUCE_FILESEARCHPATH_JUCEHEADER__
/********* End of inlined file: juce_FileSearchPath.h *********/

#endif
#ifndef __JUCE_NAMEDPIPE_JUCEHEADER__

/********* Start of inlined file: juce_NamedPipe.h *********/
#ifndef __JUCE_NAMEDPIPE_JUCEHEADER__
#define __JUCE_NAMEDPIPE_JUCEHEADER__

/**
    A cross-process pipe that can have data written to and read from it.

    Two or more processes can use these for inter-process communication.

    @see InterprocessConnection
*/
class JUCE_API  NamedPipe
{
public:

    /** Creates a NamedPipe. */
    NamedPipe();

    /** Destructor. */
    ~NamedPipe();

    /** Tries to open a pipe that already exists.

        Returns true if it succeeds.
    */
    bool openExisting (const String& pipeName);

    /** Tries to create a new pipe.

        Returns true if it succeeds.
    */
    bool createNewPipe (const String& pipeName);

    /** Closes the pipe, if it's open. */
    void close();

    /** True if the pipe is currently open. */
    bool isOpen() const throw();

    /** Returns the last name that was used to try to open this pipe. */
    const String getName() const throw();

    /** Reads data from the pipe.

        This will block until another thread has written enough data into the pipe to fill
        the number of bytes specified, or until another thread calls the cancelPendingReads()
        method.

        If the operation fails, it returns -1, otherwise, it will return the number of
        bytes read.

        If timeOutMilliseconds is less than zero, it will wait indefinitely, otherwise
        this is a maximum timeout for reading from the pipe.
    */
    int read (void* destBuffer, int maxBytesToRead, int timeOutMilliseconds = 5000);

    /** Writes some data to the pipe.

        If the operation fails, it returns -1, otherwise, it will return the number of
        bytes written.
    */
    int write (const void* sourceBuffer, int numBytesToWrite,
               int timeOutMilliseconds = 2000);

    /** If any threads are currently blocked on a read operation, this tells them to abort.
    */
    void cancelPendingReads();

    juce_UseDebuggingNewOperator

private:
    void* internal;
    String currentPipeName;

    NamedPipe (const NamedPipe&);
    const NamedPipe& operator= (const NamedPipe&);

    bool openInternal (const String& pipeName, const bool createPipe);
};

#endif   // __JUCE_NAMEDPIPE_JUCEHEADER__
/********* End of inlined file: juce_NamedPipe.h *********/

#endif
#ifndef __JUCE_BLOWFISH_JUCEHEADER__

/********* Start of inlined file: juce_BlowFish.h *********/
#ifndef __JUCE_BLOWFISH_JUCEHEADER__
#define __JUCE_BLOWFISH_JUCEHEADER__

/**
    BlowFish encryption class.

*/
class JUCE_API  BlowFish
{
public:

    /** Creates an object that can encode/decode based on the specified key.

        The key data can be up to 72 bytes long.
    */
    BlowFish (const uint8* keyData, int keyBytes);

    /** Creates a copy of another blowfish object. */
    BlowFish (const BlowFish& other);

    /** Copies another blowfish object. */
    const BlowFish& operator= (const BlowFish& other);

    /** Destructor. */
    ~BlowFish();

    /** Encrypts a pair of 32-bit integers. */
    void encrypt (uint32& data1, uint32& data2) const;

    /** Decrypts a pair of 32-bit integers. */
    void decrypt (uint32& data1, uint32& data2) const;

    juce_UseDebuggingNewOperator

private:
    uint32 p[18];
    uint32* s[4];

    uint32 F (uint32 x) const;
};

#endif   // __JUCE_BLOWFISH_JUCEHEADER__
/********* End of inlined file: juce_BlowFish.h *********/

#endif
#ifndef __JUCE_MD5_JUCEHEADER__

/********* Start of inlined file: juce_MD5.h *********/
#ifndef __JUCE_MD5_JUCEHEADER__
#define __JUCE_MD5_JUCEHEADER__

/**
    MD5 checksum class.

    Create one of these with a block of source data or a string, and it calculates the
    MD5 checksum of that data.

    You can then retrieve this checksum as a 16-byte block, or as a hex string.
*/
class JUCE_API  MD5
{
public:

    /** Creates a null MD5 object. */
    MD5();

    /** Creates a copy of another MD5. */
    MD5 (const MD5& other);

    /** Copies another MD5. */
    const MD5& operator= (const MD5& other);

    /** Creates a checksum for a block of binary data. */
    MD5 (const MemoryBlock& data);

    /** Creates a checksum for a block of binary data. */
    MD5 (const char* data, const int numBytes);

    /** Creates a checksum for a string.

        Note that this operates on the string as a block of unicode characters, so the
        result you get will differ from the value you'd get if the string was treated
        as a block of utf8 or ascii. Bear this in mind if you're comparing the result
        of this method with a checksum created by a different framework, which may have
        used a different encoding.
    */
    MD5 (const String& text);

    /** Creates a checksum for the input from a stream.

        This will read up to the given number of bytes from the stream, and produce the
        checksum of that. If the number of bytes to read is negative, it'll read
        until the stream is exhausted.
    */
    MD5 (InputStream& input, int numBytesToRead = -1);

    /** Creates a checksum for a file. */
    MD5 (const File& file);

    /** Destructor. */
    ~MD5();

    /** Returns the checksum as a 16-byte block of data. */
    const MemoryBlock getRawChecksumData() const;

    /** Returns the checksum as a 32-digit hex string. */
    const String toHexString() const;

    /** Compares this to another MD5. */
    bool operator== (const MD5& other) const;

    /** Compares this to another MD5. */
    bool operator!= (const MD5& other) const;

    juce_UseDebuggingNewOperator

private:
    uint8 result [16];

    struct ProcessContext
    {
        uint8 buffer [64];
        uint32 state [4];
        uint32 count [2];

        ProcessContext();

        void processBlock (const uint8* const data, int dataSize);
        void transform (const uint8* const buffer);
        void finish (uint8* const result);
    };

    void processStream (InputStream& input, int numBytesToRead);
};

#endif   // __JUCE_MD5_JUCEHEADER__
/********* End of inlined file: juce_MD5.h *********/

#endif
#ifndef __JUCE_PRIMES_JUCEHEADER__

/********* Start of inlined file: juce_Primes.h *********/
#ifndef __JUCE_PRIMES_JUCEHEADER__
#define __JUCE_PRIMES_JUCEHEADER__

/**
    Prime number creation class.

    This class contains static methods for generating and testing prime numbers.

    @see BitArray
*/
class JUCE_API  Primes
{
public:

    /** Creates a random prime number with a given bit-length.

        The certainty parameter specifies how many iterations to use when testing
        for primality. A safe value might be anything over about 20-30.

        The randomSeeds parameter lets you optionally pass it a set of values with
        which to seed the random number generation, improving the security of the
        keys generated.
    */
    static const BitArray createProbablePrime (int bitLength,
                                               int certainty,
                                               const int* randomSeeds = 0,
                                               int numRandomSeeds = 0) throw();

    /** Tests a number to see if it's prime.

        This isn't a bulletproof test, it uses a Miller-Rabin test to determine
        whether the number is prime.

        The certainty parameter specifies how many iterations to use when testing - a
        safe value might be anything over about 20-30.
    */
    static bool isProbablyPrime (const BitArray& number,
                                 int certainty) throw();
};

#endif   // __JUCE_PRIMES_JUCEHEADER__
/********* End of inlined file: juce_Primes.h *********/

#endif
#ifndef __JUCE_RSAKEY_JUCEHEADER__

/********* Start of inlined file: juce_RSAKey.h *********/
#ifndef __JUCE_RSAKEY_JUCEHEADER__
#define __JUCE_RSAKEY_JUCEHEADER__

/**
    RSA public/private key-pair encryption class.

    An object of this type makes up one half of a public/private RSA key pair. Use the
    createKeyPair() method to create a matching pair for encoding/decoding.
*/
class JUCE_API  RSAKey
{
public:

    /** Creates a null key object.

        Initialise a pair of objects for use with the createKeyPair() method.
    */
    RSAKey() throw();

    /** Loads a key from an encoded string representation.

        This reloads a key from a string created by the toString() method.
    */
    RSAKey (const String& stringRepresentation) throw();

    /** Destructor. */
    ~RSAKey() throw();

    /** Turns the key into a string representation.

        This can be reloaded using the constructor that takes a string.
    */
    const String toString() const throw();

    /** Encodes or decodes a value.

        Call this on the public key object to encode some data, then use the matching
        private key object to decode it.

        Returns false if the operation failed, e.g. if this object isn't a valid key.
    */
    bool applyToValue (BitArray& value) const throw();

    /** Creates a public/private key-pair.

        Each key will perform one-way encryption that can only be reversed by
        using the other key.

        The numBits parameter specifies the size of key, e.g. 128, 256, 512 bit. Bigger
        sizes are more secure, but this method will take longer to execute.

        The randomSeeds parameter lets you optionally pass it a set of values with
        which to seed the random number generation, improving the security of the
        keys generated.
    */
    static void createKeyPair (RSAKey& publicKey,
                               RSAKey& privateKey,
                               const int numBits,
                               const int* randomSeeds = 0,
                               const int numRandomSeeds = 0) throw();

    juce_UseDebuggingNewOperator

protected:
    BitArray part1, part2;
};

#endif   // __JUCE_RSAKEY_JUCEHEADER__
/********* End of inlined file: juce_RSAKey.h *********/

#endif
#ifndef __JUCE_SOCKET_JUCEHEADER__

/********* Start of inlined file: juce_Socket.h *********/
#ifndef __JUCE_SOCKET_JUCEHEADER__
#define __JUCE_SOCKET_JUCEHEADER__

/**
    A wrapper for a streaming (TCP) socket.

    This allows low-level use of sockets; for an easier-to-use messaging layer on top of
    sockets, you could also try the InterprocessConnection class.

    @see DatagramSocket, InterprocessConnection, InterprocessConnectionServer
*/
class JUCE_API  StreamingSocket
{
public:

    /** Creates an uninitialised socket.

        To connect it, use the connect() method, after which you can read() or write()
        to it.

        To wait for other sockets to connect to this one, the createListener() method
        enters "listener" mode, and can be used to spawn new sockets for each connection
        that comes along.
    */
    StreamingSocket();

    /** Destructor. */
    ~StreamingSocket();

    /** Binds the socket to the specified local port.

        @returns    true on success; false may indicate that another socket is already bound
                    on the same port
    */
    bool bindToPort (const int localPortNumber);

    /** Tries to connect the socket to hostname:port.

        If timeOutMillisecs is 0, then this method will block until the operating system
        rejects the connection (which could take a long time).

        @returns true if it succeeds.
        @see isConnected
    */
    bool connect (const String& remoteHostname,
                  const int remotePortNumber,
                  const int timeOutMillisecs = 3000);

    /** True if the socket is currently connected. */
    bool isConnected() const throw()                            { return connected; }

    /** Closes the connection. */
    void close();

    /** Returns the name of the currently connected host. */
    const String& getHostName() const throw()                   { return hostName; }

    /** Returns the port number that's currently open. */
    int getPort() const throw()                                 { return portNumber; }

    /** True if the socket is connected to this machine rather than over the network. */
    bool isLocal() const throw();

    /** Waits until the socket is ready for reading or writing.

        If readyForReading is true, it will wait until the socket is ready for
        reading; if false, it will wait until it's ready for writing.

        If the timeout is < 0, it will wait forever, or else will give up after
        the specified time.

        If the socket is ready on return, this returns 1. If it times-out before
        the socket becomes ready, it returns 0. If an error occurs, it returns -1.
    */
    int waitUntilReady (const bool readyForReading,
                        const int timeoutMsecs) const;

    /** Reads bytes from the socket.

        If blockUntilSpecifiedAmountHasArrived is true, the method will block until
        maxBytesToRead bytes have been read, (or until an error occurs). If this
        flag is false, the method will return as much data as is currently available
        without blocking.

        @returns the number of bytes read, or -1 if there was an error.
        @see waitUntilReady
    */
    int read (void* destBuffer, const int maxBytesToRead,
              const bool blockUntilSpecifiedAmountHasArrived);

    /** Writes bytes to the socket from a buffer.

        Note that this method will block unless you have checked the socket is ready
        for writing before calling it (see the waitUntilReady() method).

        @returns the number of bytes written, or -1 if there was an error.
    */
    int write (const void* sourceBuffer, const int numBytesToWrite);

    /** Puts this socket into "listener" mode.

        When in this mode, your thread can call waitForNextConnection() repeatedly,
        which will spawn new sockets for each new connection, so that these can
        be handled in parallel by other threads.

        This returns true if it manages to open the socket successfully.

        @see waitForNextConnection
    */
    bool createListener (const int portNumber);

    /** When in "listener" mode, this waits for a connection and spawns it as a new
        socket.

        The object that gets returned will be owned by the caller.

        This method can only be called after using createListener().

        @see createListener
    */
    StreamingSocket* waitForNextConnection() const;

    juce_UseDebuggingNewOperator

private:
    String hostName;
    int volatile portNumber, handle;
    bool connected, isListener;

    StreamingSocket (const String& hostname, const int portNumber, const int handle);
    StreamingSocket (const StreamingSocket&);
    const StreamingSocket& operator= (const StreamingSocket&);
};

/**
    A wrapper for a datagram (UDP) socket.

    This allows low-level use of sockets; for an easier-to-use messaging layer on top of
    sockets, you could also try the InterprocessConnection class.

    @see StreamingSocket, InterprocessConnection, InterprocessConnectionServer
*/
class JUCE_API  DatagramSocket
{
public:

    /**
        Creates an (uninitialised) datagram socket.

        The localPortNumber is the port on which to bind this socket. If this value is 0,
        the port number is assigned by the operating system.

        To use the socket for sending, call the connect() method. This will not immediately
        make a connection, but will save the destination you've provided. After this, you can
        call read() or write().

        If enableBroadcasting is true, the socket will be allowed to send broadcast messages
        (may require extra privileges on linux)

        To wait for other sockets to connect to this one, call waitForNextConnection().
    */
    DatagramSocket (const int localPortNumber,
                    const bool enableBroadcasting = false);

    /** Destructor. */
    ~DatagramSocket();

    /** Binds the socket to the specified local port.

        @returns    true on success; false may indicate that another socket is already bound
                    on the same port
    */
    bool bindToPort (const int localPortNumber);

    /** Tries to connect the socket to hostname:port.

        If timeOutMillisecs is 0, then this method will block until the operating system
        rejects the connection (which could take a long time).

        @returns true if it succeeds.
        @see isConnected
    */
    bool connect (const String& remoteHostname,
                  const int remotePortNumber,
                  const int timeOutMillisecs = 3000);

    /** True if the socket is currently connected. */
    bool isConnected() const throw()                            { return connected; }

    /** Closes the connection. */
    void close();

    /** Returns the name of the currently connected host. */
    const String& getHostName() const throw()                   { return hostName; }

    /** Returns the port number that's currently open. */
    int getPort() const throw()                                 { return portNumber; }

    /** True if the socket is connected to this machine rather than over the network. */
    bool isLocal() const throw();

    /** Waits until the socket is ready for reading or writing.

        If readyForReading is true, it will wait until the socket is ready for
        reading; if false, it will wait until it's ready for writing.

        If the timeout is < 0, it will wait forever, or else will give up after
        the specified time.

        If the socket is ready on return, this returns 1. If it times-out before
        the socket becomes ready, it returns 0. If an error occurs, it returns -1.
    */
    int waitUntilReady (const bool readyForReading,
                        const int timeoutMsecs) const;

    /** Reads bytes from the socket.

        If blockUntilSpecifiedAmountHasArrived is true, the method will block until
        maxBytesToRead bytes have been read, (or until an error occurs). If this
        flag is false, the method will return as much data as is currently available
        without blocking.

        @returns the number of bytes read, or -1 if there was an error.
        @see waitUntilReady
    */
    int read (void* destBuffer, const int maxBytesToRead,
              const bool blockUntilSpecifiedAmountHasArrived);

    /** Writes bytes to the socket from a buffer.

        Note that this method will block unless you have checked the socket is ready
        for writing before calling it (see the waitUntilReady() method).

        @returns the number of bytes written, or -1 if there was an error.
    */
    int write (const void* sourceBuffer, const int numBytesToWrite);

    /** This waits for incoming data to be sent, and returns a socket that can be used
        to read it.

        The object that gets returned is owned by the caller, and can't be used for
        sending, but can be used to read the data.
    */
    DatagramSocket* waitForNextConnection() const;

    juce_UseDebuggingNewOperator

private:
    String hostName;
    int volatile portNumber, handle;
    bool connected, allowBroadcast;
    void* serverAddress;

    DatagramSocket (const String& hostname, const int portNumber, const int handle, const int localPortNumber);
    DatagramSocket (const DatagramSocket&);
    const DatagramSocket& operator= (const DatagramSocket&);
};

#endif   // __JUCE_SOCKET_JUCEHEADER__
/********* End of inlined file: juce_Socket.h *********/

#endif
#ifndef __JUCE_URL_JUCEHEADER__

/********* Start of inlined file: juce_URL.h *********/
#ifndef __JUCE_URL_JUCEHEADER__
#define __JUCE_URL_JUCEHEADER__

/**
    Represents a URL and has a bunch of useful functions to manipulate it.

    This class can be used to launch URLs in browsers, and also to create
    InputStreams that can read from remote http or ftp sources.
*/
class JUCE_API  URL
{
public:

    /** Creates an empty URL. */
    URL() throw();

    /** Creates a URL from a string. */
    URL (const String& url);

    /** Creates a copy of another URL. */
    URL (const URL& other);

    /** Destructor. */
    ~URL() throw();

    /** Copies this URL from another one. */
    const URL& operator= (const URL& other);

    /** Returns a string version of the URL.

        If includeGetParameters is true and any parameters have been set with the
        withParameter() method, then the string will have these appended on the
        end and url-encoded.
    */
    const String toString (const bool includeGetParameters) const;

    /** True if it seems to be valid. */
    bool isWellFormed() const;

    /** Returns just the domain part of the URL.

        E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com".
    */
    const String getDomain() const;

    /** Returns the path part of the URL.

        E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar".
    */
    const String getSubPath() const;

    /** Returns the scheme of the URL.

        E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't
        include the colon).
    */
    const String getScheme() const;

    /** Returns a new version of this URL that uses a different sub-path.

        E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
        "bar", it'll return "http://www.xyz.com/bar?x=1".
    */
    const URL withNewSubPath (const String& newPath) const;

    /** Returns a copy of this URL, with a GET parameter added to the end.

        Any control characters in the value will be encoded.

        e.g. calling "withParameter ("amount", "some fish") for the url "www.fish.com"
        would produce a new url whose toString(true) method would return
        "www.fish.com?amount=some+fish".
    */
    const URL withParameter (const String& parameterName,
                             const String& parameterValue) const;

    /** Returns a copy of this URl, with a file-upload type parameter added to it.

        When performing a POST where one of your parameters is a binary file, this
        lets you specify the file.

        Note that the filename is stored, but the file itself won't actually be read
        until this URL is later used to create a network input stream.
    */
    const URL withFileToUpload (const String& parameterName,
                                const File& fileToUpload,
                                const String& mimeType) const;

    /** Returns a set of all the parameters encoded into the url.

        E.g. for the url "www.fish.com?type=haddock&amount=some+fish", this array would
        contain two pairs: "type" => "haddock" and "amount" => "some fish".

        The values returned will have been cleaned up to remove any escape characters.

        @see getNamedParameter, withParameter
    */
    const StringPairArray& getParameters() const throw();

    /** Returns the set of files that should be uploaded as part of a POST operation.

        This is the set of files that were added to the URL with the withFileToUpload()
        method.
    */
    const StringPairArray& getFilesToUpload() const throw();

    /** Returns the set of mime types associated with each of the upload files.
    */
    const StringPairArray& getMimeTypesOfUploadFiles() const throw();

    /** Returns a copy of this URL, with a block of data to send as the POST data.

        If you're setting the POST data, be careful not to have any parameters set
        as well, otherwise it'll all get thrown in together, and might not have the
        desired effect.

        If the URL already contains some POST data, this will replace it, rather
        than being appended to it.

        This data will only be used if you specify a post operation when you call
        createInputStream().
    */
    const URL withPOSTData (const String& postData) const;

    /** Returns the data that was set using withPOSTData().
    */
    const String getPostData() const throw()                        { return postData; }

    /** Tries to launch the system's default browser to open the URL.

        Returns true if this seems to have worked.
    */
    bool launchInDefaultBrowser() const;

    /** Takes a guess as to whether a string might be a valid website address.

        This isn't foolproof!
    */
    static bool isProbablyAWebsiteURL (const String& possibleURL);

    /** Takes a guess as to whether a string might be a valid email address.

        This isn't foolproof!
    */
    static bool isProbablyAnEmailAddress (const String& possibleEmailAddress);

    /** This callback function can be used by the createInputStream() method.

        It allows your app to receive progress updates during a lengthy POST operation. If you
        want to continue the operation, this should return true, or false to abort.
    */
    typedef bool (OpenStreamProgressCallback) (void* context, int bytesSent, int totalBytes);

    /** Attempts to open a stream that can read from this URL.

        @param usePostCommand   if true, it will try to do use a http 'POST' to pass
                                the paramters, otherwise it'll encode them into the
                                URL and do a 'GET'.
        @param progressCallback if this is non-zero, it lets you supply a callback function
                                to keep track of the operation's progress. This can be useful
                                for lengthy POST operations, so that you can provide user feedback.
        @param progressCallbackContext  if a callback is specified, this value will be passed to
                                the function
        @param extraHeaders     if not empty, this string is appended onto the headers that
                                are used for the request. It must therefore be a valid set of HTML
                                header directives, separated by newlines.
        @param connectionTimeOutMs  if 0, this will use whatever default setting the OS chooses. If
                                a negative number, it will be infinite. Otherwise it specifies a
                                time in milliseconds.
    */
    InputStream* createInputStream (const bool usePostCommand,
                                    OpenStreamProgressCallback* const progressCallback = 0,
                                    void* const progressCallbackContext = 0,
                                    const String& extraHeaders = String::empty,
                                    const int connectionTimeOutMs = 0) const;

    /** Tries to download the entire contents of this URL into a binary data block.

        If it succeeds, this will return true and append the data it read onto the end
        of the memory block.

        @param destData         the memory block to append the new data to
        @param usePostCommand   whether to use a POST command to get the data (uses
                                a GET command if this is false)
        @see readEntireTextStream, readEntireXmlStream
    */
    bool readEntireBinaryStream (MemoryBlock& destData,
                                 const bool usePostCommand = false) const;

    /** Tries to download the entire contents of this URL as a string.

        If it fails, this will return an empty string, otherwise it will return the
        contents of the downloaded file. If you need to distinguish between a read
        operation that fails and one that returns an empty string, you'll need to use
        a different method, such as readEntireBinaryStream().

        @param usePostCommand   whether to use a POST command to get the data (uses
                                a GET command if this is false)
        @see readEntireBinaryStream, readEntireXmlStream
    */
    const String readEntireTextStream (const bool usePostCommand = false) const;

    /** Tries to download the entire contents of this URL and parse it as XML.

        If it fails, or if the text that it reads can't be parsed as XML, this will
        return 0.

        When it returns a valid XmlElement object, the caller is responsibile for deleting
        this object when no longer needed.

        @param usePostCommand   whether to use a POST command to get the data (uses
                                a GET command if this is false)

        @see readEntireBinaryStream, readEntireTextStream
    */
    XmlElement* readEntireXmlStream (const bool usePostCommand = false) const;

    /** Adds escape sequences to a string to encode any characters that aren't
        legal in a URL.

        E.g. any spaces will be replaced with "%20".

        This is the opposite of removeEscapeChars().

        If isParameter is true, it means that the string is going to be used
        as a parameter, so it also encodes '$' and ',' (which would otherwise
        be legal in a URL.

        @see removeEscapeChars
    */
    static const String addEscapeChars (const String& stringToAddEscapeCharsTo,
                                        const bool isParameter);

    /** Replaces any escape character sequences in a string with their original
        character codes.

        E.g. any instances of "%20" will be replaced by a space.

        This is the opposite of addEscapeChars().

        @see addEscapeChars
    */
    static const String removeEscapeChars (const String& stringToRemoveEscapeCharsFrom);

    juce_UseDebuggingNewOperator

private:
    String url, postData;
    StringPairArray parameters, filesToUpload, mimeTypes;
};

#endif   // __JUCE_URL_JUCEHEADER__
/********* End of inlined file: juce_URL.h *********/

#endif
#ifndef __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__

/********* Start of inlined file: juce_BufferedInputStream.h *********/
#ifndef __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__
#define __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__

/** Wraps another input stream, and reads from it using an intermediate buffer

    If you're using an input stream such as a file input stream, and making lots of
    small read accesses to it, it's probably sensible to wrap it in one of these,
    so that the source stream gets accessed in larger chunk sizes, meaning less
    work for the underlying stream.
*/
class JUCE_API  BufferedInputStream  : public InputStream
{
public:

    /** Creates a BufferedInputStream from an input source.

        @param sourceStream                 the source stream to read from
        @param bufferSize                   the size of reservoir to use to buffer the source
        @param deleteSourceWhenDestroyed    whether the sourceStream that is passed in should be
                                            deleted by this object when it is itself deleted.
    */
    BufferedInputStream (InputStream* const sourceStream,
                         const int bufferSize,
                         const bool deleteSourceWhenDestroyed) throw();

    /** Destructor.

        This may also delete the source stream, if that option was chosen when the
        buffered stream was created.
    */
    ~BufferedInputStream() throw();

    int64 getTotalLength();
    int64 getPosition();
    bool setPosition (int64 newPosition);
    int read (void* destBuffer, int maxBytesToRead);
    const String readString();
    bool isExhausted();

    juce_UseDebuggingNewOperator

private:
    InputStream* const source;
    const bool deleteSourceWhenDestroyed;
    int bufferSize;
    int64 position, lastReadPos, bufferStart, bufferOverlap;
    char* buffer;
    void ensureBuffered();

    BufferedInputStream (const BufferedInputStream&);
    const BufferedInputStream& operator= (const BufferedInputStream&);
};

#endif   // __JUCE_BUFFEREDINPUTSTREAM_JUCEHEADER__
/********* End of inlined file: juce_BufferedInputStream.h *********/

#endif
#ifndef __JUCE_FILEINPUTSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_FileInputSource.h *********/
#ifndef __JUCE_FILEINPUTSOURCE_JUCEHEADER__
#define __JUCE_FILEINPUTSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_InputSource.h *********/
#ifndef __JUCE_INPUTSOURCE_JUCEHEADER__
#define __JUCE_INPUTSOURCE_JUCEHEADER__

/**
    A lightweight object that can create a stream to read some kind of resource.

    This may be used to refer to a file, or some other kind of source, allowing a
    caller to create an input stream that can read from it when required.

    @see FileInputSource
*/
class JUCE_API  InputSource
{
public:

    InputSource() throw()       {}

    /** Destructor. */
    virtual ~InputSource()      {}

    /** Returns a new InputStream to read this item.

        @returns            an inputstream that the caller will delete, or 0 if
                            the filename isn't found.
    */
    virtual InputStream* createInputStream() = 0;

    /** Returns a new InputStream to read an item, relative.

        @param relatedItemPath  the relative pathname of the resource that is required
        @returns            an inputstream that the caller will delete, or 0 if
                            the item isn't found.
    */
    virtual InputStream* createInputStreamFor (const String& relatedItemPath) = 0;

    /** Returns a hash code that uniquely represents this item.
    */
    virtual int64 hashCode() const = 0;

    juce_UseDebuggingNewOperator
};

#endif   // __JUCE_INPUTSOURCE_JUCEHEADER__
/********* End of inlined file: juce_InputSource.h *********/

/**
    A type of InputSource that represents a normal file.

    @see InputSource
*/
class JUCE_API  FileInputSource     : public InputSource
{
public:

    FileInputSource (const File& file) throw();
    ~FileInputSource();

    InputStream* createInputStream();
    InputStream* createInputStreamFor (const String& relatedItemPath);
    int64 hashCode() const;

    juce_UseDebuggingNewOperator

private:
    const File file;

    FileInputSource (const FileInputSource&);
    const FileInputSource& operator= (const FileInputSource&);
};

#endif   // __JUCE_FILEINPUTSOURCE_JUCEHEADER__
/********* End of inlined file: juce_FileInputSource.h *********/

#endif
#ifndef __JUCE_GZIPCOMPRESSOROUTPUTSTREAM_JUCEHEADER__

/********* Start of inlined file: juce_GZIPCompressorOutputStream.h *********/
#ifndef __JUCE_GZIPCOMPRESSOROUTPUTSTREAM_JUCEHEADER__
#define __JUCE_GZIPCOMPRESSOROUTPUTSTREAM_JUCEHEADER__

/**
    A stream which uses zlib to compress the data written into it.

    @see GZIPDecompressorInputStream
*/
class JUCE_API  GZIPCompressorOutputStream  : public OutputStream
{
public:

    /** Creates a compression stream.

        @param destStream                       the stream into which the compressed data should
                                                be written
        @param compressionLevel                 how much to compress the data, between 1 and 9, where
                                                1 is the fastest/lowest compression, and 9 is the
                                                slowest/highest compression. Any value outside this range
                                                indicates that a default compression level should be used.
        @param deleteDestStreamWhenDestroyed    whether or not to delete the destStream object when
                                                this stream is destroyed
        @param noWrap                           this is used internally by the ZipFile class
                                                and should be ignored by user applications
    */
    GZIPCompressorOutputStream (OutputStream* const destStream,
                                int compressionLevel = 0,
                                const bool deleteDestStreamWhenDestroyed = false,
                                const bool noWrap = false);

    /** Destructor. */
    ~GZIPCompressorOutputStream();

    void flush();
    int64 getPosition();
    bool setPosition (int64 newPosition);
    bool write (const void* destBuffer, int howMany);

    juce_UseDebuggingNewOperator

private:
    OutputStream* const destStream;
    const bool deleteDestStream;
    uint8* buffer;
    void* helper;
    bool doNextBlock();

    GZIPCompressorOutputStream (const GZIPCompressorOutputStream&);
    const GZIPCompressorOutputStream& operator= (const GZIPCompressorOutputStream&);
};

#endif   // __JUCE_GZIPCOMPRESSOROUTPUTSTREAM_JUCEHEADER__
/********* End of inlined file: juce_GZIPCompressorOutputStream.h *********/

#endif
#ifndef __JUCE_GZIPDECOMPRESSORINPUTSTREAM_JUCEHEADER__

/********* Start of inlined file: juce_GZIPDecompressorInputStream.h *********/
#ifndef __JUCE_GZIPDECOMPRESSORINPUTSTREAM_JUCEHEADER__
#define __JUCE_GZIPDECOMPRESSORINPUTSTREAM_JUCEHEADER__

/**
    This stream will decompress a source-stream using zlib.

    Tip: if you're reading lots of small items from one of these streams, you
         can increase the performance enormously by passing it through a
         BufferedInputStream, so that it has to read larger blocks less often.

    @see GZIPCompressorOutputStream
*/
class JUCE_API  GZIPDecompressorInputStream  : public InputStream
{
public:

    /** Creates a decompressor stream.

        @param sourceStream                 the stream to read from
        @param deleteSourceWhenDestroyed    whether or not to delete the source stream
                                            when this object is destroyed
        @param noWrap                       this is used internally by the ZipFile class
                                            and should be ignored by user applications
        @param uncompressedStreamLength     if the creator knows the length that the
                                            uncompressed stream will be, then it can supply this
                                            value, which will be returned by getTotalLength()
    */
    GZIPDecompressorInputStream (InputStream* const sourceStream,
                                 const bool deleteSourceWhenDestroyed,
                                 const bool noWrap = false,
                                 const int64 uncompressedStreamLength = -1);

    /** Destructor. */
    ~GZIPDecompressorInputStream();

    int64 getPosition();
    bool setPosition (int64 pos);
    int64 getTotalLength();
    bool isExhausted();
    int read (void* destBuffer, int maxBytesToRead);

    juce_UseDebuggingNewOperator

private:
    InputStream* const sourceStream;
    const int64 uncompressedStreamLength;
    const bool deleteSourceWhenDestroyed, noWrap;
    bool isEof;
    int activeBufferSize;
    int64 originalSourcePos, currentPos;
    uint8* buffer;
    void* helper;

    GZIPDecompressorInputStream (const GZIPDecompressorInputStream&);
    const GZIPDecompressorInputStream& operator= (const GZIPDecompressorInputStream&);
};

#endif   // __JUCE_GZIPDECOMPRESSORINPUTSTREAM_JUCEHEADER__
/********* End of inlined file: juce_GZIPDecompressorInputStream.h *********/

#endif
#ifndef __JUCE_INPUTSOURCE_JUCEHEADER__

#endif
#ifndef __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__

/********* Start of inlined file: juce_MemoryInputStream.h *********/
#ifndef __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__
#define __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__

/**
    Allows a block of data and to be accessed as a stream.

    This can either be used to refer to a shared block of memory, or can make its
    own internal copy of the data when the MemoryInputStream is created.
*/
class JUCE_API  MemoryInputStream  : public InputStream
{
public:

    /** Creates a MemoryInputStream.

        @param sourceData               the block of data to use as the stream's source
        @param sourceDataSize           the number of bytes in the source data block
        @param keepInternalCopyOfData   if false, the stream will just keep a pointer to
                                        the source data, so this data shouldn't be changed
                                        for the lifetime of the stream; if this parameter is
                                        true, the stream will make its own copy of the
                                        data and use that.
    */
    MemoryInputStream (const void* const sourceData,
                       const int sourceDataSize,
                       const bool keepInternalCopyOfData) throw();

    /** Destructor. */
    ~MemoryInputStream() throw();

    int64 getPosition();
    bool setPosition (int64 pos);
    int64 getTotalLength();
    bool isExhausted();
    int read (void* destBuffer, int maxBytesToRead);

    juce_UseDebuggingNewOperator

private:
    const char* data;
    int dataSize, position;
    MemoryBlock internalCopy;
};

#endif   // __JUCE_MEMORYINPUTSTREAM_JUCEHEADER__
/********* End of inlined file: juce_MemoryInputStream.h *********/

#endif
#ifndef __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__

/********* Start of inlined file: juce_MemoryOutputStream.h *********/
#ifndef __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__
#define __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__

/** Writes data to an internal memory buffer, which grows as required.

    The data that was written into the stream can then be accessed later as
    a contiguous block of memory.
*/
class JUCE_API  MemoryOutputStream  : public OutputStream
{
public:

    /** Creates a memory stream ready for writing into.

        @param initialSize  the intial amount of space to allocate for writing into
        @param granularity  the increments by which the internal storage will be increased
        @param memoryBlockToWriteTo if this is non-zero, then this block will be used as the
                                    place that the data gets stored. If it's zero, the stream
                                    will allocate its own storage internally, which you can
                                    access using getData() and getDataSize()
    */
    MemoryOutputStream (const int initialSize = 256,
                        const int granularity = 256,
                        MemoryBlock* const memoryBlockToWriteTo = 0) throw();

    /** Destructor.

        This will free any data that was written to it.
    */
    ~MemoryOutputStream() throw();

    /** Returns a pointer to the data that has been written to the stream.

        @see getDataSize
    */
    const char* getData() throw();

    /** Returns the number of bytes of data that have been written to the stream.

        @see getData
    */
    int getDataSize() const throw();

    /** Resets the stream, clearing any data that has been written to it so far. */
    void reset() throw();

    void flush();
    bool write (const void* buffer, int howMany);
    int64 getPosition();
    bool setPosition (int64 newPosition);

    juce_UseDebuggingNewOperator

private:
    MemoryBlock* data;
    int position, size, blockSize;
    bool ownsMemoryBlock;
};

#endif   // __JUCE_MEMORYOUTPUTSTREAM_JUCEHEADER__
/********* End of inlined file: juce_MemoryOutputStream.h *********/

#endif
#ifndef __JUCE_SUBREGIONSTREAM_JUCEHEADER__

/********* Start of inlined file: juce_SubregionStream.h *********/
#ifndef __JUCE_SUBREGIONSTREAM_JUCEHEADER__
#define __JUCE_SUBREGIONSTREAM_JUCEHEADER__

/** Wraps another input stream, and reads from a specific part of it.

    This lets you take a subsection of a stream and present it as an entire
    stream in its own right.
*/
class JUCE_API  SubregionStream  : public InputStream
{
public:

    /** Creates a SubregionStream from an input source.

        @param sourceStream                 the source stream to read from
        @param startPositionInSourceStream  this is the position in the source stream that
                                            corresponds to position 0 in this stream
        @param lengthOfSourceStream         this specifies the maximum number of bytes
                                            from the source stream that will be passed through
                                            by this stream. When the position of this stream
                                            exceeds lengthOfSourceStream, it will cause an end-of-stream.
                                            If the length passed in here is greater than the length
                                            of the source stream (as returned by getTotalLength()),
                                            then the smaller value will be used.
                                            Passing a negative value for this parameter means it
                                            will keep reading until the source's end-of-stream.
        @param deleteSourceWhenDestroyed    whether the sourceStream that is passed in should be
                                            deleted by this object when it is itself deleted.
    */
    SubregionStream (InputStream* const sourceStream,
                     const int64 startPositionInSourceStream,
                     const int64 lengthOfSourceStream,
                     const bool deleteSourceWhenDestroyed) throw();

    /** Destructor.

        This may also delete the source stream, if that option was chosen when the
        buffered stream was created.
    */
    ~SubregionStream() throw();

    int64 getTotalLength();
    int64 getPosition();
    bool setPosition (int64 newPosition);
    int read (void* destBuffer, int maxBytesToRead);
    bool isExhausted();

    juce_UseDebuggingNewOperator

private:
    InputStream* const source;
    const bool deleteSourceWhenDestroyed;
    const int64 startPositionInSourceStream, lengthOfSourceStream;

    SubregionStream (const SubregionStream&);
    const SubregionStream& operator= (const SubregionStream&);
};

#endif   // __JUCE_SUBREGIONSTREAM_JUCEHEADER__
/********* End of inlined file: juce_SubregionStream.h *********/

#endif
#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__

/********* Start of inlined file: juce_PerformanceCounter.h *********/
#ifndef __JUCE_PERFORMANCECOUNTER_JUCEHEADER__
#define __JUCE_PERFORMANCECOUNTER_JUCEHEADER__

/** A timer for measuring performance of code and dumping the results to a file.

    e.g. @code

        PerformanceCounter pc ("fish", 50, "/temp/myfishlog.txt");

        for (;;)
        {
            pc.start();

            doSomethingFishy();

            pc.stop();
        }
    @endcode

    In this example, the time of each period between calling start/stop will be
    measured and averaged over 50 runs, and the results printed to a file
    every 50 times round the loop.
*/
class JUCE_API  PerformanceCounter
{
public:

    /** Creates a PerformanceCounter object.

        @param counterName      the name used when printing out the statistics
        @param runsPerPrintout  the number of start/stop iterations before calling
                                printStatistics()
        @param loggingFile      a file to dump the results to - if this is File::nonexistent,
                                the results are just written to the debugger output
    */
    PerformanceCounter (const String& counterName,
                        int runsPerPrintout = 100,
                        const File& loggingFile = File::nonexistent);

    /** Destructor. */
    ~PerformanceCounter();

    /** Starts timing.

        @see stop
    */
    void start();

    /** Stops timing and prints out the results.

        The number of iterations before doing a printout of the
        results is set in the constructor.

        @see start
    */
    void stop();

    /** Dumps the current metrics to the debugger output and to a file.

        As well as using Logger::outputDebugString to print the results,
        this will write then to the file specified in the constructor (if
        this was valid).
    */
    void printStatistics();

    juce_UseDebuggingNewOperator

private:

    String name;
    int numRuns, runsPerPrint;
    double totalTime;
    int64 started;
    File outputFile;
};

#endif   // __JUCE_PERFORMANCECOUNTER_JUCEHEADER__
/********* End of inlined file: juce_PerformanceCounter.h *********/

#endif
#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__

/********* Start of inlined file: juce_PlatformUtilities.h *********/
#ifndef __JUCE_PLATFORMUTILITIES_JUCEHEADER__
#define __JUCE_PLATFORMUTILITIES_JUCEHEADER__

/**
    A collection of miscellaneous platform-specific utilities.

*/
class JUCE_API  PlatformUtilities
{
public:

    /** Plays the operating system's default alert 'beep' sound. */
    static void beep();

    static bool launchEmailWithAttachments (const String& targetEmailAddress,
                                            const String& emailSubject,
                                            const String& bodyText,
                                            const StringArray& filesToAttach);

#if JUCE_MAC || DOXYGEN

    /** MAC ONLY - Turns a Core CF String into a juce one. */
    static const String cfStringToJuceString (CFStringRef cfString);

    /** MAC ONLY - Turns a juce string into a Core CF one. */
    static CFStringRef juceStringToCFString (const String& s);

    /** MAC ONLY - Turns a file path into an FSRef, returning true if it succeeds. */
    static bool makeFSRefFromPath (FSRef* destFSRef, const String& path);

    /** MAC ONLY - Turns an FSRef into a juce string path. */
    static const String makePathFromFSRef (FSRef* file);

    /** MAC ONLY - Converts any decomposed unicode characters in a string into
        their precomposed equivalents.
    */
    static const String convertToPrecomposedUnicode (const String& s);

    /** MAC ONLY - Gets the type of a file from the file's resources. */
    static OSType getTypeOfFile (const String& filename);

    /** MAC ONLY - Returns true if this file is actually a bundle. */
    static bool isBundle (const String& filename);

    /** MAC ONLY - Adds an item to the dock */
    static void addItemToDock (const File& file);
#endif

#if JUCE_WIN32 || DOXYGEN

    // Some registry helper functions:

    /** WIN32 ONLY - Returns a string from the registry.

        The path is a string for the entire path of a value in the registry,
        e.g. "HKEY_CURRENT_USER\Software\foo\bar"
    */
    static const String getRegistryValue (const String& regValuePath,
                                          const String& defaultValue = String::empty);

    /** WIN32 ONLY - Sets a registry value as a string.

        This will take care of creating any groups needed to get to the given
        registry value.
    */
    static void setRegistryValue (const String& regValuePath,
                                  const String& value);

    /** WIN32 ONLY - Returns true if the given value exists in the registry. */
    static bool registryValueExists (const String& regValuePath);

    /** WIN32 ONLY - Deletes a registry value. */
    static void deleteRegistryValue (const String& regValuePath);

    /** WIN32 ONLY - Deletes a registry key (which is registry-talk for 'folder'). */
    static void deleteRegistryKey (const String& regKeyPath);

    /** WIN32 ONLY - Creates a file association in the registry.

        This lets you set the exe that should be launched by a given file extension.
        @param fileExtension        the file extension to associate, including the
                                    initial dot, e.g. ".txt"
        @param symbolicDescription  a space-free short token to identify the file type
        @param fullDescription      a human-readable description of the file type
        @param targetExecutable     the executable that should be launched
        @param iconResourceNumber   the icon that gets displayed for the file type will be
                                    found by looking up this resource number in the
                                    executable. Pass 0 here to not use an icon
    */
    static void registerFileAssociation (const String& fileExtension,
                                         const String& symbolicDescription,
                                         const String& fullDescription,
                                         const File& targetExecutable,
                                         int iconResourceNumber);

    /** WIN32 ONLY - This returns the HINSTANCE of the current module.

        In a normal Juce application this will be set to the module handle
        of the application executable.

        If you're writing a DLL using Juce and plan to use any Juce messaging or
        windows, you'll need to make sure you use the setCurrentModuleInstanceHandle()
        to set the correct module handle in your DllMain() function, because
        the win32 system relies on the correct instance handle when opening windows.
    */
    static void* JUCE_CALLTYPE getCurrentModuleInstanceHandle() throw();

    /** WIN32 ONLY - Sets a new module handle to be used by the library.

        @see getCurrentModuleInstanceHandle()
    */
    static void JUCE_CALLTYPE setCurrentModuleInstanceHandle (void* newHandle) throw();

    /** WIN32 ONLY - Gets the command-line params as a string.

        This is needed to avoid unicode problems with the argc type params.
    */
    static const String JUCE_CALLTYPE getCurrentCommandLineParams() throw();
#endif

    /** Clears the floating point unit's flags.

        Only has an effect under win32, currently.
    */
    static void fpuReset();

#if JUCE_LINUX || JUCE_WIN32

    /** Loads a dynamically-linked library into the process's address space.

        @param pathOrFilename   the platform-dependent name and search path
        @returns                a handle which can be used by getProcedureEntryPoint(), or
                                zero if it fails.
        @see freeDynamicLibrary, getProcedureEntryPoint
    */
    static void* loadDynamicLibrary (const String& pathOrFilename);

    /** Frees a dynamically-linked library.

        @param libraryHandle   a handle created by loadDynamicLibrary
        @see loadDynamicLibrary, getProcedureEntryPoint
    */
    static void freeDynamicLibrary (void* libraryHandle);

    /** Finds a procedure call in a dynamically-linked library.

        @param libraryHandle    a library handle returned by loadDynamicLibrary
        @param procedureName    the name of the procedure call to try to load
        @returns                a pointer to the function if found, or 0 if it fails
        @see loadDynamicLibrary
    */
    static void* getProcedureEntryPoint (void* libraryHandle,
                                         const String& procedureName);
#endif

#if JUCE_LINUX || DOXYGEN

#endif
};

#if JUCE_MAC

/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object
    using RAII.
*/
class ScopedAutoReleasePool
{
public:
    ScopedAutoReleasePool();
    ~ScopedAutoReleasePool();

private:
    void* pool;
};

/**
    A wrapper class for picking up events from an Apple IR remote control device.

    To use it, just create a subclass of this class, implementing the buttonPressed()
    callback, then call start() and stop() to start or stop receiving events.
*/
class JUCE_API  AppleRemoteDevice
{
public:

    AppleRemoteDevice();
    virtual ~AppleRemoteDevice();

    /** The set of buttons that may be pressed.
        @see buttonPressed
    */
    enum ButtonType
    {
        menuButton = 0,     /**< The menu button (if it's held for a short time). */
        playButton,         /**< The play button. */
        plusButton,         /**< The plus or volume-up button. */
        minusButton,        /**< The minus or volume-down button. */
        rightButton,        /**< The right button (if it's held for a short time). */
        leftButton,         /**< The left button (if it's held for a short time). */
        rightButton_Long,   /**< The right button (if it's held for a long time). */
        leftButton_Long,    /**< The menu button (if it's held for a long time). */
        menuButton_Long,    /**< The menu button (if it's held for a long time). */
        playButtonSleepMode,
        switched
    };

    /** Override this method to receive the callback about a button press.

        The callback will happen on the application's message thread.

        Some buttons trigger matching up and down events, in which the isDown parameter
        will be true and then false. Others only send a single event when the
        button is pressed.
    */
    virtual void buttonPressed (const ButtonType buttonId, const bool isDown) = 0;

    /** Starts the device running and responding to events.

        Returns true if it managed to open the device.

        @param inExclusiveMode  if true, the remote will be grabbed exclusively for this app,
                                and will not be available to any other part of the system. If
                                false, it will be shared with other apps.
        @see stop
    */
    bool start (const bool inExclusiveMode) throw();

    /** Stops the device running.
        @see start
    */
    void stop() throw();

    /** Returns true if the device has been started successfully.
    */
    bool isActive() const throw();

    /** Returns the ID number of the remote, if it has sent one.
    */
    int getRemoteId() const throw()             { return remoteId; }

    juce_UseDebuggingNewOperator

    /** @internal */
    void handleCallbackInternal();

private:
    void* device;
    void* queue;
    int remoteId;

    bool open (const bool openInExclusiveMode) throw();
};

#endif

#endif   // __JUCE_PLATFORMUTILITIES_JUCEHEADER__
/********* End of inlined file: juce_PlatformUtilities.h *********/

#endif
#ifndef __JUCE_UUID_JUCEHEADER__

/********* Start of inlined file: juce_Uuid.h *********/
#ifndef __JUCE_UUID_JUCEHEADER__
#define __JUCE_UUID_JUCEHEADER__

/**
    A universally unique 128-bit identifier.

    This class generates very random unique numbers based on the system time
    and MAC addresses if any are available. It's extremely unlikely that two identical
    UUIDs would ever be created by chance.

    The class includes methods for saving the ID as a string or as raw binary data.
*/
class JUCE_API  Uuid
{
public:

    /** Creates a new unique ID. */
    Uuid();

    /** Destructor. */
    ~Uuid() throw();

    /** Creates a copy of another UUID. */
    Uuid (const Uuid& other);

    /** Copies another UUID. */
    Uuid& operator= (const Uuid& other);

    /** Returns true if the ID is zero. */
    bool isNull() const throw();

    /** Compares two UUIDs. */
    bool operator== (const Uuid& other) const;

    /** Compares two UUIDs. */
    bool operator!= (const Uuid& other) const;

    /** Returns a stringified version of this UUID.

        A Uuid object can later be reconstructed from this string using operator= or
        the constructor that takes a string parameter.

        @returns a 32 character hex string.
    */
    const String toString() const;

    /** Creates an ID from an encoded string version.

        @see toString
    */
    Uuid (const String& uuidString);

    /** Copies from a stringified UUID.

        The string passed in should be one that was created with the toString() method.
    */
    Uuid& operator= (const String& uuidString);

    /** Returns a pointer to the internal binary representation of the ID.

        This is an array of 16 bytes. To reconstruct a Uuid from its data, use
        the constructor or operator= method that takes an array of uint8s.
    */
    const uint8* getRawData() const throw()                 { return value.asBytes; }

    /** Creates a UUID from a 16-byte array.

        @see getRawData
    */
    Uuid (const uint8* const rawData);

    /** Sets this UUID from 16-bytes of raw data. */
    Uuid& operator= (const uint8* const rawData);

    juce_UseDebuggingNewOperator

private:
    union
    {
        uint8 asBytes [16];
        int asInt[4];
        int64 asInt64[2];

    } value;
};

#endif   // __JUCE_UUID_JUCEHEADER__
/********* End of inlined file: juce_Uuid.h *********/

#endif
#ifndef __JUCE_ZIPFILE_JUCEHEADER__

/********* Start of inlined file: juce_ZipFile.h *********/
#ifndef __JUCE_ZIPFILE_JUCEHEADER__
#define __JUCE_ZIPFILE_JUCEHEADER__

/**
    Decodes a ZIP file from a stream.

    This can enumerate the items in a ZIP file and can create suitable stream objects
    to read each one.
*/
class JUCE_API  ZipFile
{
public:

    /** Creates a ZipFile for a given stream.

        @param inputStream                  the stream to read from
        @param deleteStreamWhenDestroyed    if set to true, the object passed-in
                                            will be deleted when this ZipFile object is deleted
    */
    ZipFile (InputStream* const inputStream,
             const bool deleteStreamWhenDestroyed) throw();

    /** Creates a ZipFile based for a file. */
    ZipFile (const File& file);

    /** Creates a ZipFile for an input source.

        The inputSource object will be owned by the zip file, which will delete
        it later when not needed.
    */
    ZipFile (InputSource* const inputSource);

    /** Destructor. */
    ~ZipFile() throw();

    /**
        Contains information about one of the entries in a ZipFile.

        @see ZipFile::getEntry
    */
    struct ZipEntry
    {
        /** The name of the file, which may also include a partial pathname. */
        String filename;

        /** The file's original size. */
        unsigned int uncompressedSize;

        /** The last time the file was modified. */
        Time fileTime;
    };

    /** Returns the number of items in the zip file. */
    int getNumEntries() const throw();

    /** Returns a structure that describes one of the entries in the zip file.

        This may return zero if the index is out of range.

        @see ZipFile::ZipEntry
    */
    const ZipEntry* getEntry (const int index) const throw();

    /** Returns the index of the first entry with a given filename.

        This uses a case-sensitive comparison to look for a filename in the
        list of entries. It might return -1 if no match is found.

        @see ZipFile::ZipEntry
    */
    int getIndexOfFileName (const String& fileName) const throw();

    /** Returns a structure that describes one of the entries in the zip file.

        This uses a case-sensitive comparison to look for a filename in the
        list of entries. It might return 0 if no match is found.

        @see ZipFile::ZipEntry
    */
    const ZipEntry* getEntry (const String& fileName) const throw();

    /** Sorts the list of entries, based on the filename.
    */
    void sortEntriesByFilename();

    /** Creates a stream that can read from one of the zip file's entries.

        The stream that is returned must be deleted by the caller (and
        zero might be returned if a stream can't be opened for some reason).

        The stream must not be used after the ZipFile object that created
        has been deleted.
    */
    InputStream* createStreamForEntry (const int index);

    /** Uncompresses all of the files in the zip file.

        This will expand all the entires into a target directory. The relative
        paths of the entries are used.

        @param targetDirectory      the root folder to uncompress to
        @param shouldOverwriteFiles whether to overwrite existing files with similarly-named ones
    */
    void uncompressTo (const File& targetDirectory,
                       const bool shouldOverwriteFiles = true);

    juce_UseDebuggingNewOperator

private:
    VoidArray entries;
    friend class ZipInputStream;
    CriticalSection lock;
    InputStream* inputStream;
    InputSource* inputSource;

    bool deleteStreamWhenDestroyed;
    int numEntries, centralRecStart;

#ifdef JUCE_DEBUG
    int numOpenStreams;
#endif

    void init();
    int findEndOfZipEntryTable (InputStream* in);

    ZipFile (const ZipFile&);
    const ZipFile& operator= (const ZipFile&);
};

#endif   // __JUCE_ZIPFILE_JUCEHEADER__
/********* End of inlined file: juce_ZipFile.h *********/

#endif
#ifndef __JUCE_CHARACTERFUNCTIONS_JUCEHEADER__

#endif
#ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__

/********* Start of inlined file: juce_LocalisedStrings.h *********/
#ifndef __JUCE_LOCALISEDSTRINGS_JUCEHEADER__
#define __JUCE_LOCALISEDSTRINGS_JUCEHEADER__

/** Used in the same way as the T(text) macro, this will attempt to translate a
    string into a localised version using the LocalisedStrings class.

    @see LocalisedStrings
*/
#define TRANS(stringLiteral)     \
    LocalisedStrings::translateWithCurrentMappings (stringLiteral)

/**
    Used to convert strings to localised foreign-language versions.

    This is basically a look-up table of strings and their translated equivalents.
    It can be loaded from a text file, so that you can supply a set of localised
    versions of strings that you use in your app.

    To use it in your code, simply call the translate() method on each string that
    might have foreign versions, and if none is found, the method will just return
    the original string.

    The translation file should start with some lines specifying a description of
    the language it contains, and also a list of ISO country codes where it might
    be appropriate to use the file. After that, each line of the file should contain
    a pair of quoted strings with an '=' sign.

    E.g. for a french translation, the file might be:

    @code
    language: French
    countries: fr be mc ch lu

    "hello" = "bonjour"
    "goodbye" = "au revoir"
    @endcode

    If the strings need to contain a quote character, they can use '\"' instead, and
    if the first non-whitespace character on a line isn't a quote, then it's ignored,
    (you can use this to add comments).

    Note that this is a singleton class, so don't create or destroy the object directly.
    There's also a TRANS(text) macro defined to make it easy to use the this.

    E.g. @code
    printSomething (TRANS("hello"));
    @endcode

    This macro is used in the Juce classes themselves, so your application has a chance to
    intercept and translate any internal Juce text strings that might be shown. (You can easily
    get a list of all the messages by searching for the TRANS() macro in the Juce source
    code).
*/
class JUCE_API  LocalisedStrings
{
public:

    /** Creates a set of translations from the text of a translation file.

        When you create one of these, you can call setCurrentMappings() to make it
        the set of mappings that the system's using.
    */
    LocalisedStrings (const String& fileContents) throw();

    /** Creates a set of translations from a file.

        When you create one of these, you can call setCurrentMappings() to make it
        the set of mappings that the system's using.
    */
    LocalisedStrings (const File& fileToLoad) throw();

    /** Destructor. */
    ~LocalisedStrings() throw();

    /** Selects the current set of mappings to be used by the system.

        The object you pass in will be automatically deleted when no longer needed, so
        don't keep a pointer to it. You can also pass in zero to remove the current
        mappings.

        See also the TRANS() macro, which uses the current set to do its translation.

        @see translateWithCurrentMappings
    */
    static void setCurrentMappings (LocalisedStrings* newTranslations) throw();

    /** Returns the currently selected set of mappings.

        This is the object that was last passed to setCurrentMappings(). It may
        be 0 if none has been created.
    */
    static LocalisedStrings* getCurrentMappings() throw();

    /** Tries to translate a string using the currently selected set of mappings.

        If no mapping has been set, or if the mapping doesn't contain a translation
        for the string, this will just return the original string.

        See also the TRANS() macro, which uses this method to do its translation.

        @see setCurrentMappings, getCurrentMappings
    */
    static const String translateWithCurrentMappings (const String& text) throw();

    /** Tries to translate a string using the currently selected set of mappings.

        If no mapping has been set, or if the mapping doesn't contain a translation
        for the string, this will just return the original string.

        See also the TRANS() macro, which uses this method to do its translation.

        @see setCurrentMappings, getCurrentMappings
    */
    static const String translateWithCurrentMappings (const char* text) throw();

    /** Attempts to look up a string and return its localised version.

        If the string isn't found in the list, the original string will be returned.
    */
    const String translate (const String& text) const throw();

    /** Returns the name of the language specified in the translation file.

        This is specified in the file using a line starting with "language:", e.g.
        @code
        language: german
        @endcode
    */
    const String getLanguageName() const throw()                { return languageName; }

    /** Returns the list of suitable country codes listed in the translation file.

        These is specified in the file using a line starting with "countries:", e.g.
        @code
        countries: fr be mc ch lu
        @endcode

        The country codes are supposed to be 2-character ISO complient codes.
    */
    const StringArray getCountryCodes() const throw()           { return countryCodes; }

    /** Indicates whether to use a case-insensitive search when looking up a string.
        This defaults to true.
    */
    void setIgnoresCase (const bool shouldIgnoreCase) throw();

    juce_UseDebuggingNewOperator

private:
    String languageName;
    StringArray countryCodes;
    StringPairArray translations;

    void loadFromText (const String& fileContents) throw();
};

#endif   // __JUCE_LOCALISEDSTRINGS_JUCEHEADER__
/********* End of inlined file: juce_LocalisedStrings.h *********/

#endif
#ifndef __JUCE_STRING_JUCEHEADER__

#endif
#ifndef __JUCE_STRINGARRAY_JUCEHEADER__

#endif
#ifndef __JUCE_STRINGPAIRARRAY_JUCEHEADER__

#endif
#ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__

/********* Start of inlined file: juce_XmlDocument.h *********/
#ifndef __JUCE_XMLDOCUMENT_JUCEHEADER__
#define __JUCE_XMLDOCUMENT_JUCEHEADER__

/**
    Parses a text-based XML document and creates an XmlElement object from it.

    The parser will parse DTDs to load external entities but won't
    check the document for validity against the DTD.

    e.g.
    @code

    XmlDocument myDocument (File ("myfile.xml"));
    XmlElement* mainElement = myDocument.getDocumentElement();

    if (mainElement == 0)
    {
        String error = myDocument.getLastParseError();
    }
    else
    {
        ..use the element
    }

    @endcode

    @see XmlElement
*/
class JUCE_API  XmlDocument
{
public:

    /** Creates an XmlDocument from the xml text.

        The text doesn't actually get parsed until the getDocumentElement() method is
        called.
    */
    XmlDocument (const String& documentText) throw();

    /** Creates an XmlDocument from a file.

        The text doesn't actually get parsed until the getDocumentElement() method is
        called.
    */
    XmlDocument (const File& file);

    /** Destructor. */
    ~XmlDocument() throw();

    /** Creates an XmlElement object to represent the main document node.

        This method will do the actual parsing of the text, and if there's a
        parse error, it may returns 0 (and you can find out the error using
        the getLastParseError() method).

        @param onlyReadOuterDocumentElement     if true, the parser will only read the
                                                first section of the file, and will only
                                                return the outer document element - this
                                                allows quick checking of large files to
                                                see if they contain the correct type of
                                                tag, without having to parse the entire file
        @returns    a new XmlElement which the caller will need to delete, or null if
                    there was an error.
        @see getLastParseError
    */
    XmlElement* getDocumentElement (const bool onlyReadOuterDocumentElement = false);

    /** Returns the parsing error that occurred the last time getDocumentElement was called.

        @returns the error, or an empty string if there was no error.
    */
    const String& getLastParseError() const throw();

    /** Sets an input source object to use for parsing documents that reference external entities.

        If the document has been created from a file, this probably won't be needed, but
        if you're parsing some text and there might be a DTD that references external
        files, you may need to create a custom input source that can retrieve the
        other files it needs.

        The object that is passed-in will be deleted automatically when no longer needed.

        @see InputSource
    */
    void setInputSource (InputSource* const newSource) throw();

    /** Sets a flag to change the treatment of empty text elements.

        If this is true (the default state), then any text elements that contain only
        whitespace characters will be ingored during parsing. If you need to catch
        whitespace-only text, then you should set this to false before calling the
        getDocumentElement() method.
    */
    void setEmptyTextElementsIgnored (const bool shouldBeIgnored) throw();

    juce_UseDebuggingNewOperator

private:
    String originalText;
    const tchar* input;
    bool outOfData, errorOccurred;

    bool identifierLookupTable [128];
    String lastError, dtdText;
    StringArray tokenisedDTD;
    bool needToLoadDTD, ignoreEmptyTextElements;
    InputSource* inputSource;

    void setLastError (const String& desc, const bool carryOn) throw();
    void skipHeader() throw();
    void skipNextWhiteSpace() throw();
    tchar readNextChar() throw();
    XmlElement* readNextElement (const bool alsoParseSubElements) throw();
    void readChildElements (XmlElement* parent) throw();
    int findNextTokenLength() throw();
    void readQuotedString (String& result) throw();
    void readEntity (String& result) throw();

    const String getFileContents (const String& filename) const;
    const String expandEntity (const String& entity);
    const String expandExternalEntity (const String& entity);
    const String getParameterEntity (const String& entity);
};

#endif   // __JUCE_XMLDOCUMENT_JUCEHEADER__
/********* End of inlined file: juce_XmlDocument.h *********/

#endif
#ifndef __JUCE_XMLELEMENT_JUCEHEADER__

#endif
#ifndef __JUCE_CRITICALSECTION_JUCEHEADER__

#endif
#ifndef __JUCE_INTERPROCESSLOCK_JUCEHEADER__

/********* Start of inlined file: juce_InterProcessLock.h *********/
#ifndef __JUCE_INTERPROCESSLOCK_JUCEHEADER__
#define __JUCE_INTERPROCESSLOCK_JUCEHEADER__

/**
    Acts as a critical section which processes can use to block each other.

    @see CriticalSection
*/
class JUCE_API  InterProcessLock
{
public:

    /** Creates a lock object.

        @param name     a name that processes will use to identify this lock object
    */
    InterProcessLock (const String& name) throw();

    /** Destructor.

        This will also release the lock if it's currently held by this process.
    */
    ~InterProcessLock() throw();

    /** Attempts to lock the critical section.

        @param timeOutMillisecs     how many milliseconds to wait if the lock
                                    is already held by another process - a value of
                                    0 will return immediately, negative values will wait
                                    forever
        @returns    true if the lock could be gained within the timeout period, or
                    false if the timeout expired.
    */
    bool enter (int timeOutMillisecs = -1) throw();

    /** Releases the lock if it's currently held by this process.
    */
    void exit() throw();

    juce_UseDebuggingNewOperator

private:

    void* internal;
    String name;
    int reentrancyLevel;

    InterProcessLock (const InterProcessLock&);
    const InterProcessLock& operator= (const InterProcessLock&);
};

#endif   // __JUCE_INTERPROCESSLOCK_JUCEHEADER__
/********* End of inlined file: juce_InterProcessLock.h *********/

#endif
#ifndef __JUCE_PROCESS_JUCEHEADER__

/********* Start of inlined file: juce_Process.h *********/
#ifndef __JUCE_PROCESS_JUCEHEADER__
#define __JUCE_PROCESS_JUCEHEADER__

/** Represents the current executable's process.

    This contains methods for controlling the current application at the
    process-level.

    @see Thread, JUCEApplication
*/
class JUCE_API  Process
{
public:

    enum ProcessPriority
    {
        LowPriority         = 0,
        NormalPriority      = 1,
        HighPriority        = 2,
        RealtimePriority    = 3
    };

    /** Changes the current process's priority.

        @param priority     the process priority, where
                            0=low, 1=normal, 2=high, 3=realtime
    */
    static void setPriority (const ProcessPriority priority);

    /** Kills the current process immediately.

        This is an emergency process terminator that kills the application
        immediately - it's intended only for use only when something goes
        horribly wrong.

        @see JUCEApplication::quit
    */
    static void terminate();

    /** Returns true if this application process is the one that the user is
        currently using.
    */
    static bool isForegroundProcess() throw();

    /** Raises the current process's privilege level.

        Does nothing if this isn't supported by the current OS, or if process
        privilege level is fixed.
    */
    static void raisePrivilege();

    /** Lowers the current process's privilege level.

        Does nothing if this isn't supported by the current OS, or if process
        privilege level is fixed.
    */
    static void lowerPrivilege();

    /** Returns true if this process is being hosted by a debugger.
    */
    static bool JUCE_CALLTYPE isRunningUnderDebugger() throw();
};

#endif   // __JUCE_PROCESS_JUCEHEADER__
/********* End of inlined file: juce_Process.h *********/

#endif
#ifndef __JUCE_READWRITELOCK_JUCEHEADER__

/********* Start of inlined file: juce_ReadWriteLock.h *********/
#ifndef __JUCE_READWRITELOCK_JUCEHEADER__
#define __JUCE_READWRITELOCK_JUCEHEADER__

/********* Start of inlined file: juce_WaitableEvent.h *********/
#ifndef __JUCE_WAITABLEEVENT_JUCEHEADER__
#define __JUCE_WAITABLEEVENT_JUCEHEADER__

/**
    Allows threads to wait for events triggered by other threads.

    A thread can call wait() on a WaitableObject, and this will suspend the
    calling thread until another thread wakes it up by calling the signal()
    method.
*/
class JUCE_API  WaitableEvent
{
public:

    /** Creates a WaitableEvent object. */
    WaitableEvent() throw();

    /** Destructor.

        If other threads are waiting on this object when it gets deleted, this
        can cause nasty errors, so be careful!
    */
    ~WaitableEvent() throw();

    /** Suspends the calling thread until the event has been signalled.

        This will wait until the object's signal() method is called by another thread,
        or until the timeout expires.

        After the event has been signalled, this method will return true and reset
        the event.

        @param timeOutMilliseconds  the maximum time to wait, in milliseconds. A negative
                                    value will cause it to wait forever.

        @returns    true if the object has been signalled, false if the timeout expires first.
        @see signal, reset
    */
    bool wait (const int timeOutMilliseconds = -1) const throw();

    /** Wakes up any threads that are currently waiting on this object.

        If signal() is called when nothing is waiting, the next thread to call wait()
        will return immediately and reset the signal.

        @see wait, reset
    */
    void signal() const throw();

    /** Resets the event to an unsignalled state.

        If it's not already signalled, this does nothing.
    */
    void reset() const throw();

    juce_UseDebuggingNewOperator

private:
    void* internal;

    WaitableEvent (const WaitableEvent&);
    const WaitableEvent& operator= (const WaitableEvent&);
};

#endif   // __JUCE_WAITABLEEVENT_JUCEHEADER__
/********* End of inlined file: juce_WaitableEvent.h *********/

/********* Start of inlined file: juce_Thread.h *********/
#ifndef __JUCE_THREAD_JUCEHEADER__
#define __JUCE_THREAD_JUCEHEADER__

/**
    Encapsulates a thread.

    Subclasses derive from Thread and implement the run() method, in which they
    do their business. The thread can then be started with the startThread() method
    and controlled with various other methods.

    This class also contains some thread-related static methods, such
    as sleep(), yield(), getCurrentThreadId() etc.

    @see CriticalSection, WaitableEvent, Process, ThreadWithProgressWindow,
         MessageManagerLock
*/
class JUCE_API  Thread
{
public:

    /**
        Creates a thread.

        When first created, the thread is not running. Use the startThread()
        method to start it.
    */
    Thread (const String& threadName);

    /** Destructor.

        Deleting a Thread object that is running will only give the thread a
        brief opportunity to stop itself cleanly, so it's recommended that you
        should always call stopThread() with a decent timeout before deleting,
        to avoid the thread being forcibly killed (which is a Bad Thing).
    */
    virtual ~Thread();

    /** Must be implemented to perform the thread's actual code.

        Remember that the thread must regularly check the threadShouldExit()
        method whilst running, and if this returns true it should return from
        the run() method as soon as possible to avoid being forcibly killed.

        @see threadShouldExit, startThread
    */
    virtual void run() = 0;

    // Thread control functions..

    /** Starts the thread running.

        This will start the thread's run() method.
        (if it's already started, startThread() won't do anything).

        @see stopThread
    */
    void startThread() throw();

    /** Starts the thread with a given priority.

        Launches the thread with a given priority, where 0 = lowest, 10 = highest.
        If the thread is already running, its priority will be changed.

        @see startThread, setPriority
    */
    void startThread (const int priority) throw();

    /** Attempts to stop the thread running.

        This method will cause the threadShouldExit() method to return true
        and call notify() in case the thread is currently waiting.

        Hopefully the thread will then respond to this by exiting cleanly, and
        the stopThread method will wait for a given time-period for this to
        happen.

        If the thread is stuck and fails to respond after the time-out, it gets
        forcibly killed, which is a very bad thing to happen, as it could still
        be holding locks, etc. which are needed by other parts of your program.

        @param timeOutMilliseconds  The number of milliseconds to wait for the
                                    thread to finish before killing it by force. A negative
                                    value in here will wait forever.
        @see signalThreadShouldExit, threadShouldExit, waitForThreadToExit, isThreadRunning
    */
    void stopThread (const int timeOutMilliseconds) throw();

    /** Returns true if the thread is currently active */
    bool isThreadRunning() const throw();

    /** Sets a flag to tell the thread it should stop.

        Calling this means that the threadShouldExit() method will then return true.
        The thread should be regularly checking this to see whether it should exit.

        @see threadShouldExit
        @see waitForThreadToExit
    */
    void signalThreadShouldExit() throw();

    /** Checks whether the thread has been told to stop running.

        Threads need to check this regularly, and if it returns true, they should
        return from their run() method at the first possible opportunity.

        @see signalThreadShouldExit
    */
    inline bool threadShouldExit() const throw()  { return threadShouldExit_; }

    /** Waits for the thread to stop.

        This will waits until isThreadRunning() is false or until a timeout expires.

        @param timeOutMilliseconds  the time to wait, in milliseconds. If this value
                                    is less than zero, it will wait forever.
        @returns    true if the thread exits, or false if the timeout expires first.
    */
    bool waitForThreadToExit (const int timeOutMilliseconds) const throw();

    /** Changes the thread's priority.
        May return false if for some reason the priority can't be changed.

        @param priority     the new priority, in the range 0 (lowest) to 10 (highest). A priority
                            of 5 is normal.
    */
    bool setPriority (const int priority) throw();

    /** Changes the priority of the caller thread.

        Similar to setPriority(), but this static method acts on the caller thread.
        May return false if for some reason the priority can't be changed.

        @see setPriority
    */
    static bool setCurrentThreadPriority (const int priority) throw();

    /** Sets the affinity mask for the thread.

        This will only have an effect next time the thread is started - i.e. if the
        thread is already running when called, it'll have no effect.

        @see setCurrentThreadAffinityMask
    */
    void setAffinityMask (const uint32 affinityMask) throw();

    /** Changes the affinity mask for the caller thread.

        This will change the affinity mask for the thread that calls this static method.

        @see setAffinityMask
    */
    static void setCurrentThreadAffinityMask (const uint32 affinityMask) throw();

    // this can be called from any thread that needs to pause..
    static void JUCE_CALLTYPE sleep (int milliseconds) throw();

    /** Yields the calling thread's current time-slot. */
    static void JUCE_CALLTYPE yield() throw();

    /** Makes the thread wait for a notification.

        This puts the thread to sleep until either the timeout period expires, or
        another thread calls the notify() method to wake it up.

        @returns    true if the event has been signalled, false if the timeout expires.
    */
    bool wait (const int timeOutMilliseconds) const throw();

    /** Wakes up the thread.

        If the thread has called the wait() method, this will wake it up.

        @see wait
    */
    void notify() const throw();

    /** A value type used for thread IDs.
        @see getCurrentThreadId(), getThreadId()
    */
    typedef void* ThreadID;

    /** Returns an id that identifies the caller thread.

        To find the ID of a particular thread object, use getThreadId().

        @returns    a unique identifier that identifies the calling thread.
        @see getThreadId
    */
    static ThreadID getCurrentThreadId() throw();

    /** Finds the thread object that is currently running.

        Note that the main UI thread (or other non-Juce threads) don't have a Thread
        object associated with them, so this will return 0.
    */
    static Thread* getCurrentThread() throw();

    /** Returns the ID of this thread.

        That means the ID of this thread object - not of the thread that's calling the method.

        This can change when the thread is started and stopped, and will be invalid if the
        thread's not actually running.

        @see getCurrentThreadId
    */
    ThreadID getThreadId() const throw();

    /** Returns the name of the thread.

        This is the name that gets set in the constructor.
    */
    const String getThreadName() const throw()                      { return threadName_; }

    /** Returns the number of currently-running threads.

        @returns  the number of Thread objects known to be currently running.
        @see stopAllThreads
    */
    static int getNumRunningThreads() throw();

    /** Tries to stop all currently-running threads.

        This will attempt to stop all the threads known to be running at the moment.
    */
    static void stopAllThreads (const int timeoutInMillisecs) throw();

    juce_UseDebuggingNewOperator

private:
    const String threadName_;
    void* volatile threadHandle_;
    CriticalSection startStopLock;
    WaitableEvent startSuspensionEvent_, defaultEvent_;

    int threadPriority_;
    ThreadID threadId_;
    uint32 affinityMask_;
    bool volatile threadShouldExit_;

    friend void JUCE_API juce_threadEntryPoint (void*);
    static void threadEntryPoint (Thread* thread) throw();

    Thread (const Thread&);
    const Thread& operator= (const Thread&);
};

#endif   // __JUCE_THREAD_JUCEHEADER__
/********* End of inlined file: juce_Thread.h *********/

/**
    A critical section that allows multiple simultaneous readers.

    Features of this type of lock are:

    - Multiple readers can hold the lock at the same time, but only one writer
      can hold it at once.
    - Writers trying to gain the lock will be blocked until all readers and writers
      have released it
    - Readers trying to gain the lock while a writer is waiting to acquire it will be
      blocked until the writer has obtained and released it
    - If a thread already has a read lock and tries to obtain a write lock, it will succeed if
      there are no other readers
    - If a thread already has the write lock and tries to obtain a read lock, this will succeed.
    - Recursive locking is supported.

    @see ScopedReadLock, ScopedWriteLock, CriticalSection
*/
class JUCE_API  ReadWriteLock
{
public:

    /**
        Creates a ReadWriteLock object.
    */
    ReadWriteLock() throw();

    /** Destructor.

        If the object is deleted whilst locked, any subsequent behaviour
        is unpredictable.
    */
    ~ReadWriteLock() throw();

    /** Locks this object for reading.

        Multiple threads can simulaneously lock the object for reading, but if another
        thread has it locked for writing, then this will block until it releases the
        lock.

        @see exitRead, ScopedReadLock
    */
    void enterRead() const throw();

    /** Releases the read-lock.

        If the caller thread hasn't got the lock, this can have unpredictable results.

        If the enterRead() method has been called multiple times by the thread, each
        call must be matched by a call to exitRead() before other threads will be allowed
        to take over the lock.

        @see enterRead, ScopedReadLock
    */
    void exitRead() const throw();

    /** Locks this object for writing.

        This will block until any other threads that have it locked for reading or
        writing have released their lock.

        @see exitWrite, ScopedWriteLock
    */
    void enterWrite() const throw();

    /** Tries to lock this object for writing.

        This is like enterWrite(), but doesn't block - it returns true if it manages
        to obtain the lock.

        @see enterWrite
    */
    bool tryEnterWrite() const throw();

    /** Releases the write-lock.

        If the caller thread hasn't got the lock, this can have unpredictable results.

        If the enterWrite() method has been called multiple times by the thread, each
        call must be matched by a call to exit() before other threads will be allowed
        to take over the lock.

        @see enterWrite, ScopedWriteLock
    */
    void exitWrite() const throw();

    juce_UseDebuggingNewOperator

private:

    CriticalSection accessLock;
    WaitableEvent waitEvent;
    mutable int numWaitingWriters, numWriters;
    mutable Thread::ThreadID writerThreadId;
    mutable Array <Thread::ThreadID> readerThreads;

    ReadWriteLock (const ReadWriteLock&);
    const ReadWriteLock& operator= (const ReadWriteLock&);
};

#endif   // __JUCE_READWRITELOCK_JUCEHEADER__
/********* End of inlined file: juce_ReadWriteLock.h *********/

#endif
#ifndef __JUCE_SCOPEDLOCK_JUCEHEADER__

#endif
#ifndef __JUCE_SCOPEDREADLOCK_JUCEHEADER__

/********* Start of inlined file: juce_ScopedReadLock.h *********/
#ifndef __JUCE_SCOPEDREADLOCK_JUCEHEADER__
#define __JUCE_SCOPEDREADLOCK_JUCEHEADER__

/**
    Automatically locks and unlocks a ReadWriteLock object.

    Use one of these as a local variable to control access to a ReadWriteLock.

    e.g. @code

    ReadWriteLock myLock;

    for (;;)
    {
        const ScopedReadLock myScopedLock (myLock);
        // myLock is now locked

        ...do some stuff...

        // myLock gets unlocked here.
    }
    @endcode

    @see ReadWriteLock, ScopedWriteLock
*/
class JUCE_API  ScopedReadLock
{
public:

    /** Creates a ScopedReadLock.

        As soon as it is created, this will call ReadWriteLock::enterRead(), and
        when the ScopedReadLock object is deleted, the ReadWriteLock will
        be unlocked.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen! Best just to use it
        as a local stack object, rather than creating one with the new() operator.
    */
    inline ScopedReadLock (const ReadWriteLock& lock) throw()       : lock_ (lock) { lock.enterRead(); }

    /** Destructor.

        The ReadWriteLock's exitRead() method will be called when the destructor is called.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen!
    */
    inline ~ScopedReadLock() throw()                                { lock_.exitRead(); }

private:

    const ReadWriteLock& lock_;

    ScopedReadLock (const ScopedReadLock&);
    const ScopedReadLock& operator= (const ScopedReadLock&);
};

#endif   // __JUCE_SCOPEDREADLOCK_JUCEHEADER__
/********* End of inlined file: juce_ScopedReadLock.h *********/

#endif
#ifndef __JUCE_SCOPEDTRYLOCK_JUCEHEADER__

/********* Start of inlined file: juce_ScopedTryLock.h *********/
#ifndef __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
#define __JUCE_SCOPEDTRYLOCK_JUCEHEADER__

/**
    Automatically tries to lock and unlock a CriticalSection object.

    Use one of these as a local variable to control access to a CriticalSection.

    e.g. @code

    CriticalSection myCriticalSection;

    for (;;)
    {
        const ScopedTryLock myScopedTryLock (myCriticalSection);

        // Unlike using a ScopedLock, this may fail to actually get the lock, so you
        // should test this with the isLocked() method before doing your thread-unsafe
        // action..
        if (myScopedTryLock.isLocked())
        {
           ...do some stuff...
        }
        else
        {
            ..our attempt at locking failed because another thread had already locked it..
        }

        // myCriticalSection gets unlocked here (if it was locked)
    }
    @endcode

    @see CriticalSection::tryEnter, ScopedLock, ScopedUnlock, ScopedReadLock
*/
class JUCE_API  ScopedTryLock
{
public:

    /** Creates a ScopedTryLock.

        As soon as it is created, this will try to lock the CriticalSection, and
        when the ScopedTryLock object is deleted, the CriticalSection will
        be unlocked if the lock was successful.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen! Best just to use it
        as a local stack object, rather than creating one with the new() operator.
    */
    inline ScopedTryLock (const CriticalSection& lock) throw()      : lock_ (lock), lockWasSuccessful (lock.tryEnter()) {}

    /** Destructor.

        The CriticalSection will be unlocked (if locked) when the destructor is called.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen!
    */
    inline ~ScopedTryLock() throw()                                 { if (lockWasSuccessful) lock_.exit(); }

    /** Lock state

    @return True if the CriticalSection is locked.
    */
    bool isLocked() const throw()                                   { return lockWasSuccessful; }

private:

    const CriticalSection& lock_;
    const bool lockWasSuccessful;

    ScopedTryLock (const ScopedTryLock&);
    const ScopedTryLock& operator= (const ScopedTryLock&);
};

#endif   // __JUCE_SCOPEDTRYLOCK_JUCEHEADER__
/********* End of inlined file: juce_ScopedTryLock.h *********/

#endif
#ifndef __JUCE_SCOPEDWRITELOCK_JUCEHEADER__

/********* Start of inlined file: juce_ScopedWriteLock.h *********/
#ifndef __JUCE_SCOPEDWRITELOCK_JUCEHEADER__
#define __JUCE_SCOPEDWRITELOCK_JUCEHEADER__

/**
    Automatically locks and unlocks a ReadWriteLock object.

    Use one of these as a local variable to control access to a ReadWriteLock.

    e.g. @code

    ReadWriteLock myLock;

    for (;;)
    {
        const ScopedWriteLock myScopedLock (myLock);
        // myLock is now locked

        ...do some stuff...

        // myLock gets unlocked here.
    }
    @endcode

    @see ReadWriteLock, ScopedReadLock
*/
class JUCE_API  ScopedWriteLock
{
public:

    /** Creates a ScopedWriteLock.

        As soon as it is created, this will call ReadWriteLock::enterWrite(), and
        when the ScopedWriteLock object is deleted, the ReadWriteLock will
        be unlocked.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen! Best just to use it
        as a local stack object, rather than creating one with the new() operator.
    */
    inline ScopedWriteLock (const ReadWriteLock& lock) throw()       : lock_ (lock) { lock.enterWrite(); }

    /** Destructor.

        The ReadWriteLock's exitWrite() method will be called when the destructor is called.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen!
    */
    inline ~ScopedWriteLock() throw()                                { lock_.exitWrite(); }

private:

    const ReadWriteLock& lock_;

    ScopedWriteLock (const ScopedWriteLock&);
    const ScopedWriteLock& operator= (const ScopedWriteLock&);
};

#endif   // __JUCE_SCOPEDWRITELOCK_JUCEHEADER__
/********* End of inlined file: juce_ScopedWriteLock.h *********/

#endif
#ifndef __JUCE_THREAD_JUCEHEADER__

#endif
#ifndef __JUCE_THREADPOOL_JUCEHEADER__

/********* Start of inlined file: juce_ThreadPool.h *********/
#ifndef __JUCE_THREADPOOL_JUCEHEADER__
#define __JUCE_THREADPOOL_JUCEHEADER__

class ThreadPool;
class ThreadPoolThread;

/**
    A task that is executed by a ThreadPool object.

    A ThreadPool keeps a list of ThreadPoolJob objects which are executed by
    its threads.

    The runJob() method needs to be implemented to do the task, and if the code that
    does the work takes a significant time to run, it must keep checking the shouldExit()
    method to see if something is trying to interrupt the job. If shouldExit() returns
    true, the runJob() method must return immediately.

    @see ThreadPool, Thread
*/
class JUCE_API  ThreadPoolJob
{
public:

    /** Creates a thread pool job object.

        After creating your job, add it to a thread pool with ThreadPool::addJob().
    */
    ThreadPoolJob (const String& name);

    /** Destructor. */
    virtual ~ThreadPoolJob();

    /** Returns the name of this job.
        @see setJobName
    */
    const String getJobName() const;

    /** Changes the job's name.
        @see getJobName
    */
    void setJobName (const String& newName);

    /** These are the values that can be returned by the runJob() method.
    */
    enum JobStatus
    {
        jobHasFinished = 0,     /**< indicates that the job has finished and can be
                                     removed from the pool. */

        jobHasFinishedAndShouldBeDeleted,  /**< indicates that the job has finished and that it
                                                should be automatically deleted by the pool. */

        jobNeedsRunningAgain    /**< indicates that the job would like to be called
                                     again when a thread is free. */
    };

    /** Peforms the actual work that this job needs to do.

        Your subclass must implement this method, in which is does its work.

        If the code in this method takes a significant time to run, it must repeatedly check
        the shouldExit() method to see if something is trying to interrupt the job.
        If shouldExit() ever returns true, the runJob() method must return immediately.

        If this method returns jobHasFinished, then the job will be removed from the pool
        immediately. If it returns jobNeedsRunningAgain, then the job will be left in the
        pool and will get a chance to run again as soon as a thread is free.

        @see shouldExit()
    */
    virtual JobStatus runJob() = 0;

    /** Returns true if this job is currently running its runJob() method. */
    bool isRunning() const throw()       { return isActive; }

    /** Returns true if something is trying to interrupt this job and make it stop.

        Your runJob() method must call this whenever it gets a chance, and if it ever
        returns true, the runJob() method must return immediately.

        @see signalJobShouldExit()
    */
    bool shouldExit() const throw()      { return shouldStop; }

    /** Calling this will cause the shouldExit() method to return true, and the job
        should (if it's been implemented correctly) stop as soon as possible.

        @see shouldExit()
    */
    void signalJobShouldExit();

    juce_UseDebuggingNewOperator

private:
    friend class ThreadPool;
    friend class ThreadPoolThread;
    String jobName;
    ThreadPool* pool;
    bool shouldStop, isActive, shouldBeDeleted;
};

/**
    A set of threads that will run a list of jobs.

    When a ThreadPoolJob object is added to the ThreadPool's list, its run() method
    will be called by the next pooled thread that becomes free.

    @see ThreadPoolJob, Thread
*/
class JUCE_API  ThreadPool
{
public:

    /** Creates a thread pool.

        Once you've created a pool, you can give it some things to do with the addJob()
        method.

        @param numberOfThreads              the maximum number of actual threads to run.
        @param startThreadsOnlyWhenNeeded   if this is true, then no threads will be started
                                            until there are some jobs to run. If false, then
                                            all the threads will be fired-up immediately so that
                                            they're ready for action
        @param stopThreadsWhenNotUsedTimeoutMs  if this timeout is > 0, then if any threads have been
                                            inactive for this length of time, they will automatically
                                            be stopped until more jobs come along and they're needed
    */
    ThreadPool (const int numberOfThreads,
                const bool startThreadsOnlyWhenNeeded = true,
                const int stopThreadsWhenNotUsedTimeoutMs = 5000);

    /** Destructor.

        This will attempt to remove all the jobs before deleting, but if you want to
        specify a timeout, you should call removeAllJobs() explicitly before deleting
        the pool.
    */
    ~ThreadPool();

    /** Adds a job to the queue.

        Once a job has been added, then the next time a thread is free, it will run
        the job's ThreadPoolJob::runJob() method. Depending on the return value of the
        runJob() method, the pool will either remove the job from the pool or add it to
        the back of the queue to be run again.
    */
    void addJob (ThreadPoolJob* const job);

    /** Tries to remove a job from the pool.

        If the job isn't yet running, this will simply remove it. If it is running, it
        will wait for it to finish.

        If the timeout period expires before the job finishes running, then the job will be
        left in the pool and this will return false. It returns true if the job is sucessfully
        stopped and removed.

        @param job                  the job to remove
        @param interruptIfRunning   if true, then if the job is currently busy, its
                                    ThreadPoolJob::signalJobShouldExit() method will be called to try
                                    to interrupt it. If false, then if the job will be allowed to run
                                    until it stops normally (or the timeout expires)
        @param timeOutMilliseconds  the length of time this method should wait for the job to finish
                                    before giving up and returning false
    */
    bool removeJob (ThreadPoolJob* const job,
                    const bool interruptIfRunning,
                    const int timeOutMilliseconds);

    /** Tries clear all jobs from the pool.

        @param interruptRunningJobs if true, then all running jobs will have their ThreadPoolJob::signalJobShouldExit()
                                    methods called to try to interrupt them
        @param timeOutMilliseconds  the length of time this method should wait for all the jobs to finish
                                    before giving up and returning false
        @param deleteInactiveJobs   if true, any jobs that aren't currently running will be deleted. If false,
                                    they will simply be removed from the pool. Jobs that are already running when
                                    this method is called can choose whether they should be deleted by
                                    returning jobHasFinishedAndShouldBeDeleted from their runJob() method.
        @returns    true if all jobs are successfully stopped and removed; false if the timeout period
                    expires while waiting for them to stop
    */
    bool removeAllJobs (const bool interruptRunningJobs,
                        const int timeOutMilliseconds,
                        const bool deleteInactiveJobs = false);

    /** Returns the number of jobs currently running or queued.
    */
    int getNumJobs() const throw();

    /** Returns one of the jobs in the queue.

        Note that this can be a very volatile list as jobs might be continuously getting shifted
        around in the list, and this method may return 0 if the index is currently out-of-range.
    */
    ThreadPoolJob* getJob (const int index) const;

    /** Returns true if the given job is currently queued or running.

        @see isJobRunning()
    */
    bool contains (const ThreadPoolJob* const job) const throw();

    /** Returns true if the given job is currently being run by a thread.
    */
    bool isJobRunning (const ThreadPoolJob* const job) const;

    /** Waits until a job has finished running and has been removed from the pool.

        This will wait until the job is no longer in the pool - i.e. until its
        runJob() method returns ThreadPoolJob::jobHasFinished.

        If the timeout period expires before the job finishes, this will return false;
        it returns true if the job has finished successfully.
    */
    bool waitForJobToFinish (const ThreadPoolJob* const job,
                             const int timeOutMilliseconds) const;

    /** Returns a list of the names of all the jobs currently running or queued.

        If onlyReturnActiveJobs is true, only the ones currently running are returned.
    */
    const StringArray getNamesOfAllJobs (const bool onlyReturnActiveJobs) const;

    /** Changes the priority of all the threads.

        This will call Thread::setPriority() for each thread in the pool.
        May return false if for some reason the priority can't be changed.
    */
    bool setThreadPriorities (const int newPriority);

    juce_UseDebuggingNewOperator

private:
    const int numThreads, threadStopTimeout;
    int priority;
    Thread** threads;
    VoidArray jobs;

    CriticalSection lock;
    uint32 lastJobEndTime;

    friend class ThreadPoolThread;
    bool runNextJob();

    ThreadPool (const ThreadPool&);
    const ThreadPool& operator= (const ThreadPool&);
};

#endif   // __JUCE_THREADPOOL_JUCEHEADER__
/********* End of inlined file: juce_ThreadPool.h *********/

#endif
#ifndef __JUCE_TIMESLICETHREAD_JUCEHEADER__

/********* Start of inlined file: juce_TimeSliceThread.h *********/
#ifndef __JUCE_TIMESLICETHREAD_JUCEHEADER__
#define __JUCE_TIMESLICETHREAD_JUCEHEADER__

/**
    Used by the TimeSliceThread class.

    To register your class with a TimeSliceThread, derive from this class and
    use the TimeSliceThread::addTimeSliceClient() method to add it to the list.

    Make sure you always call TimeSliceThread::removeTimeSliceClient() before
    deleting your client!

    @see TimeSliceThread
*/
class JUCE_API  TimeSliceClient
{
public:
    /** Destructor. */
    virtual ~TimeSliceClient()   {}

    /** Called back by a TimeSliceThread.

        When you register this class with it, a TimeSliceThread will repeatedly call
        this method.

        The implementation of this method should use its time-slice to do something that's
        quick - never block for longer than absolutely necessary.

        @returns    Your method should return true if it needs more time, or false if it's
                    not too busy and doesn't need calling back urgently. If all the thread's
                    clients indicate that they're not busy, then it'll save CPU by sleeping for
                    up to half a second in between callbacks. You can force the TimeSliceThread
                    to wake up and poll again immediately by calling its notify() method.
    */
    virtual bool useTimeSlice() = 0;
};

/**
    A thread that keeps a list of clients, and calls each one in turn, giving them
    all a chance to run some sort of short task.

    @see TimeSliceClient, Thread
*/
class JUCE_API  TimeSliceThread   : public Thread
{
public:

    /**
        Creates a TimeSliceThread.

        When first created, the thread is not running. Use the startThread()
        method to start it.
    */
    TimeSliceThread (const String& threadName);

    /** Destructor.

        Deleting a Thread object that is running will only give the thread a
        brief opportunity to stop itself cleanly, so it's recommended that you
        should always call stopThread() with a decent timeout before deleting,
        to avoid the thread being forcibly killed (which is a Bad Thing).
    */
    ~TimeSliceThread();

    /** Adds a client to the list.

        The client's callbacks will start immediately (possibly before the method
        has returned).
    */
    void addTimeSliceClient (TimeSliceClient* const client);

    /** Removes a client from the list.

        This method will make sure that all callbacks to the client have completely
        finished before the method returns.
    */
    void removeTimeSliceClient (TimeSliceClient* const client);

    /** Returns the number of registered clients. */
    int getNumClients() const throw();

    /** Returns one of the registered clients. */
    TimeSliceClient* getClient (const int index) const throw();

    /** @internal */
    void run();

    juce_UseDebuggingNewOperator

private:
    CriticalSection callbackLock, listLock;
    Array <TimeSliceClient*> clients;
    int index;
    TimeSliceClient* clientBeingCalled;
    bool clientsChanged;

    TimeSliceThread (const TimeSliceThread&);
    const TimeSliceThread& operator= (const TimeSliceThread&);
};

#endif   // __JUCE_TIMESLICETHREAD_JUCEHEADER__
/********* End of inlined file: juce_TimeSliceThread.h *********/

#endif
#ifndef __JUCE_WAITABLEEVENT_JUCEHEADER__

#endif

#endif
/********* End of inlined file: juce_core_includes.h *********/

// if you're compiling a command-line app, you might want to just include the core headers,
// so you can set this macro before including juce.h
#if ! JUCE_ONLY_BUILD_CORE_LIBRARY

/********* Start of inlined file: juce_app_includes.h *********/
#ifndef __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__
#define __JUCE_JUCE_APP_INCLUDES_INCLUDEFILES__

#ifndef __JUCE_APPLICATION_JUCEHEADER__

/********* Start of inlined file: juce_Application.h *********/
#ifndef __JUCE_APPLICATION_JUCEHEADER__
#define __JUCE_APPLICATION_JUCEHEADER__

/********* Start of inlined file: juce_ApplicationCommandTarget.h *********/
#ifndef __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__
#define __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__

/********* Start of inlined file: juce_Component.h *********/
#ifndef __JUCE_COMPONENT_JUCEHEADER__
#define __JUCE_COMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_MouseCursor.h *********/
#ifndef __JUCE_MOUSECURSOR_JUCEHEADER__
#define __JUCE_MOUSECURSOR_JUCEHEADER__

class Image;
class RefCountedMouseCursor;
class ComponentPeer;
class Component;

/**
    Represents a mouse cursor image.

    This object can either be used to represent one of the standard mouse
    cursor shapes, or a custom one generated from an image.
*/
class JUCE_API  MouseCursor
{
public:

    /** The set of available standard mouse cursors. */
    enum StandardCursorType
    {
        NoCursor = 0,                   /**< An invisible cursor. */
        NormalCursor,                   /**< The stardard arrow cursor. */

        WaitCursor,                     /**< The normal hourglass or spinning-beachball 'busy' cursor. */
        IBeamCursor,                    /**< A vertical I-beam for positioning within text. */
        CrosshairCursor,                /**< A pair of crosshairs. */
        CopyingCursor,                  /**< The normal arrow cursor, but with a "+" on it to indicate
                                             that you're dragging a copy of something. */

        PointingHandCursor,             /**< A hand with a pointing finger, for clicking on web-links. */
        DraggingHandCursor,             /**< An open flat hand for dragging heavy objects around. */

        LeftRightResizeCursor,          /**< An arrow pointing left and right. */
        UpDownResizeCursor,             /**< an arrow pointing up and down. */
        UpDownLeftRightResizeCursor,    /**< An arrow pointing up, down, left and right. */

        TopEdgeResizeCursor,            /**< A platform-specific cursor for resizing the top-edge of a window. */
        BottomEdgeResizeCursor,         /**< A platform-specific cursor for resizing the bottom-edge of a window. */
        LeftEdgeResizeCursor,           /**< A platform-specific cursor for resizing the left-edge of a window. */
        RightEdgeResizeCursor,          /**< A platform-specific cursor for resizing the right-edge of a window. */
        TopLeftCornerResizeCursor,      /**< A platform-specific cursor for resizing the top-left-corner of a window. */
        TopRightCornerResizeCursor,     /**< A platform-specific cursor for resizing the top-right-corner of a window. */
        BottomLeftCornerResizeCursor,   /**< A platform-specific cursor for resizing the bottom-left-corner of a window. */
        BottomRightCornerResizeCursor   /**< A platform-specific cursor for resizing the bottom-right-corner of a window. */
    };

    /** Creates the standard arrow cursor. */
    MouseCursor() throw();

    /** Creates one of the standard mouse cursor */
    MouseCursor (const StandardCursorType type) throw();

    /** Creates a custom cursor from an image.

        @param image    the image to use for the cursor - if this is bigger than the
                        system can manage, it might get scaled down first, and might
                        also have to be turned to black-and-white if it can't do colour
                        cursors.
        @param hotSpotX the x position of the cursor's hotspot within the image
        @param hotSpotY the y position of the cursor's hotspot within the image
    */
    MouseCursor (Image& image,
                 const int hotSpotX,
                 const int hotSpotY) throw();

    /** Creates a copy of another cursor object. */
    MouseCursor (const MouseCursor& other) throw();

    /** Copies this cursor from another object. */
    const MouseCursor& operator= (const MouseCursor& other) throw();

    /** Destructor. */
    ~MouseCursor() throw();

    /** Checks whether two mouse cursors are the same.

        For custom cursors, two cursors created from the same image won't be
        recognised as the same, only MouseCursor objects that have been
        copied from the same object.
    */
    bool operator== (const MouseCursor& other) const throw();

    /** Checks whether two mouse cursors are the same.

        For custom cursors, two cursors created from the same image won't be
        recognised as the same, only MouseCursor objects that have been
        copied from the same object.
    */
    bool operator!= (const MouseCursor& other) const throw();

    /** Makes the system show its default 'busy' cursor.

        This will turn the system cursor to an hourglass or spinning beachball
        until the next time the mouse is moved, or hideWaitCursor() is called.

        This is handy if the message loop is about to block for a couple of
        seconds while busy and you want to give the user feedback about this.

        @see MessageManager::setTimeBeforeShowingWaitCursor
    */
    static void showWaitCursor() throw();

    /** If showWaitCursor has been called, this will return the mouse to its
        normal state.

        This will look at what component is under the mouse, and update the
        cursor to be the correct one for that component.

        @see showWaitCursor
    */
    static void hideWaitCursor() throw();

    juce_UseDebuggingNewOperator

private:
    RefCountedMouseCursor* cursorHandle;

    friend class Component;

    void showInWindow (ComponentPeer* window) const throw();
    void showInAllWindows() const throw();

    void* getHandle() const throw();
};

#endif   // __JUCE_MOUSECURSOR_JUCEHEADER__
/********* End of inlined file: juce_MouseCursor.h *********/

/********* Start of inlined file: juce_MouseListener.h *********/
#ifndef __JUCE_MOUSELISTENER_JUCEHEADER__
#define __JUCE_MOUSELISTENER_JUCEHEADER__

/********* Start of inlined file: juce_MouseEvent.h *********/
#ifndef __JUCE_MOUSEEVENT_JUCEHEADER__
#define __JUCE_MOUSEEVENT_JUCEHEADER__

class Component;

/********* Start of inlined file: juce_ModifierKeys.h *********/
#ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__
#define __JUCE_MODIFIERKEYS_JUCEHEADER__

/**
    Represents the state of the mouse buttons and modifier keys.

    This is used both by mouse events and by KeyPress objects to describe
    the state of keys such as shift, control, alt, etc.

    @see KeyPress, MouseEvent::mods
*/
class JUCE_API  ModifierKeys
{
public:

    /** Creates a ModifierKeys object from a raw set of flags.

        @param flags to represent the keys that are down
        @see    shiftModifier, ctrlModifier, altModifier, leftButtonModifier,
                rightButtonModifier, commandModifier, popupMenuClickModifier
    */
    ModifierKeys (const int flags = 0) throw();

    /** Creates a copy of another object. */
    ModifierKeys (const ModifierKeys& other) throw();

    /** Copies this object from another one. */
    const ModifierKeys& operator= (const ModifierKeys& other) throw();

    /** Checks whether the 'command' key flag is set (or 'ctrl' on Windows/Linux).

        This is a platform-agnostic way of checking for the operating system's
        preferred command-key modifier - so on the Mac it tests for the Apple key, on
        Windows/Linux, it's actually checking for the CTRL key.
    */
    inline bool isCommandDown() const throw()           { return (flags & commandModifier) != 0; }

    /** Checks whether the user is trying to launch a pop-up menu.

        This checks for platform-specific modifiers that might indicate that the user
        is following the operating system's normal method of showing a pop-up menu.

        So on Windows/Linux, this method is really testing for a right-click.
        On the Mac, it tests for either the CTRL key being down, or a right-click.
    */
    inline bool isPopupMenu() const throw()             { return (flags & popupMenuClickModifier) != 0; }

    /** Checks whether the flag is set for the left mouse-button. */
    inline bool isLeftButtonDown() const throw()        { return (flags & leftButtonModifier) != 0; }

    /** Checks whether the flag is set for the right mouse-button.

        Note that for detecting popup-menu clicks, you should be using isPopupMenu() instead, as
        this is platform-independent (and makes your code more explanatory too).
    */
    inline bool isRightButtonDown() const throw()       { return (flags & rightButtonModifier) != 0; }

    inline bool isMiddleButtonDown() const throw()      { return (flags & middleButtonModifier) != 0; }

    /** Tests for any of the mouse-button flags. */
    inline bool isAnyMouseButtonDown() const throw()    { return (flags & allMouseButtonModifiers) != 0; }

    /** Tests for any of the modifier key flags. */
    inline bool isAnyModifierKeyDown() const throw()    { return (flags & (shiftModifier | ctrlModifier | altModifier | commandModifier)) != 0; }

    /** Checks whether the shift key's flag is set. */
    inline bool isShiftDown() const throw()             { return (flags & shiftModifier) != 0; }

    /** Checks whether the CTRL key's flag is set.

        Remember that it's better to use the platform-agnostic routines to test for command-key and
        popup-menu modifiers.

        @see isCommandDown, isPopupMenu
    */
    inline bool isCtrlDown() const throw()              { return (flags & ctrlModifier) != 0; }

    /** Checks whether the shift key's flag is set. */
    inline bool isAltDown() const throw()               { return (flags & altModifier) != 0; }

    /** Flags that represent the different keys. */
    enum Flags
    {
        /** Shift key flag. */
        shiftModifier                           = 1,

        /** CTRL key flag. */
        ctrlModifier                            = 2,

        /** ALT key flag. */
        altModifier                             = 4,

        /** Left mouse button flag. */
        leftButtonModifier                      = 16,

        /** Right mouse button flag. */
        rightButtonModifier                     = 32,

        /** Middle mouse button flag. */
        middleButtonModifier                    = 64,

#if JUCE_MAC
        /** Command key flag - on windows this is the same as the CTRL key flag. */
        commandModifier                         = 8,

        /** Popup menu flag - on windows this is the same as rightButtonModifier, on the
            Mac it's the same as (rightButtonModifier | ctrlModifier). */
        popupMenuClickModifier                  = rightButtonModifier | ctrlModifier,
#else
        /** Command key flag - on windows this is the same as the CTRL key flag. */
        commandModifier                         = ctrlModifier,

        /** Popup menu flag - on windows this is the same as rightButtonModifier, on the
            Mac it's the same as (rightButtonModifier | ctrlModifier). */
        popupMenuClickModifier                  = rightButtonModifier,
#endif

        /** Represents a combination of all the shift, alt, ctrl and command key modifiers. */
        allKeyboardModifiers                    = shiftModifier | ctrlModifier | altModifier | commandModifier,

        /** Represents a combination of all the mouse buttons at once. */
        allMouseButtonModifiers                 = leftButtonModifier | rightButtonModifier | middleButtonModifier,
    };

    /** Returns the raw flags for direct testing. */
    inline int getRawFlags() const throw()                              { return flags; }

    /** Tests a combination of flags and returns true if any of them are set. */
    inline bool testFlags (const int flagsToTest) const throw()         { return (flags & flagsToTest) != 0; }

    /** Creates a ModifierKeys object to represent the last-known state of the
        keyboard and mouse buttons.

        @see getCurrentModifiersRealtime
    */
    static const ModifierKeys getCurrentModifiers() throw();

    /** Creates a ModifierKeys object to represent the current state of the
        keyboard and mouse buttons.

        This isn't often needed and isn't recommended, but will actively check all the
        mouse and key states rather than just returning their last-known state like
        getCurrentModifiers() does.

        This is only needed in special circumstances for up-to-date modifier information
        at times when the app's event loop isn't running normally.
    */
    static const ModifierKeys getCurrentModifiersRealtime() throw();

private:

    int flags;

    static int currentModifierFlags;

    friend class ComponentPeer;
    static void updateCurrentModifiers() throw();
};

#endif   // __JUCE_MODIFIERKEYS_JUCEHEADER__
/********* End of inlined file: juce_ModifierKeys.h *********/

/**
    Contains position and status information about a mouse event.

    @see MouseListener, Component::mouseMove, Component::mouseEnter, Component::mouseExit,
         Component::mouseDown, Component::mouseUp, Component::mouseDrag
*/
class JUCE_API  MouseEvent
{
public:

    /** Creates a MouseEvent.

        Normally an application will never need to use this.

        @param x                the x position of the mouse, relative to the component that is passed-in
        @param y                the y position of the mouse, relative to the component that is passed-in
        @param modifiers        the key modifiers at the time of the event
        @param originator       the component that the mouse event applies to
        @param eventTime        the time the event happened
        @param mouseDownX       the x position of the corresponding mouse-down event (relative to the component that is passed-in).
                                If there isn't a corresponding mouse-down (e.g. for a mouse-move), this will just be
                                the same as the current mouse-x position.
        @param mouseDownY       the y position of the corresponding mouse-down event (relative to the component that is passed-in)
                                If there isn't a corresponding mouse-down (e.g. for a mouse-move), this will just be
                                the same as the current mouse-y position.
        @param mouseDownTime    the time at which the corresponding mouse-down event happened
                                If there isn't a corresponding mouse-down (e.g. for a mouse-move), this will just be
                                the same as the current mouse-event time.
        @param numberOfClicks   how many clicks, e.g. a double-click event will be 2, a triple-click will be 3, etc
        @param mouseWasDragged  whether the mouse has been dragged significantly since the previous mouse-down
    */
    MouseEvent (const int x, const int y,
                const ModifierKeys& modifiers,
                Component* const originator,
                const Time& eventTime,
                const int mouseDownX,
                const int mouseDownY,
                const Time& mouseDownTime,
                const int numberOfClicks,
                const bool mouseWasDragged) throw();

    /** Destructor. */
    ~MouseEvent() throw();

    /** The x-position of the mouse when the event occurred.

        This value is relative to the top-left of the component to which the
        event applies (as indicated by the MouseEvent::eventComponent field).
    */
    int x;

    /** The y-position of the mouse when the event occurred.

        This value is relative to the top-left of the component to which the
        event applies (as indicated by the MouseEvent::eventComponent field).
    */
    int y;

    /** The key modifiers associated with the event.

        This will let you find out which mouse buttons were down, as well as which
        modifier keys were held down.

        When used for mouse-up events, this will indicate the state of the mouse buttons
        just before they were released, so that you can tell which button they let go of.
    */
    ModifierKeys mods;

    /** The component that this event applies to.

        This is usually the component that the mouse was over at the time, but for mouse-drag
        events the mouse could actually be over a different component and the events are
        still sent to the component that the button was originally pressed on.

        The x and y member variables are relative to this component's position.

        If you use getEventRelativeTo() to retarget this object to be relative to a different
        component, this pointer will be updated, but originalComponent remains unchanged.

        @see originalComponent
    */
    Component* eventComponent;

    /** The component that the event first occurred on.

        If you use getEventRelativeTo() to retarget this object to be relative to a different
        component, this value remains unchanged to indicate the first component that received it.

        @see eventComponent
    */
    Component* originalComponent;

    /** The time that this mouse-event occurred.
    */
    Time eventTime;

    /** Returns the x co-ordinate of the last place that a mouse was pressed.

        The co-ordinate is relative to the component specified in MouseEvent::component.

        @see getDistanceFromDragStart, getDistanceFromDragStartX, mouseWasClicked
    */
    int getMouseDownX() const throw();

    /** Returns the y co-ordinate of the last place that a mouse was pressed.

        The co-ordinate is relative to the component specified in MouseEvent::component.

        @see getDistanceFromDragStart, getDistanceFromDragStartX, mouseWasClicked
    */
    int getMouseDownY() const throw();

    /** Returns the straight-line distance between where the mouse is now and where it
        was the last time the button was pressed.

        This is quite handy for things like deciding whether the user has moved far enough
        for it to be considered a drag operation.

        @see getDistanceFromDragStartX
    */
    int getDistanceFromDragStart() const throw();

    /** Returns the difference between the mouse's current x postion and where it was
        when the button was last pressed.

        @see getDistanceFromDragStart
    */
    int getDistanceFromDragStartX() const throw();

    /** Returns the difference between the mouse's current y postion and where it was
        when the button was last pressed.

        @see getDistanceFromDragStart
    */
    int getDistanceFromDragStartY() const throw();

    /** Returns true if the mouse has just been clicked.

        Used in either your mouseUp() or mouseDrag() methods, this will tell you whether
        the user has dragged the mouse more than a few pixels from the place where the
        mouse-down occurred.

        Once they have dragged it far enough for this method to return false, it will continue
        to return false until the mouse-up, even if they move the mouse back to the same
        position where they originally pressed it. This means that it's very handy for
        objects that can either be clicked on or dragged, as you can use it in the mouseDrag()
        callback to ignore any small movements they might make while clicking.

        @returns    true if the mouse wasn't dragged by more than a few pixels between
                    the last time the button was pressed and released.
    */
    bool mouseWasClicked() const throw();

    /** For a click event, the number of times the mouse was clicked in succession.

        So for example a double-click event will return 2, a triple-click 3, etc.
    */
    int getNumberOfClicks() const throw()                               { return numberOfClicks; }

    /** Returns the time that the mouse button has been held down for.

        If called from a mouseDrag or mouseUp callback, this will return the
        number of milliseconds since the corresponding mouseDown event occurred.
        If called in other contexts, e.g. a mouseMove, then the returned value
        may be 0 or an undefined value.
    */
    int getLengthOfMousePress() const throw();

    /** Returns the mouse x position of this event, in global screen co-ordinates.

        The co-ordinates are relative to the top-left of the main monitor.

        @see getMouseDownScreenX, Desktop::getMousePosition
    */
    int getScreenX() const throw();

    /** Returns the mouse y position of this event, in global screen co-ordinates.

        The co-ordinates are relative to the top-left of the main monitor.

        @see getMouseDownScreenY, Desktop::getMousePosition
    */
    int getScreenY() const throw();

    /** Returns the x co-ordinate at which the mouse button was last pressed.

        The co-ordinates are relative to the top-left of the main monitor.

        @see getScreenX, Desktop::getMousePosition
    */
    int getMouseDownScreenX() const throw();

    /** Returns the y co-ordinate at which the mouse button was last pressed.

        The co-ordinates are relative to the top-left of the main monitor.

        @see getScreenY, Desktop::getMousePosition
    */
    int getMouseDownScreenY() const throw();

    /** Creates a version of this event that is relative to a different component.

        The x and y positions of the event that is returned will have been
        adjusted to be relative to the new component.
    */
    const MouseEvent getEventRelativeTo (Component* const otherComponent) const throw();

    /** Changes the application-wide setting for the double-click time limit.

        This is the maximum length of time between mouse-clicks for it to be
        considered a double-click. It's used by the Component class.

        @see getDoubleClickTimeout, MouseListener::mouseDoubleClick
    */
    static void setDoubleClickTimeout (const int timeOutMilliseconds) throw();

    /** Returns the application-wide setting for the double-click time limit.

        This is the maximum length of time between mouse-clicks for it to be
        considered a double-click. It's used by the Component class.

        @see setDoubleClickTimeout, MouseListener::mouseDoubleClick
    */
    static int getDoubleClickTimeout() throw();

    juce_UseDebuggingNewOperator

private:
    int mouseDownX, mouseDownY;
    Time mouseDownTime;
    int numberOfClicks;
    bool wasMovedSinceMouseDown;
};

#endif   // __JUCE_MOUSEEVENT_JUCEHEADER__
/********* End of inlined file: juce_MouseEvent.h *********/

/**
    A MouseListener can be registered with a component to receive callbacks
    about mouse events that happen to that component.

    @see Component::addMouseListener, Component::removeMouseListener
*/
class JUCE_API  MouseListener
{
public:
    /** Destructor. */
    virtual ~MouseListener()  {}

    /** Called when the mouse moves inside a component.

        If the mouse button isn't pressed and the mouse moves over a component,
        this will be called to let the component react to this.

        A component will always get a mouseEnter callback before a mouseMove.

        @param e    details about the position and status of the mouse event, including
                    the source component in which it occurred
        @see mouseEnter, mouseExit, mouseDrag, contains
    */
    virtual void mouseMove          (const MouseEvent& e);

    /** Called when the mouse first enters a component.

        If the mouse button isn't pressed and the mouse moves into a component,
        this will be called to let the component react to this.

        When the mouse button is pressed and held down while being moved in
        or out of a component, no mouseEnter or mouseExit callbacks are made - only
        mouseDrag messages are sent to the component that the mouse was originally
        clicked on, until the button is released.

        @param e    details about the position and status of the mouse event, including
                    the source component in which it occurred
        @see mouseExit, mouseDrag, mouseMove, contains
    */
    virtual void mouseEnter         (const MouseEvent& e);

    /** Called when the mouse moves out of a component.

        This will be called when the mouse moves off the edge of this
        component.

        If the mouse button was pressed, and it was then dragged off the
        edge of the component and released, then this callback will happen
        when the button is released, after the mouseUp callback.

        @param e    details about the position and status of the mouse event, including
                    the source component in which it occurred
        @see mouseEnter, mouseDrag, mouseMove, contains
    */
    virtual void mouseExit          (const MouseEvent& e);

    /** Called when a mouse button is pressed.

        The MouseEvent object passed in contains lots of methods for finding out
        which button was pressed, as well as which modifier keys (e.g. shift, ctrl)
        were held down at the time.

        Once a button is held down, the mouseDrag method will be called when the
        mouse moves, until the button is released.

        @param e    details about the position and status of the mouse event, including
                    the source component in which it occurred
        @see mouseUp, mouseDrag, mouseDoubleClick, contains
    */
    virtual void mouseDown          (const MouseEvent& e);

    /** Called when the mouse is moved while a button is held down.

        When a mouse button is pressed inside a component, that component
        receives mouseDrag callbacks each time the mouse moves, even if the
        mouse strays outside the component's bounds.

        @param e    details about the position and status of the mouse event, including
                    the source component in which it occurred
        @see mouseDown, mouseUp, mouseMove, contains, setDragRepeatInterval
    */
    virtual void mouseDrag          (const MouseEvent& e);

    /** Called when a mouse button is released.

        A mouseUp callback is sent to the component in which a button was pressed
        even if the mouse is actually over a different component when the
        button is released.

        The MouseEvent object passed in contains lots of methods for finding out
        which buttons were down just before they were released.

        @param e    details about the position and status of the mouse event, including
                    the source component in which it occurred
        @see mouseDown, mouseDrag, mouseDoubleClick, contains
    */
    virtual void mouseUp            (const MouseEvent& e);

    /** Called when a mouse button has been double-clicked on a component.

        The MouseEvent object passed in contains lots of methods for finding out
        which button was pressed, as well as which modifier keys (e.g. shift, ctrl)
        were held down at the time.

        @param e    details about the position and status of the mouse event, including
                    the source component in which it occurred
        @see mouseDown, mouseUp
    */
    virtual void mouseDoubleClick   (const MouseEvent& e);

    /** Called when the mouse-wheel is moved.

        This callback is sent to the component that the mouse is over when the
        wheel is moved.

        If not overridden, the component will forward this message to its parent, so
        that parent components can collect mouse-wheel messages that happen to
        child components which aren't interested in them.

        @param e    details about the position and status of the mouse event, including
                    the source component in which it occurred
        @param wheelIncrementX   the speed and direction of the horizontal scroll-wheel - a positive
                                 value means the wheel has been pushed to the right, negative means it
                                 was pushed to the left
        @param wheelIncrementY   the speed and direction of the vertical scroll-wheel - a positive
                                 value means the wheel has been pushed upwards, negative means it
                                 was pushed downwards
    */
    virtual void mouseWheelMove     (const MouseEvent& e,
                                     float wheelIncrementX,
                                     float wheelIncrementY);

private:
    // XXX Deprecated! The parameters for this method have changed to accommodate horizonatal scroll-wheels.
    // This line is here to cause a syntax error if you're trying to use the old-style definition, so
    // if that happens, update your code to use the new one above.
    virtual int mouseWheelMove (const MouseEvent&, float) { return 0; }
};

#endif   // __JUCE_MOUSELISTENER_JUCEHEADER__
/********* End of inlined file: juce_MouseListener.h *********/

/********* Start of inlined file: juce_ComponentListener.h *********/
#ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__
#define __JUCE_COMPONENTLISTENER_JUCEHEADER__

class Component;

/**
    Gets informed about changes to a component's hierarchy or position.

    To monitor a component for changes, register a subclass of ComponentListener
    with the component using Component::addComponentListener().

    Be sure to deregister listeners before you delete them!

    @see Component::addComponentListener, Component::removeComponentListener
*/
class JUCE_API  ComponentListener
{
public:
    /** Destructor. */
    virtual ~ComponentListener()  {}

    /** Called when the component's position or size changes.

        @param component    the component that was moved or resized
        @param wasMoved     true if the component's top-left corner has just moved
        @param wasResized   true if the component's width or height has just changed
        @see Component::setBounds, Component::resized, Component::moved
    */
    virtual void componentMovedOrResized (Component& component,
                                          bool wasMoved,
                                          bool wasResized);

    /** Called when the component is brought to the top of the z-order.

        @param component    the component that was moved
        @see Component::toFront, Component::broughtToFront
    */
    virtual void componentBroughtToFront (Component& component);

    /** Called when the component is made visible or invisible.

        @param component    the component that changed
        @see Component::setVisible
    */
    virtual void componentVisibilityChanged (Component& component);

    /** Called when the component has children added or removed.

        @param component    the component whose children were changed
        @see Component::childrenChanged, Component::addChildComponent,
             Component::removeChildComponent
    */
    virtual void componentChildrenChanged (Component& component);

    /** Called to indicate that the component's parents have changed.

        When a component is added or removed from its parent, all of its children
        will produce this notification (recursively - so all children of its
        children will also be called as well).

        @param component    the component that this listener is registered with
        @see Component::parentHierarchyChanged
    */
    virtual void componentParentHierarchyChanged (Component& component);

    /** Called when the component's name is changed.

        @see Component::setName, Component::getName
    */
    virtual void componentNameChanged (Component& component);
};

#endif   // __JUCE_COMPONENTLISTENER_JUCEHEADER__
/********* End of inlined file: juce_ComponentListener.h *********/

/********* Start of inlined file: juce_KeyListener.h *********/
#ifndef __JUCE_KEYLISTENER_JUCEHEADER__
#define __JUCE_KEYLISTENER_JUCEHEADER__

/********* Start of inlined file: juce_KeyPress.h *********/
#ifndef __JUCE_KEYPRESS_JUCEHEADER__
#define __JUCE_KEYPRESS_JUCEHEADER__

/**
    Represents a key press, including any modifier keys that are needed.

    E.g. a KeyPress might represent CTRL+C, SHIFT+ALT+H, Spacebar, Escape, etc.

    @see Component, KeyListener, Button::addShortcut, KeyPressMappingManager
*/
class JUCE_API  KeyPress
{
public:

    /** Creates an (invalid) KeyPress.

        @see isValid
    */
    KeyPress() throw();

    /** Creates a KeyPress for a key and some modifiers.

        e.g.
        CTRL+C would be: KeyPress ('c', ModifierKeys::ctrlModifier)
        SHIFT+Escape would be: KeyPress (KeyPress::escapeKey, ModifierKeys::shiftModifier)

        @param keyCode      a code that represents the key - this value must be
                            one of special constants listed in this class, or an
                            8-bit character code such as a letter (case is ignored),
                            digit or a simple key like "," or ".". Note that this
                            isn't the same as the textCharacter parameter, so for example
                            a keyCode of 'a' and a shift-key modifier should have a
                            textCharacter value of 'A'.
        @param modifiers    the modifiers to associate with the keystroke
        @param textCharacter    the character that would be printed if someone typed
                            this keypress into a text editor. This value may be
                            null if the keypress is a non-printing character
        @see getKeyCode, isKeyCode, getModifiers
    */
    KeyPress (const int keyCode,
              const ModifierKeys& modifiers,
              const juce_wchar textCharacter) throw();

    /** Creates a keypress with a keyCode but no modifiers or text character.
    */
    KeyPress (const int keyCode) throw();

    /** Creates a copy of another KeyPress. */
    KeyPress (const KeyPress& other) throw();

    /** Copies this KeyPress from another one. */
    const KeyPress& operator= (const KeyPress& other) throw();

    /** Compares two KeyPress objects. */
    bool operator== (const KeyPress& other) const throw();

    /** Compares two KeyPress objects. */
    bool operator!= (const KeyPress& other) const throw();

    /** Returns true if this is a valid KeyPress.

        A null keypress can be created by the default constructor, in case it's
        needed.
    */
    bool isValid() const throw()                                { return keyCode != 0; }

    /** Returns the key code itself.

        This will either be one of the special constants defined in this class,
        or an 8-bit character code.
    */
    int getKeyCode() const throw()                              { return keyCode; }

    /** Returns the key modifiers.

        @see ModifierKeys
    */
    const ModifierKeys getModifiers() const throw()             { return mods; }

    /** Returns the character that is associated with this keypress.

        This is the character that you'd expect to see printed if you press this
        keypress in a text editor or similar component.
    */
    juce_wchar getTextCharacter() const throw()                 { return textCharacter; }

    /** Checks whether the KeyPress's key is the same as the one provided, without checking
        the modifiers.

        The values for key codes can either be one of the special constants defined in
        this class, or an 8-bit character code.

        @see getKeyCode
    */
    bool isKeyCode (const int keyCodeToCompare) const throw()   { return keyCode == keyCodeToCompare; }

    /** Converts a textual key description to a KeyPress.

        This attempts to decode a textual version of a keypress, e.g. "CTRL + C" or "SPACE".

        This isn't designed to cope with any kind of input, but should be given the
        strings that are created by the getTextDescription() method.

        If the string can't be parsed, the object returned will be invalid.

        @see getTextDescription
    */
    static const KeyPress createFromDescription (const String& textVersion) throw();

    /** Creates a textual description of the key combination.

        e.g. "CTRL + C" or "DELETE".

        To store a keypress in a file, use this method, along with createFromDescription()
        to retrieve it later.
    */
    const String getTextDescription() const throw();

    /** Checks whether the user is currently holding down the keys that make up this
        KeyPress.

        Note that this will return false if any extra modifier keys are
        down - e.g. if the keypress is CTRL+X and the user is actually holding CTRL+ALT+x
        then it will be false.
    */
    bool isCurrentlyDown() const throw();

    /** Checks whether a particular key is held down, irrespective of modifiers.

        The values for key codes can either be one of the special constants defined in
        this class, or an 8-bit character code.
    */
    static bool isKeyCurrentlyDown (int keyCode) throw();

    // Key codes
    //
    // Note that the actual values of these are platform-specific and may change
    // without warning, so don't store them anywhere as constants. For persisting/retrieving
    // KeyPress objects, use getTextDescription() and createFromDescription() instead.
    //

    static const int spaceKey;      /**< key-code for the space bar */
    static const int escapeKey;     /**< key-code for the escape key */
    static const int returnKey;     /**< key-code for the return key*/
    static const int tabKey;        /**< key-code for the tab key*/

    static const int deleteKey;     /**< key-code for the delete key (not backspace) */
    static const int backspaceKey;  /**< key-code for the backspace key */
    static const int insertKey;     /**< key-code for the insert key */

    static const int upKey;         /**< key-code for the cursor-up key */
    static const int downKey;       /**< key-code for the cursor-down key */
    static const int leftKey;       /**< key-code for the cursor-left key */
    static const int rightKey;      /**< key-code for the cursor-right key */
    static const int pageUpKey;     /**< key-code for the page-up key */
    static const int pageDownKey;   /**< key-code for the page-down key */
    static const int homeKey;       /**< key-code for the home key */
    static const int endKey;        /**< key-code for the end key */

    static const int F1Key;         /**< key-code for the F1 key */
    static const int F2Key;         /**< key-code for the F2 key */
    static const int F3Key;         /**< key-code for the F3 key */
    static const int F4Key;         /**< key-code for the F4 key */
    static const int F5Key;         /**< key-code for the F5 key */
    static const int F6Key;         /**< key-code for the F6 key */
    static const int F7Key;         /**< key-code for the F7 key */
    static const int F8Key;         /**< key-code for the F8 key */
    static const int F9Key;         /**< key-code for the F9 key */
    static const int F10Key;        /**< key-code for the F10 key */
    static const int F11Key;        /**< key-code for the F11 key */
    static const int F12Key;        /**< key-code for the F12 key */
    static const int F13Key;        /**< key-code for the F13 key */
    static const int F14Key;        /**< key-code for the F14 key */
    static const int F15Key;        /**< key-code for the F15 key */
    static const int F16Key;        /**< key-code for the F16 key */

    static const int numberPad0;     /**< key-code for the 0 on the numeric keypad. */
    static const int numberPad1;     /**< key-code for the 1 on the numeric keypad. */
    static const int numberPad2;     /**< key-code for the 2 on the numeric keypad. */
    static const int numberPad3;     /**< key-code for the 3 on the numeric keypad. */
    static const int numberPad4;     /**< key-code for the 4 on the numeric keypad. */
    static const int numberPad5;     /**< key-code for the 5 on the numeric keypad. */
    static const int numberPad6;     /**< key-code for the 6 on the numeric keypad. */
    static const int numberPad7;     /**< key-code for the 7 on the numeric keypad. */
    static const int numberPad8;     /**< key-code for the 8 on the numeric keypad. */
    static const int numberPad9;     /**< key-code for the 9 on the numeric keypad. */

    static const int numberPadAdd;            /**< key-code for the add sign on the numeric keypad. */
    static const int numberPadSubtract;       /**< key-code for the subtract sign on the numeric keypad. */
    static const int numberPadMultiply;       /**< key-code for the multiply sign on the numeric keypad. */
    static const int numberPadDivide;         /**< key-code for the divide sign on the numeric keypad. */
    static const int numberPadSeparator;      /**< key-code for the comma on the numeric keypad. */
    static const int numberPadDecimalPoint;   /**< key-code for the decimal point sign on the numeric keypad. */
    static const int numberPadEquals;         /**< key-code for the equals key on the numeric keypad. */
    static const int numberPadDelete;         /**< key-code for the delete key on the numeric keypad. */

    static const int playKey;        /**< key-code for a multimedia 'play' key, (not all keyboards will have one) */
    static const int stopKey;        /**< key-code for a multimedia 'stop' key, (not all keyboards will have one) */
    static const int fastForwardKey; /**< key-code for a multimedia 'fast-forward' key, (not all keyboards will have one) */
    static const int rewindKey;      /**< key-code for a multimedia 'rewind' key, (not all keyboards will have one) */

    juce_UseDebuggingNewOperator

private:

    int keyCode;
    ModifierKeys mods;
    juce_wchar textCharacter;
};

#endif   // __JUCE_KEYPRESS_JUCEHEADER__
/********* End of inlined file: juce_KeyPress.h *********/

class Component;

/**
    Receives callbacks when keys are pressed.

    You can add a key listener to a component to be informed when that component
    gets key events. See the Component::addListener method for more details.

    @see KeyPress, Component::addKeyListener, KeyPressMappingManager
*/
class JUCE_API  KeyListener
{
public:
    /** Destructor. */
    virtual ~KeyListener()  {}

    /** Called to indicate that a key has been pressed.

        If your implementation returns true, then the key event is considered to have
        been consumed, and will not be passed on to any other components. If it returns
        false, then the key will be passed to other components that might want to use it.

        @param key                      the keystroke, including modifier keys
        @param originatingComponent     the component that received the key event
        @see keyStateChanged, Component::keyPressed
    */
    virtual bool keyPressed (const KeyPress& key,
                             Component* originatingComponent) = 0;

    /** Called when any key is pressed or released.

        When this is called, classes that might be interested in
        the state of one or more keys can use KeyPress::isKeyCurrentlyDown() to
        check whether their key has changed.

        If your implementation returns true, then the key event is considered to have
        been consumed, and will not be passed on to any other components. If it returns
        false, then the key will be passed to other components that might want to use it.

        @param originatingComponent     the component that received the key event
        @param isKeyDown                true if a key is being pressed, false if one is being released
        @see KeyPress, Component::keyStateChanged
    */
    virtual bool keyStateChanged (const bool isKeyDown, Component* originatingComponent);

private:
    // (dummy method to cause a deliberate compile error - if you hit this, you need to update your
    // subclass to use the new parameters to keyStateChanged)
    virtual void keyStateChanged (Component*) {};
};

#endif   // __JUCE_KEYLISTENER_JUCEHEADER__
/********* End of inlined file: juce_KeyListener.h *********/

/********* Start of inlined file: juce_KeyboardFocusTraverser.h *********/
#ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__
#define __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__

class Component;

/**
    Controls the order in which focus moves between components.

    The default algorithm used by this class to work out the order of traversal
    is as follows:
    - if two components both have an explicit focus order specified, then the
      one with the lowest number comes first (see the Component::setExplicitFocusOrder()
      method).
    - any component with an explicit focus order greater than 0 comes before ones
      that don't have an order specified.
    - any unspecified components are traversed in a left-to-right, then top-to-bottom
      order.

    If you need traversal in a more customised way, you can create a subclass
    of KeyboardFocusTraverser that uses your own algorithm, and use
    Component::createFocusTraverser() to create it.

    @see Component::setExplicitFocusOrder, Component::createFocusTraverser
*/
class JUCE_API  KeyboardFocusTraverser
{
public:
    KeyboardFocusTraverser();

    /** Destructor. */
    virtual ~KeyboardFocusTraverser();

    /** Returns the component that should be given focus after the specified one
        when moving "forwards".

        The default implementation will return the next component which is to the
        right of or below this one.

        This may return 0 if there's no suitable candidate.
    */
    virtual Component* getNextComponent (Component* current);

    /** Returns the component that should be given focus after the specified one
        when moving "backwards".

        The default implementation will return the next component which is to the
        left of or above this one.

        This may return 0 if there's no suitable candidate.
    */
    virtual Component* getPreviousComponent (Component* current);

    /** Returns the component that should receive focus be default within the given
        parent component.

        The default implementation will just return the foremost child component that
        wants focus.

        This may return 0 if there's no suitable candidate.
    */
    virtual Component* getDefaultComponent (Component* parentComponent);
};

#endif   // __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__
/********* End of inlined file: juce_KeyboardFocusTraverser.h *********/

/********* Start of inlined file: juce_ImageEffectFilter.h *********/
#ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__
#define __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__

/********* Start of inlined file: juce_Graphics.h *********/
#ifndef __JUCE_GRAPHICS_JUCEHEADER__
#define __JUCE_GRAPHICS_JUCEHEADER__

/********* Start of inlined file: juce_Font.h *********/
#ifndef __JUCE_FONT_JUCEHEADER__
#define __JUCE_FONT_JUCEHEADER__

/********* Start of inlined file: juce_Typeface.h *********/
#ifndef __JUCE_TYPEFACE_JUCEHEADER__
#define __JUCE_TYPEFACE_JUCEHEADER__

/********* Start of inlined file: juce_Path.h *********/
#ifndef __JUCE_PATH_JUCEHEADER__
#define __JUCE_PATH_JUCEHEADER__

/********* Start of inlined file: juce_AffineTransform.h *********/
#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__
#define __JUCE_AFFINETRANSFORM_JUCEHEADER__

/**
    Represents a 2D affine-transformation matrix.

    An affine transformation is a transformation such as a rotation, scale, shear,
    resize or translation.

    These are used for various 2D transformation tasks, e.g. with Path objects.

    @see Path, Point, Line
*/
class JUCE_API  AffineTransform
{
public:

    /** Creates an identity transform. */
    AffineTransform() throw();

    /** Creates a copy of another transform. */
    AffineTransform (const AffineTransform& other) throw();

    /** Creates a transform from a set of raw matrix values.

        The resulting matrix is:

            (mat00 mat01 mat02)
            (mat10 mat11 mat12)
            (  0     0     1  )
    */
    AffineTransform (const float mat00, const float mat01, const float mat02,
                     const float mat10, const float mat11, const float mat12) throw();

    /** Copies from another AffineTransform object */
    const AffineTransform& operator= (const AffineTransform& other) throw();

    /** Compares two transforms. */
    bool operator== (const AffineTransform& other) const throw();

    /** Compares two transforms. */
    bool operator!= (const AffineTransform& other) const throw();

    /** A ready-to-use identity transform, which you can use to append other
        transformations to.

        e.g. @code
        AffineTransform myTransform = AffineTransform::identity.rotated (.5f)
                                                               .scaled (2.0f);

        @endcode
    */
    static const AffineTransform identity;

    /** Transforms a 2D co-ordinate using this matrix. */
    void transformPoint (float& x,
                         float& y) const throw();

    /** Transforms a 2D co-ordinate using this matrix. */
    void transformPoint (double& x,
                         double& y) const throw();

    /** Returns a new transform which is the same as this one followed by a translation. */
    const AffineTransform translated (const float deltaX,
                                      const float deltaY) const throw();

    /** Returns a new transform which is a translation. */
    static const AffineTransform translation (const float deltaX,
                                              const float deltaY) throw();

    /** Returns a transform which is the same as this one followed by a rotation.

        The rotation is specified by a number of radians to rotate clockwise, centred around
        the origin (0, 0).
    */
    const AffineTransform rotated (const float angleInRadians) const throw();

    /** Returns a transform which is the same as this one followed by a rotation about a given point.

        The rotation is specified by a number of radians to rotate clockwise, centred around
        the co-ordinates passed in.
    */
    const AffineTransform rotated (const float angleInRadians,
                                   const float pivotX,
                                   const float pivotY) const throw();

    /** Returns a new transform which is a rotation about (0, 0). */
    static const AffineTransform rotation (const float angleInRadians) throw();

    /** Returns a new transform which is a rotation about a given point. */
    static const AffineTransform rotation (const float angleInRadians,
                                           const float pivotX,
                                           const float pivotY) throw();

    /** Returns a transform which is the same as this one followed by a re-scaling.

        The scaling is centred around the origin (0, 0).
    */
    const AffineTransform scaled (const float factorX,
                                  const float factorY) const throw();

    /** Returns a new transform which is a re-scale about the origin. */
    static const AffineTransform scale (const float factorX,
                                        const float factorY) throw();

    /** Returns a transform which is the same as this one followed by a shear.

        The shear is centred around the origin (0, 0).
    */
    const AffineTransform sheared (const float shearX,
                                   const float shearY) const throw();

    /** Returns a matrix which is the inverse operation of this one.

        Some matrices don't have an inverse - in this case, the method will just return
        an identity transform.
    */
    const AffineTransform inverted() const throw();

    /** Returns the result of concatenating another transformation after this one. */
    const AffineTransform followedBy (const AffineTransform& other) const throw();

    /** Returns true if this transform has no effect on points. */
    bool isIdentity() const throw();

    /** Returns true if this transform maps to a singularity - i.e. if it has no inverse. */
    bool isSingularity() const throw();

    juce_UseDebuggingNewOperator

    /* The transform matrix is:

        (mat00 mat01 mat02)
        (mat10 mat11 mat12)
        (  0     0     1  )
    */
    float mat00, mat01, mat02;
    float mat10, mat11, mat12;

private:

    const AffineTransform followedBy (const float mat00, const float mat01, const float mat02,
                                      const float mat10, const float mat11, const float mat12) const throw();
};

#endif   // __JUCE_AFFINETRANSFORM_JUCEHEADER__
/********* End of inlined file: juce_AffineTransform.h *********/

/********* Start of inlined file: juce_Point.h *********/
#ifndef __JUCE_POINT_JUCEHEADER__
#define __JUCE_POINT_JUCEHEADER__

/**
    A pair of (x, y) co-ordinates.

    Uses 32-bit floating point accuracy.

    @see Line, Path, AffineTransform
*/
class JUCE_API  Point
{
public:

    /** Creates a point with co-ordinates (0, 0). */
    Point() throw();

    /** Creates a copy of another point. */
    Point (const Point& other) throw();

    /** Creates a point from an (x, y) position. */
    Point (const float x, const float y) throw();

    /** Copies this point from another one.
        @see setXY
    */
    const Point& operator= (const Point& other) throw();

    /** Destructor. */
    ~Point() throw();

    /** Returns the point's x co-ordinate. */
    inline float getX() const throw()                   { return x; }

    /** Returns the point's y co-ordinate. */
    inline float getY() const throw()                   { return y; }

    /** Changes the point's x and y co-ordinates. */
    void setXY (const float x,
                const float y) throw();

    /** Uses a transform to change the point's co-ordinates.

        @see AffineTransform::transformPoint
    */
    void applyTransform (const AffineTransform& transform) throw();

    juce_UseDebuggingNewOperator

private:
    float x, y;
};

#endif   // __JUCE_POINT_JUCEHEADER__
/********* End of inlined file: juce_Point.h *********/

/********* Start of inlined file: juce_Justification.h *********/
#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__
#define __JUCE_JUSTIFICATION_JUCEHEADER__

/**
    Represents a type of justification to be used when positioning graphical items.

    e.g. it indicates whether something should be placed top-left, top-right,
    centred, etc.

    It is used in various places wherever this kind of information is needed.
*/
class JUCE_API  Justification
{
public:

    /** Creates a Justification object using a combination of flags. */
    inline Justification (const int flags_) throw()  : flags (flags_) {}

    /** Creates a copy of another Justification object. */
    Justification (const Justification& other) throw();

    /** Copies another Justification object. */
    const Justification& operator= (const Justification& other) throw();

    /** Returns the raw flags that are set for this Justification object. */
    inline int getFlags() const throw()                             { return flags; }

    /** Tests a set of flags for this object.

        @returns true if any of the flags passed in are set on this object.
    */
    inline bool testFlags (const int flagsToTest) const throw()     { return (flags & flagsToTest) != 0; }

    /** Returns just the flags from this object that deal with vertical layout. */
    int getOnlyVerticalFlags() const throw();

    /** Returns just the flags from this object that deal with horizontal layout. */
    int getOnlyHorizontalFlags() const throw();

    /** Adjusts the position of a rectangle to fit it into a space.

        The (x, y) position of the rectangle will be updated to position it inside the
        given space according to the justification flags.
    */
    void applyToRectangle (int& x, int& y,
                           const int w, const int h,
                           const int spaceX, const int spaceY,
                           const int spaceW, const int spaceH) const throw();

    /** Flag values that can be combined and used in the constructor. */
    enum
    {

        /** Indicates that the item should be aligned against the left edge of the available space. */
        left                            = 1,

        /** Indicates that the item should be aligned against the right edge of the available space. */
        right                           = 2,

        /** Indicates that the item should be placed in the centre between the left and right
            sides of the available space. */
        horizontallyCentred             = 4,

        /** Indicates that the item should be aligned against the top edge of the available space. */
        top                             = 8,

        /** Indicates that the item should be aligned against the bottom edge of the available space. */
        bottom                          = 16,

        /** Indicates that the item should be placed in the centre between the top and bottom
            sides of the available space. */
        verticallyCentred               = 32,

        /** Indicates that lines of text should be spread out to fill the maximum width
            available, so that both margins are aligned vertically.
        */
        horizontallyJustified           = 64,

        /** Indicates that the item should be centred vertically and horizontally.

            This is equivalent to (horizontallyCentred | verticallyCentred)
        */
        centred                         = 36,

        /** Indicates that the item should be centred vertically but placed on the left hand side.

            This is equivalent to (left | verticallyCentred)
        */
        centredLeft                     = 33,

        /** Indicates that the item should be centred vertically but placed on the right hand side.

            This is equivalent to (right | verticallyCentred)
        */
        centredRight                    = 34,

        /** Indicates that the item should be centred horizontally and placed at the top.

            This is equivalent to (horizontallyCentred | top)
        */
        centredTop                      = 12,

        /** Indicates that the item should be centred horizontally and placed at the bottom.

            This is equivalent to (horizontallyCentred | bottom)
        */
        centredBottom                   = 20,

        /** Indicates that the item should be placed in the top-left corner.

            This is equivalent to (left | top)
        */
        topLeft                         = 9,

        /** Indicates that the item should be placed in the top-right corner.

            This is equivalent to (right | top)
        */
        topRight                        = 10,

        /** Indicates that the item should be placed in the bottom-left corner.

            This is equivalent to (left | bottom)
        */
        bottomLeft                      = 17,

        /** Indicates that the item should be placed in the bottom-left corner.

            This is equivalent to (right | bottom)
        */
        bottomRight                     = 18
    };

private:

    int flags;
};

#endif   // __JUCE_JUSTIFICATION_JUCEHEADER__
/********* End of inlined file: juce_Justification.h *********/

/**
    A path is a sequence of lines and curves that may either form a closed shape
    or be open-ended.

    To use a path, you can create an empty one, then add lines and curves to it
    to create shapes, then it can be rendered by a Graphics context or used
    for geometric operations.

    e.g. @code
    Path myPath;

    myPath.startNewSubPath (10.0f, 10.0f);          // move the current position to (10, 10)
    myPath.lineTo (100.0f, 200.0f);                 // draw a line from here to (100, 200)
    myPath.quadraticTo (0.0f, 150.0f, 5.0f, 50.0f); // draw a curve that ends at (5, 50)
    myPath.closeSubPath();                          // close the subpath with a line back to (10, 10)

    // add an ellipse as well, which will form a second sub-path within the path..
    myPath.addEllipse (50.0f, 50.0f, 40.0f, 30.0f);

    // double the width of the whole thing..
    myPath.applyTransform (AffineTransform::scale (2.0f, 1.0f));

    // and draw it to a graphics context with a 5-pixel thick outline.
    g.strokePath (myPath, PathStrokeType (5.0f));

    @endcode

    A path object can actually contain multiple sub-paths, which may themselves
    be open or closed.

    @see PathFlatteningIterator, PathStrokeType, Graphics
*/
class JUCE_API  Path  : private ArrayAllocationBase <float>
{
public:

    /** Creates an empty path. */
    Path() throw();

    /** Creates a copy of another path. */
    Path (const Path& other) throw();

    /** Destructor. */
    ~Path() throw();

    /** Copies this path from another one. */
    const Path& operator= (const Path& other) throw();

    /** Returns true if the path doesn't contain any lines or curves. */
    bool isEmpty() const throw();

    /** Returns the smallest rectangle that contains all points within the path.
    */
    void getBounds (float& x, float& y,
                    float& w, float& h) const throw();

    /** Returns the smallest rectangle that contains all points within the path
        after it's been transformed with the given tranasform matrix.
    */
    void getBoundsTransformed (const AffineTransform& transform,
                               float& x, float& y,
                               float& w, float& h) const throw();

    /** Checks whether a point lies within the path.

        This is only relevent for closed paths (see closeSubPath()), and
        may produce false results if used on a path which has open sub-paths.

        The path's winding rule is taken into account by this method.

        The tolerence parameter is passed to the PathFlatteningIterator that
        is used to trace the path - for more info about it, see the notes for
        the PathFlatteningIterator constructor.

        @see closeSubPath, setUsingNonZeroWinding
    */
    bool contains (const float x,
                   const float y,
                   const float tolerence = 10.0f) const throw();

    /** Checks whether a line crosses the path.

        This will return positive if the line crosses any of the paths constituent
        lines or curves. It doesn't take into account whether the line is inside
        or outside the path, or whether the path is open or closed.

        The tolerence parameter is passed to the PathFlatteningIterator that
        is used to trace the path - for more info about it, see the notes for
        the PathFlatteningIterator constructor.
    */
    bool intersectsLine (const float x1, const float y1,
                         const float x2, const float y2,
                         const float tolerence = 10.0f) throw();

    /** Removes all lines and curves, resetting the path completely. */
    void clear() throw();

    /** Begins a new subpath with a given starting position.

        This will move the path's current position to the co-ordinates passed in and
        make it ready to draw lines or curves starting from this position.

        After adding whatever lines and curves are needed, you can either
        close the current sub-path using closeSubPath() or call startNewSubPath()
        to move to a new sub-path, leaving the old one open-ended.

        @see lineTo, quadraticTo, cubicTo, closeSubPath
    */
    void startNewSubPath (const float startX,
                          const float startY) throw();

    /** Closes a the current sub-path with a line back to its start-point.

        When creating a closed shape such as a triangle, don't use 3 lineTo()
        calls - instead use two lineTo() calls, followed by a closeSubPath()
        to join the final point back to the start.

        This ensures that closes shapes are recognised as such, and this is
        important for tasks like drawing strokes, which needs to know whether to
        draw end-caps or not.

        @see startNewSubPath, lineTo, quadraticTo, cubicTo, closeSubPath
    */
    void closeSubPath() throw();

    /** Adds a line from the shape's last position to a new end-point.

        This will connect the end-point of the last line or curve that was added
        to a new point, using a straight line.

        See the class description for an example of how to add lines and curves to a path.

        @see startNewSubPath, quadraticTo, cubicTo, closeSubPath
    */
    void lineTo (const float endX,
                 const float endY) throw();

    /** Adds a quadratic bezier curve from the shape's last position to a new position.

        This will connect the end-point of the last line or curve that was added
        to a new point, using a quadratic spline with one control-point.

        See the class description for an example of how to add lines and curves to a path.

        @see startNewSubPath, lineTo, cubicTo, closeSubPath
    */
    void quadraticTo (const float controlPointX,
                      const float controlPointY,
                      const float endPointX,
                      const float endPointY) throw();

    /** Adds a cubic bezier curve from the shape's last position to a new position.

        This will connect the end-point of the last line or curve that was added
        to a new point, using a cubic spline with two control-points.

        See the class description for an example of how to add lines and curves to a path.

        @see startNewSubPath, lineTo, quadraticTo, closeSubPath
    */
    void cubicTo (const float controlPoint1X,
                  const float controlPoint1Y,
                  const float controlPoint2X,
                  const float controlPoint2Y,
                  const float endPointX,
                  const float endPointY) throw();

    /** Returns the last point that was added to the path by one of the drawing methods.
    */
    const Point getCurrentPosition() const;

    /** Adds a rectangle to the path.

        The rectangle is added as a new sub-path. (Any currently open paths will be
        left open).

        @see addRoundedRectangle, addTriangle
    */
    void addRectangle (const float x, const float y,
                       const float w, const float h) throw();

    /** Adds a rectangle with rounded corners to the path.

        The rectangle is added as a new sub-path. (Any currently open paths will be
        left open).

        @see addRectangle, addTriangle
    */
    void addRoundedRectangle (const float x, const float y,
                              const float w, const float h,
                              float cornerSize) throw();

    /** Adds a rectangle with rounded corners to the path.

        The rectangle is added as a new sub-path. (Any currently open paths will be
        left open).

        @see addRectangle, addTriangle
    */
    void addRoundedRectangle (const float x, const float y,
                              const float w, const float h,
                              float cornerSizeX,
                              float cornerSizeY) throw();

    /** Adds a triangle to the path.

        The triangle is added as a new closed sub-path. (Any currently open paths will be
        left open).

        Note that whether the vertices are specified in clockwise or anticlockwise
        order will affect how the triangle is filled when it overlaps other
        shapes (the winding order setting will affect this of course).
    */
    void addTriangle (const float x1, const float y1,
                      const float x2, const float y2,
                      const float x3, const float y3) throw();

    /** Adds a quadrilateral to the path.

        The quad is added as a new closed sub-path. (Any currently open paths will be
        left open).

        Note that whether the vertices are specified in clockwise or anticlockwise
        order will affect how the quad is filled when it overlaps other
        shapes (the winding order setting will affect this of course).
    */
    void addQuadrilateral (const float x1, const float y1,
                           const float x2, const float y2,
                           const float x3, const float y3,
                           const float x4, const float y4) throw();

    /** Adds an ellipse to the path.

        The shape is added as a new sub-path. (Any currently open paths will be
        left open).

        @see addArc
    */
    void addEllipse (const float x, const float y,
                     const float width, const float height) throw();

    /** Adds an elliptical arc to the current path.

        Note that when specifying the start and end angles, the curve will be drawn either clockwise
        or anti-clockwise according to whether the end angle is greater than the start. This means
        that sometimes you may need to use values greater than 2*Pi for the end angle.

        @param x            the left-hand edge of the rectangle in which the elliptical outline fits
        @param y            the top edge of the rectangle in which the elliptical outline fits
        @param width        the width of the rectangle in which the elliptical outline fits
        @param height       the height of the rectangle in which the elliptical outline fits
        @param fromRadians  the angle (clockwise) in radians at which to start the arc segment (where 0 is the
                            top-centre of the ellipse)
        @param toRadians    the angle (clockwise) in radians at which to end the arc segment (where 0 is the
                            top-centre of the ellipse). This angle can be greater than 2*Pi, so for example to
                            draw a curve clockwise from the 9 o'clock position to the 3 o'clock position via
                            12 o'clock, you'd use 1.5*Pi and 2.5*Pi as the start and finish points.
        @param startAsNewSubPath    if true, the arc will begin a new subpath from its starting point; if false,
                            it will be added to the current sub-path, continuing from the current postition

        @see addCentredArc, arcTo, addPieSegment, addEllipse
    */
    void addArc (const float x, const float y,
                 const float width, const float height,
                 const float fromRadians,
                 const float toRadians,
                 const bool startAsNewSubPath = false) throw();

    /** Adds an arc which is centred at a given point, and can have a rotation specified.

        Note that when specifying the start and end angles, the curve will be drawn either clockwise
        or anti-clockwise according to whether the end angle is greater than the start. This means
        that sometimes you may need to use values greater than 2*Pi for the end angle.

        @param centreX      the centre x of the ellipse
        @param centreY      the centre y of the ellipse
        @param radiusX      the horizontal radius of the ellipse
        @param radiusY      the vertical radius of the ellipse
        @param rotationOfEllipse    an angle by which the whole ellipse should be rotated about its centre, in radians (clockwise)
        @param fromRadians  the angle (clockwise) in radians at which to start the arc segment (where 0 is the
                            top-centre of the ellipse)
        @param toRadians    the angle (clockwise) in radians at which to end the arc segment (where 0 is the
                            top-centre of the ellipse). This angle can be greater than 2*Pi, so for example to
                            draw a curve clockwise from the 9 o'clock position to the 3 o'clock position via
                            12 o'clock, you'd use 1.5*Pi and 2.5*Pi as the start and finish points.
        @param startAsNewSubPath    if true, the arc will begin a new subpath from its starting point; if false,
                            it will be added to the current sub-path, continuing from the current postition

        @see addArc, arcTo
    */
    void addCentredArc (const float centreX, const float centreY,
                        const float radiusX, const float radiusY,
                        const float rotationOfEllipse,
                        const float fromRadians,
                        const float toRadians,
                        const bool startAsNewSubPath = false) throw();

    /** Adds a "pie-chart" shape to the path.

        The shape is added as a new sub-path. (Any currently open paths will be
        left open).

        Note that when specifying the start and end angles, the curve will be drawn either clockwise
        or anti-clockwise according to whether the end angle is greater than the start. This means
        that sometimes you may need to use values greater than 2*Pi for the end angle.

        @param x            the left-hand edge of the rectangle in which the elliptical outline fits
        @param y            the top edge of the rectangle in which the elliptical outline fits
        @param width        the width of the rectangle in which the elliptical outline fits
        @param height       the height of the rectangle in which the elliptical outline fits
        @param fromRadians  the angle (clockwise) in radians at which to start the arc segment (where 0 is the
                            top-centre of the ellipse)
        @param toRadians    the angle (clockwise) in radians at which to end the arc segment (where 0 is the
                            top-centre of the ellipse)
        @param innerCircleProportionalSize  if this is > 0, then the pie will be drawn as a curved band around a hollow
                            ellipse at its centre, where this value indicates the inner ellipse's size with
                            respect to the outer one.

        @see addArc
    */
    void addPieSegment (const float x, const float y,
                        const float width, const float height,
                        const float fromRadians,
                        const float toRadians,
                        const float innerCircleProportionalSize);

    /** Adds a line with a specified thickness.

        The line is added as a new closed sub-path. (Any currently open paths will be
        left open).

        @see addArrow
    */
    void addLineSegment (const float startX, const float startY,
                         const float endX, const float endY,
                         float lineThickness) throw();

    /** Adds a line with an arrowhead on the end.

        The arrow is added as a new closed sub-path. (Any currently open paths will be
        left open).
    */
    void addArrow (const float startX, const float startY,
                   const float endX, const float endY,
                   float lineThickness,
                   float arrowheadWidth,
                   float arrowheadLength) throw();

    /** Adds a star shape to the path.

    */
    void addStar (const float centreX,
                  const float centreY,
                  const int numberOfPoints,
                  const float innerRadius,
                  const float outerRadius,
                  const float startAngle = 0.0f);

    /** Adds a speech-bubble shape to the path.

        @param bodyX            the left of the main body area of the bubble
        @param bodyY            the top of the main body area of the bubble
        @param bodyW            the width of the main body area of the bubble
        @param bodyH            the height of the main body area of the bubble
        @param cornerSize       the amount by which to round off the corners of the main body rectangle
        @param arrowTipX        the x position that the tip of the arrow should connect to
        @param arrowTipY        the y position that the tip of the arrow should connect to
        @param whichSide        the side to connect the arrow to: 0 = top, 1 = left, 2 = bottom, 3 = right
        @param arrowPositionAlongEdgeProportional   how far along the edge of the main rectangle the
                                arrow's base should be - this is a proportional distance between 0 and 1.0
        @param arrowWidth       how wide the base of the arrow should be where it joins the main rectangle
    */
    void addBubble (float bodyX, float bodyY,
                    float bodyW, float bodyH,
                    float cornerSize,
                    float arrowTipX,
                    float arrowTipY,
                    int whichSide,
                    float arrowPositionAlongEdgeProportional,
                    float arrowWidth);

    /** Adds another path to this one.

        The new path is added as a new sub-path. (Any currently open paths in this
        path will be left open).

        @param pathToAppend     the path to add
    */
    void addPath (const Path& pathToAppend) throw();

    /** Adds another path to this one, transforming it on the way in.

        The new path is added as a new sub-path, its points being transformed by the given
        matrix before being added.

        @param pathToAppend     the path to add
        @param transformToApply an optional transform to apply to the incoming vertices
    */
    void addPath (const Path& pathToAppend,
                  const AffineTransform& transformToApply) throw();

    /** Swaps the contents of this path with another one.

        The internal data of the two paths is swapped over, so this is much faster than
        copying it to a temp variable and back.
    */
    void swapWithPath (Path& other);

    /** Applies a 2D transform to all the vertices in the path.

        @see AffineTransform, scaleToFit, getTransformToScaleToFit
    */
    void applyTransform (const AffineTransform& transform) throw();

    /** Rescales this path to make it fit neatly into a given space.

        This is effectively a quick way of calling
        applyTransform (getTransformToScaleToFit (x, y, w, h, preserveProportions))

        @param x                    the x position of the rectangle to fit the path inside
        @param y                    the y position of the rectangle to fit the path inside
        @param width                the width of the rectangle to fit the path inside
        @param height               the height of the rectangle to fit the path inside
        @param preserveProportions  if true, it will fit the path into the space without altering its
                                    horizontal/vertical scale ratio; if false, it will distort the
                                    path to fill the specified ratio both horizontally and vertically

        @see applyTransform, getTransformToScaleToFit
    */
    void scaleToFit (const float x, const float y,
                     const float width, const float height,
                     const bool preserveProportions) throw();

    /** Returns a transform that can be used to rescale the path to fit into a given space.

        @param x                    the x position of the rectangle to fit the path inside
        @param y                    the y position of the rectangle to fit the path inside
        @param width                the width of the rectangle to fit the path inside
        @param height               the height of the rectangle to fit the path inside
        @param preserveProportions  if true, it will fit the path into the space without altering its
                                    horizontal/vertical scale ratio; if false, it will distort the
                                    path to fill the specified ratio both horizontally and vertically
        @param justificationType    if the proportions are preseved, the resultant path may be smaller
                                    than the available rectangle, so this describes how it should be
                                    positioned within the space.
        @returns                    an appropriate transformation

        @see applyTransform, scaleToFit

    */
    const AffineTransform getTransformToScaleToFit (const float x, const float y,
                                                    const float width, const float height,
                                                    const bool preserveProportions,
                                                    const Justification& justificationType = Justification::centred) const throw();

    /** Creates a version of this path where all sharp corners have been replaced by curves.

        Wherever two lines meet at an angle, this will replace the corner with a curve
        of the given radius.
    */
    const Path createPathWithRoundedCorners (const float cornerRadius) const throw();

    /** Changes the winding-rule to be used when filling the path.

        If set to true (which is the default), then the path uses a non-zero-winding rule
        to determine which points are inside the path. If set to false, it uses an
        alternate-winding rule.

        The winding-rule comes into play when areas of the shape overlap other
        areas, and determines whether the overlapping regions are considered to be
        inside or outside.

        Changing this value just sets a flag - it doesn't affect the contents of the
        path.

        @see isUsingNonZeroWinding
    */
    void setUsingNonZeroWinding (const bool isNonZeroWinding) throw();

    /** Returns the flag that indicates whether the path should use a non-zero winding rule.

        The default for a new path is true.

        @see setUsingNonZeroWinding
    */
    bool isUsingNonZeroWinding() const throw()          { return useNonZeroWinding; }

    /** Iterates the lines and curves that a path contains.

        @see Path, PathFlatteningIterator
    */
    class JUCE_API  Iterator
    {
    public:

        Iterator (const Path& path);
        ~Iterator();

        /** Moves onto the next element in the path.

            If this returns false, there are no more elements. If it returns true,
            the elementType variable will be set to the type of the current element,
            and some of the x and y variables will be filled in with values.
        */
        bool next();

        enum PathElementType
        {
            startNewSubPath,    /**< For this type, x1 and y1 will be set to indicate the first point in the subpath.  */
            lineTo,             /**< For this type, x1 and y1 indicate the end point of the line.  */
            quadraticTo,        /**< For this type, x1, y1, x2, y2 indicate the control point and endpoint of a quadratic curve. */
            cubicTo,            /**< For this type, x1, y1, x2, y2, x3, y3 indicate the two control points and the endpoint of a cubic curve. */
            closePath           /**< Indicates that the sub-path is being closed. None of the x or y values are valid in this case. */
        };

        PathElementType elementType;

        float x1, y1, x2, y2, x3, y3;

    private:
        const Path& path;
        int index;

        Iterator (const Iterator&);
        const Iterator& operator= (const Iterator&);
    };

    /** Loads a stored path from a data stream.

        The data in the stream must have been written using writePathToStream().

        Note that this will append the stored path to whatever is currently in
        this path, so you might need to call clear() beforehand.

        @see loadPathFromData, writePathToStream
    */
    void loadPathFromStream (InputStream& source);

    /** Loads a stored path from a block of data.

        This is similar to loadPathFromStream(), but just reads from a block
        of data. Useful if you're including stored shapes in your code as a
        block of static data.

        @see loadPathFromStream, writePathToStream
    */
    void loadPathFromData (const unsigned char* const data,
                           const int numberOfBytes) throw();

    /** Stores the path by writing it out to a stream.

        After writing out a path, you can reload it using loadPathFromStream().

        @see loadPathFromStream, loadPathFromData
    */
    void writePathToStream (OutputStream& destination) const;

    /** Creates a string containing a textual representation of this path.
        @see restoreFromString
    */
    const String toString() const;

    /** Restores this path from a string that was created with the toString() method.
        @see toString()
    */
    void restoreFromString (const String& stringVersion);

    juce_UseDebuggingNewOperator

private:
    friend class PathFlatteningIterator;
    friend class Path::Iterator;
    int numElements;
    float pathXMin, pathXMax, pathYMin, pathYMax;
    bool useNonZeroWinding;

    static const float lineMarker;
    static const float moveMarker;
    static const float quadMarker;
    static const float cubicMarker;
    static const float closeSubPathMarker;
};

#endif   // __JUCE_PATH_JUCEHEADER__
/********* End of inlined file: juce_Path.h *********/

class Font;
class Typeface;

/**
    Stores information about the shape and kerning of one of the glyphs in a Typeface.

    @see Typeface, PositionedGlyph, GlyphArrangement
*/
class JUCE_API  TypefaceGlyphInfo
{
public:

    /** Returns the path that describes the glyph's outline.

        This is normalised to a height of 1.0, and its origin is the
        left-hand edge of the glyph's baseline.
    */
    const Path& getPath() const throw()             { return path; }

    /** Returns the unicode character that this glyph represents. */
    juce_wchar getCharacter() const throw()         { return character; }

    bool isWhitespace() const throw()               { return CharacterFunctions::isWhitespace (character); }

    /** Returns the distance to leave between this and a following character.

        The value returned is expressed as a proportion of the font's height.
    */
    float getHorizontalSpacing (const juce_wchar subsequentCharacter) const throw();

    /** Returns the typeface that this glyph belongs to. */
    Typeface* getTypeface() const throw()           { return typeface; }

private:

    friend class Typeface;

    struct KerningPair
    {
        juce_wchar character2;
        float kerningAmount;
    };

    const juce_wchar character;
    const Path path;
    float width;
    MemoryBlock kerningPairs;
    Typeface* const typeface;

    TypefaceGlyphInfo (const juce_wchar character,
                       const Path& shape,
                       const float horizontalSeparation,
                       Typeface* const typeface) throw();
    ~TypefaceGlyphInfo() throw();

    KerningPair& getKerningPair (const int index) const throw();
    int getNumKerningPairs() const throw();

    void addKerningPair (const juce_wchar subsequentCharacter,
                         const float extraKerningAmount) throw();

    const TypefaceGlyphInfo& operator= (const TypefaceGlyphInfo&);
};

/**
    Represents a size-independent system font.

    A Font object represents a particular Typeface along with a specific size,
    style, kerning, scale, etc, wheras the Typeface is just a generalised description
    of the shapes of the glyphs and their properties.

*/
class JUCE_API  Typeface  : public ReferenceCountedObject
{
public:

    /** Tries to load a named system font and to initialise all the glyphs
        appropriately from it.

        @param faceName     the name of the typeface, e.g. "Times"
        @param bold         whether to try to find a bold version of the font (may not always be available)
        @param italic       whether to try to find an italicised version of the font (may not always be available)
    */
    Typeface (const String& faceName,
              const bool bold,
              const bool italic);

    /** Creates a copy of another typeface */
    Typeface (const Typeface& other);

    /** Destructor. */
    ~Typeface();

    /** Copies another typeface over this one. */
    const Typeface& operator= (const Typeface& other) throw();

    /** Returns a unique ID for the typeface.

        This is based on the name and style, so can be used to compare two Typeface objects.
    */
    int hashCode() const throw()                    { return hash; }

    /** Returns the name of the typeface, e.g. "Times", "Verdana", etc */
    const String& getName() const throw()           { return typefaceName; }

    /** Returns the font's ascent as a proportion of its height. */
    float getAscent() const throw()                 { return ascent; }

    /** Returns true if the font is flagged as being bold. */
    bool isBold() const throw()                     { return bold; }

    /** Returns true if the typeface's 'italic' flag is set. */
    bool isItalic() const throw()                   { return italic; }

    /** Finds the Path that describes the outline shape of a character.

        The height of the path is normalised to 1.0 (i.e. a distance of 1.0 is the
        height of the font).

        This may return 0 if the typeface has no characters, but if the character
        that is asked for is not found, it will first try to return a default
        character instead.
    */
    const Path* getOutlineForGlyph (const juce_wchar character) throw();

    /** Tries to find the information describing a glyph for this character.

        If there isn't a glyph specifically for the character it will return
        a default glyph instead; if the typeface is empty, it may return a null
        pointer.
    */
    const TypefaceGlyphInfo* getGlyph (const juce_wchar character) throw();

    /** Deletes all the glyphs and kerning data fom the typeface. */
    void clear() throw();

    /** Adds a glyph to the typeface.

        This is typically only called by the platform-specific code that generates
        the typeface from a system font.
    */
    void addGlyph (const juce_wchar character,
                   const Path& path,
                   const float horizontalSpacing) throw();

    /** Adds a kerning distance to the typeface.

        The extra amount passed in is expressed as a proportion of the font's
        height, normalised to 1.0.

        This is typically only called by the platform-specific code that generates
        the typeface from a system font.
    */
    void addKerningPair (const juce_wchar firstChar,
                         const juce_wchar secondChar,
                         const float extraAmount) throw();

    /** Sets the typeface's name.

        This is typically only called by the platform-specific code that generates
        the typeface from a system font. Calling this method won't actually affect
        the underlying font being used.
    */
    void setName (const String& name) throw();

    /** Sets the font's ascent value, as a proportion of the font height.

        This is typically only called by the platform-specific code that generates
        the typeface from a system font.
    */
    void setAscent (const float newAscent) throw();

    /** Sets the typeface's 'bold' flag.

        This is typically only called by the platform-specific code that generates
        the typeface from a system font.
    */
    void setBold (const bool shouldBeBold) throw();

    /** Sets the typeface's 'italic' flag.

        This is typically only called by the platform-specific code that generates
        the typeface from a system font.
    */
    void setItalic (const bool shouldBeItalic) throw();

    /** Changes the character index to use as the default character.

        This is the character that gets returned for characters which don't have a
        glyph set for them.
    */
    void setDefaultCharacter (const juce_wchar newDefaultCharacter) throw();

    /** Creates a typeface from data created using Typeface::serialise().

        This will attempt to load a compressed typeface that was created using
        the Typeface::serialise() method. This is handy if you want to store
        a typeface in your application as a binary blob, and use it without
        having to actually install it on the computer.

        @see Typeface::serialise()
    */
    Typeface (InputStream& serialisedTypefaceStream);

    /** Writes the typeface to a stream (using a proprietary format).

        This lets you save a typeface and reload it using the
        Typeface::Typeface (InputStream&) constructor. The data's saved in
        a compressed format.

        @see Typeface::Typeface (InputStream&)
    */
    void serialise (OutputStream& outputStream);

    /** A name that represents the default sans-serif typeface name.

        Note that this is NOT the platform-specific typeface name (e.g. "Times"), but
        is a generic string that represents whatever that font is, such as "DefaultSans".

        If you try to create a typeface with this name, the global default LookAndFeel
        object will be asked to provide an appropriate typeface.
    */
    static const tchar* defaultTypefaceNameSans;

    /** A name that represents the default serif typeface name.

        Note that this is NOT the platform-specific typeface name (e.g. "Times"), but
        is a generic string that represents it, such as "DefaultSans".

        If you try to create a typeface with this name, the global default LookAndFeel
        object will be asked to provide an appropriate typeface.
    */
    static const tchar* defaultTypefaceNameSerif;

    /** A name that represents the default monospaced typeface name.

        Note that this is NOT the platform-specific typeface name (e.g. "Times"), but
        is a generic string that represents it, such as "DefaultSans".

        If you try to create a typeface with this name, the global default LookAndFeel
        object will be asked to provide an appropriate typeface.
    */
    static const tchar* defaultTypefaceNameMono;

    /** A handy typedef to make it easy to use ref counted pointers to this class. */
    typedef ReferenceCountedObjectPtr <Typeface> Ptr;

    juce_UseDebuggingNewOperator

private:
    VoidArray glyphs;
    short lookupTable [128];

    String typefaceName;
    int hash;
    float ascent; // as a proportion of the height
    bool bold, italic, isFullyPopulated;
    juce_wchar defaultCharacter; // the char to use if a matching glyph can't be found.

    Typeface() throw();
    void addGlyphCopy (const TypefaceGlyphInfo* const glyphInfoToCopy) throw();

    friend class Font;
    friend class TypefaceCache;
    friend class FontGlyphAlphaMap;

    static const Ptr getTypefaceFor (const Font& font) throw();

    // this is a platform-dependent method that will look for the given typeface
    // and set up its kerning tables, etc. accordingly.
    // If addAllGlyphsToFont is true, it should also add all the glyphs in the font
    // to the typeface immediately, rather than having to add them later on-demand.
    void initialiseTypefaceCharacteristics (const String& fontName,
                                            bool bold, bool italic,
                                            bool addAllGlyphsToFont) throw();

    // platform-specific routine to look up and add a glyph to this typeface
    bool findAndAddSystemGlyph (juce_wchar character) throw();

    void updateHashCode() throw();

    friend class LookAndFeel;
    static void getDefaultFontNames (String& defaultSans, String& defaultSerif, String& defaultFixed) throw();
};

#endif   // __JUCE_TYPEFACE_JUCEHEADER__
/********* End of inlined file: juce_Typeface.h *********/

/**
    Represents a particular font, including its size, style, etc.

    Apart from the typeface to be used, a Font object also dictates whether
    the font is bold, italic, underlined, how big it is, and its kerning and
    horizontal scale factor.

    @see Typeface
*/
class JUCE_API  Font
{
public:

    /** A combination of these values is used by the constructor to specify the
        style of font to use.
    */
    enum FontStyleFlags
    {
        plain       = 0,    /**< indicates a plain, non-bold, non-italic version of the font. @see setStyleFlags */
        bold        = 1,    /**< boldens the font. @see setStyleFlags */
        italic      = 2,    /**< finds an italic version of the font. @see setStyleFlags */
        underlined  = 4     /**< underlines the font. @see setStyleFlags */
    };

    /** Creates a sans-serif font in a given size.

        @param fontHeight   the height in pixels (can be fractional)
        @param styleFlags   the style to use - this can be a combination of the
                            Font::bold, Font::italic and Font::underlined, or
                            just Font::plain for the normal style.
        @see FontStyleFlags, getDefaultSansSerifFontName
    */
    Font (const float fontHeight,
          const int styleFlags = plain) throw();

    /** Creates a font with a given typeface and parameters.

        @param typefaceName the name of the typeface to use
        @param fontHeight   the height in pixels (can be fractional)
        @param styleFlags   the style to use - this can be a combination of the
                            Font::bold, Font::italic and Font::underlined, or
                            just Font::plain for the normal style.
        @see FontStyleFlags, getDefaultSansSerifFontName
    */
    Font (const String& typefaceName,
          const float fontHeight,
          const int styleFlags) throw();

    /** Creates a copy of another Font object. */
    Font (const Font& other) throw();

    /** Creates a font based on a typeface.

        The font object stores its own internal copy of the typeface, so you can safely
        delete the one passed in after calling this.
    */
    Font (const Typeface& typeface) throw();

    /** Creates a basic sans-serif font at a default height.

        You should use one of the other constructors for creating a font that you're planning
        on drawing with - this constructor is here to help initialise objects before changing
        the font's settings later.
    */
    Font() throw();

    /** Copies this font from another one. */
    const Font& operator= (const Font& other) throw();

    bool operator== (const Font& other) const throw();
    bool operator!= (const Font& other) const throw();

    /** Destructor. */
    ~Font() throw();

    /** Changes the name of the typeface family.

        e.g. "Arial", "Courier", etc.

        This may also be set to Typeface::defaultTypefaceNameSans, Typeface::defaultTypefaceNameSerif,
        or Typeface::defaultTypefaceNameMono, which are not actual platform-specific font names, but
        are generic names that are used to represent the various default fonts.

        If a suitable font isn't found on the machine, it'll just use a default instead.
    */
    void setTypefaceName (const String& faceName) throw();

    /** Returns the name of the typeface family that this font uses.

        e.g. "Arial", "Courier", etc.

        Note that this may also be one of the values: Typeface::defaultTypefaceNameSans,
        Typeface::defaultTypefaceNameSerif, or Typeface::defaultTypefaceNameMono, which are not actual
        platform-specific font names, but are generic names that are used to represent the various
        default fonts. If you need to know the exact typeface name being used, you can call
        Font::getTypeface()->getTypefaceName(), which will give you the platform-specific name.
    */
    const String& getTypefaceName() const throw()               { return typefaceName; }

    /** Returns a typeface name that represents the default sans-serif font.

        This is also the typeface that will be used when a font is created without
        specifying any typeface details.

        Note that this method just returns the same value as Typeface::defaultTypefaceNameSans,
        which is a generic placeholder string, and not a platform-specific font name.

        @see Typeface::defaultTypefaceNameSans, setTypefaceName, getDefaultSerifFontName, getDefaultMonospacedFontName,
    */
    static const String getDefaultSansSerifFontName() throw()       { return Typeface::defaultTypefaceNameSans; }

    /** Returns a typeface name that represents the default sans-serif font.

        Note that this method just returns the same value as Typeface::defaultTypefaceNameSerif,
        which is a generic placeholder string, and not a platform-specific font name.

        @see Typeface::defaultTypefaceNameSerif, setTypefaceName, getDefaultSansSerifFontName, getDefaultMonospacedFontName
    */
    static const String getDefaultSerifFontName() throw()           { return Typeface::defaultTypefaceNameSerif; }

    /** Returns a typeface name that represents the default sans-serif font.

        Note that this method just returns the same value as Typeface::defaultTypefaceNameMono,
        which is a generic placeholder string, and not a platform-specific font name.

        @see Typeface::defaultTypefaceNameMono, setTypefaceName, getDefaultSansSerifFontName, getDefaultSerifFontName
    */
    static const String getDefaultMonospacedFontName() throw()      { return Typeface::defaultTypefaceNameMono; }

    /** Returns the total height of this font.

        This is the maximum height, from the top of the ascent to the bottom of the
        descenders.

        @see setHeight, setHeightWithoutChangingWidth, getAscent
    */
    float getHeight() const throw()                             { return height; }

    /** Changes the font's height.

        @see getHeight, setHeightWithoutChangingWidth
    */
    void setHeight (float newHeight) throw();

    /** Changes the font's height without changing its width.

        This alters the horizontal scale to compensate for the change in height.
    */
    void setHeightWithoutChangingWidth (float newHeight) throw();

    /** Returns the height of the font above its baseline.

        This is the maximum height from the baseline to the top.

        @see getHeight, getDescent
    */
    float getAscent() const throw();

    /** Returns the amount that the font descends below its baseline.

        This is calculated as (getHeight() - getAscent()).

        @see getAscent, getHeight
    */
    float getDescent() const throw();

    /** Returns the font's style flags.

        This will return a bitwise-or'ed combination of values from the FontStyleFlags
        enum, to describe whether the font is bold, italic, etc.

        @see FontStyleFlags
    */
    int getStyleFlags() const throw()                           { return styleFlags; }

    /** Changes the font's style.

        @param newFlags     a bitwise-or'ed combination of values from the FontStyleFlags
                            enum, to set the font's properties
        @see FontStyleFlags
    */
    void setStyleFlags (const int newFlags) throw();

    /** Makes the font bold or non-bold. */
    void setBold (const bool shouldBeBold) throw();
    /** Returns true if the font is bold. */
    bool isBold() const throw();

    /** Makes the font italic or non-italic. */
    void setItalic (const bool shouldBeItalic) throw();
    /** Returns true if the font is italic. */
    bool isItalic() const throw();

    /** Makes the font underlined or non-underlined. */
    void setUnderline (const bool shouldBeUnderlined) throw();
    /** Returns true if the font is underlined. */
    bool isUnderlined() const throw();

    /** Changes the font's horizontal scale factor.

        @param scaleFactor  a value of 1.0 is the normal scale, less than this will be
                            narrower, greater than 1.0 will be stretched out.
    */
    void setHorizontalScale (const float scaleFactor) throw();

    /** Returns the font's horizontal scale.

        A value of 1.0 is the normal scale, less than this will be narrower, greater
        than 1.0 will be stretched out.

        @see setHorizontalScale
    */
    float getHorizontalScale() const throw()                { return horizontalScale; }

    /** Changes the font's kerning.

        @param extraKerning     a multiple of the font's height that will be added
                                to space between the characters. So a value of zero is
                                normal spacing, positive values spread the letters out,
                                negative values make them closer together.
    */
    void setExtraKerningFactor (const float extraKerning) throw();

    /** Returns the font's kerning.

        This is the extra space added between adjacent characters, as a proportion
        of the font's height.

        A value of zero is normal spacing, positive values will spread the letters
        out more, and negative values make them closer together.
    */
    float getExtraKerningFactor() const throw()             { return kerning; }

    /** Changes all the font's characteristics with one call. */
    void setSizeAndStyle (const float newHeight,
                          const int newStyleFlags,
                          const float newHorizontalScale,
                          const float newKerningAmount) throw();

    /** Resets this font's characteristics.

        This is basically like saying "myFont = Font();", because it resets the
        typeface, size, style, etc to a default state. Not very useful to most
        people, its raison d'etre is to help the Graphics class be more efficient.
    */
    void resetToDefaultState() throw();

    /** Returns the total width of a string as it would be drawn using this font.

        For a more accurate floating-point result, use getStringWidthFloat().
    */
    int getStringWidth (const String& text) const throw();

    /** Returns the total width of a string as it would be drawn using this font.

        @see getStringWidth
    */
    float getStringWidthFloat (const String& text) const throw();

    /** Returns the typeface used by this font.

        Note that the object returned may go out of scope if this font is deleted
        or has its style changed.
    */
    Typeface* getTypeface() const throw();

    /** Creates an array of Font objects to represent all the fonts on the system.

        If you just need the names of the typefaces, you can also use
        findAllTypefaceNames() instead.

        @param results  the array to which new Font objects will be added.
    */
    static void findFonts (OwnedArray<Font>& results) throw();

    /** Returns a list of all the available typeface names.

        The names returned can be passed into setTypefaceName().

        You can use this instead of findFonts() if you only need their names, and not
        font objects.
    */
    static const StringArray findAllTypefaceNames() throw();

    /** Returns the name of the typeface to be used for rendering glyphs that aren't found
        in the requested typeface.
    */
    static const String getFallbackFontName() throw();

    /** Sets the (platform-specific) name of the typeface to use to find glyphs that aren't
        available in whatever font you're trying to use.
    */
    static void setFallbackFontName (const String& name) throw();

    juce_UseDebuggingNewOperator

private:

    friend class FontGlyphAlphaMap;
    friend class TypefaceCache;

    String typefaceName;
    float height, horizontalScale, kerning;
    mutable float ascent;
    int styleFlags;
    mutable Typeface::Ptr typeface;
};

#endif   // __JUCE_FONT_JUCEHEADER__
/********* End of inlined file: juce_Font.h *********/

/********* Start of inlined file: juce_Rectangle.h *********/
#ifndef __JUCE_RECTANGLE_JUCEHEADER__
#define __JUCE_RECTANGLE_JUCEHEADER__

/**
    A rectangle, specified using integer co-ordinates.

    @see RectangleList, Path, Line, Point
*/
class JUCE_API  Rectangle
{
public:

    /** Creates a rectangle of zero size.

        The default co-ordinates will be (0, 0, 0, 0).
    */
    Rectangle() throw();

    /** Creates a copy of another rectangle. */
    Rectangle (const Rectangle& other) throw();

    /** Creates a rectangle with a given position and size. */
    Rectangle (const int x, const int y,
               const int width, const int height) throw();

    /** Creates a rectangle with a given size, and a position of (0, 0). */
    Rectangle (const int width, const int height) throw();

    /** Destructor. */
    ~Rectangle() throw();

    /** Returns the x co-ordinate of the rectangle's left-hand-side. */
    inline int getX() const throw()                         { return x; }

    /** Returns the y co-ordinate of the rectangle's top edge. */
    inline int getY() const throw()                         { return y; }

    /** Returns the width of the rectangle. */
    inline int getWidth() const throw()                     { return w; }

    /** Returns the height of the rectangle. */
    inline int getHeight() const throw()                    { return h; }

    /** Returns the x co-ordinate of the rectangle's right-hand-side. */
    inline int getRight() const throw()                     { return x + w; }

    /** Returns the y co-ordinate of the rectangle's bottom edge. */
    inline int getBottom() const throw()                    { return y + h; }

    /** Returns the x co-ordinate of the rectangle's centre. */
    inline int getCentreX() const throw()                   { return x + (w >> 1); }

    /** Returns the y co-ordinate of the rectangle's centre. */
    inline int getCentreY() const throw()                   { return y + (h >> 1); }

    /** Returns true if the rectangle's width and height are both zero or less */
    bool isEmpty() const throw();

    /** Changes the position of the rectangle's top-left corner (leaving its size unchanged). */
    void setPosition (const int x, const int y) throw();

    /** Changes the rectangle's size, leaving the position of its top-left corner unchanged. */
    void setSize (const int w, const int h) throw();

    /** Changes all the rectangle's co-ordinates. */
    void setBounds (const int newX, const int newY,
                    const int newWidth, const int newHeight) throw();

    /** Moves the x position, adjusting the width so that the right-hand edge remains in the same place.
        If the x is moved to be on the right of the current right-hand edge, the width will be set to zero.
    */
    void setLeft (const int newLeft) throw();

    /** Moves the y position, adjusting the height so that the bottom edge remains in the same place.
        If the y is moved to be below the current bottom edge, the height will be set to zero.
    */
    void setTop (const int newTop) throw();

    /** Adjusts the width so that the right-hand edge of the rectangle has this new value.
        If the new right is below the current X value, the X will be pushed down to match it.
        @see getRight
    */
    void setRight (const int newRight) throw();

    /** Adjusts the height so that the bottom edge of the rectangle has this new value.
        If the new bottom is lower than the current Y value, the Y will be pushed down to match it.
        @see getBottom
    */
    void setBottom (const int newBottom) throw();

    /** Moves the rectangle's position by adding amount to its x and y co-ordinates. */
    void translate (const int deltaX,
                    const int deltaY) throw();

    /** Returns a rectangle which is the same as this one moved by a given amount. */
    const Rectangle translated (const int deltaX,
                                const int deltaY) const throw();

    /** Expands the rectangle by a given amount.

        Effectively, its new size is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2).
        @see expanded, reduce, reduced
    */
    void expand (const int deltaX,
                 const int deltaY) throw();

    /** Returns a rectangle that is larger than this one by a given amount.

        Effectively, the rectangle returned is (x - deltaX, y - deltaY, w + deltaX * 2, h + deltaY * 2).
        @see expand, reduce, reduced
    */
    const Rectangle expanded (const int deltaX,
                              const int deltaY) const throw();

    /** Shrinks the rectangle by a given amount.

        Effectively, its new size is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2).
        @see reduced, expand, expanded
    */
    void reduce (const int deltaX,
                 const int deltaY) throw();

    /** Returns a rectangle that is smaller than this one by a given amount.

        Effectively, the rectangle returned is (x + deltaX, y + deltaY, w - deltaX * 2, h - deltaY * 2).
        @see reduce, expand, expanded
    */
    const Rectangle reduced (const int deltaX,
                             const int deltaY) const throw();

    /** Returns true if the two rectangles are identical. */
    bool operator== (const Rectangle& other) const throw();

    /** Returns true if the two rectangles are not identical. */
    bool operator!= (const Rectangle& other) const throw();

    /** Returns true if this co-ordinate is inside the rectangle. */
    bool contains (const int x, const int y) const throw();

    /** Returns true if this other rectangle is completely inside this one. */
    bool contains (const Rectangle& other) const throw();

    /** Returns true if any part of another rectangle overlaps this one. */
    bool intersects (const Rectangle& other) const throw();

    /** Returns the region that is the overlap between this and another rectangle.

        If the two rectangles don't overlap, the rectangle returned will be empty.
    */
    const Rectangle getIntersection (const Rectangle& other) const throw();

    /** Clips a rectangle so that it lies only within this one.

        This is a non-static version of intersectRectangles().

        Returns false if the two regions didn't overlap.
    */
    bool intersectRectangle (int& x, int& y, int& w, int& h) const throw();

    /** Returns the smallest rectangle that contains both this one and the one
        passed-in.
    */
    const Rectangle getUnion (const Rectangle& other) const throw();

    /** If this rectangle merged with another one results in a simple rectangle, this
        will set this rectangle to the result, and return true.

        Returns false and does nothing to this rectangle if the two rectangles don't overlap,
        or if they form a complex region.
    */
    bool enlargeIfAdjacent (const Rectangle& other) throw();

    /** If after removing another rectangle from this one the result is a simple rectangle,
        this will set this object's bounds to be the result, and return true.

        Returns false and does nothing to this rectangle if the two rectangles don't overlap,
        or if removing the other one would form a complex region.
    */
    bool reduceIfPartlyContainedIn (const Rectangle& other) throw();

    /** Static utility to intersect two sets of rectangular co-ordinates.

        Returns false if the two regions didn't overlap.

        @see intersectRectangle
    */
    static bool intersectRectangles (int& x1, int& y1, int& w1, int& h1,
                                     int x2, int y2, int w2, int h2) throw();

    /** Creates a string describing this rectangle.

        The string will be of the form "x y width height", e.g. "100 100 400 200".

        Coupled with the fromString() method, this is very handy for things like
        storing rectangles (particularly component positions) in XML attributes.

        @see fromString
    */
    const String toString() const throw();

    /** Parses a string containing a rectangle's details.

        The string should contain 4 integer tokens, in the form "x y width height". They
        can be comma or whitespace separated.

        This method is intended to go with the toString() method, to form an easy way
        of saving/loading rectangles as strings.

        @see toString
    */
    static const Rectangle fromString (const String& stringVersion);

    juce_UseDebuggingNewOperator

private:
    friend class RectangleList;
    int x, y, w, h;
};

#endif   // __JUCE_RECTANGLE_JUCEHEADER__
/********* End of inlined file: juce_Rectangle.h *********/

/********* Start of inlined file: juce_PathStrokeType.h *********/
#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__
#define __JUCE_PATHSTROKETYPE_JUCEHEADER__

/**
    Describes a type of stroke used to render a solid outline along a path.

    A PathStrokeType object can be used directly to create the shape of an outline
    around a path, and is used by Graphics::strokePath to specify the type of
    stroke to draw.

    @see Path, Graphics::strokePath
*/
class JUCE_API  PathStrokeType
{
public:

    /** The type of shape to use for the corners between two adjacent line segments. */
    enum JointStyle
    {
        mitered,    /**< Indicates that corners should be drawn with sharp joints.
                         Note that for angles that curve back on themselves, drawing a
                         mitre could require extending the point too far away from the
                         path, so a mitre limit is imposed and any corners that exceed it
                         are drawn as bevelled instead. */
        curved,     /**< Indicates that corners should be drawn as rounded-off. */
        beveled     /**< Indicates that corners should be drawn with a line flattening their
                         outside edge. */
    };

    /** The type shape to use for the ends of lines. */
    enum EndCapStyle
    {
        butt,       /**< Ends of lines are flat and don't extend beyond the end point. */
        square,     /**< Ends of lines are flat, but stick out beyond the end point for half
                         the thickness of the stroke. */
        rounded     /**< Ends of lines are rounded-off with a circular shape. */
    };

    /** Creates a stroke type.

        @param strokeThickness      the width of the line to use
        @param jointStyle           the type of joints to use for corners
        @param endStyle             the type of end-caps to use for the ends of open paths.
    */
    PathStrokeType (const float strokeThickness,
                    const JointStyle jointStyle = mitered,
                    const EndCapStyle endStyle = butt) throw();

    /** Createes a copy of another stroke type. */
    PathStrokeType (const PathStrokeType& other) throw();

    /** Copies another stroke onto this one. */
    const PathStrokeType& operator= (const PathStrokeType& other) throw();

    /** Destructor. */
    ~PathStrokeType() throw();

    /** Applies this stroke type to a path and returns the resultant stroke as another Path.

        @param destPath         the resultant stroked outline shape will be copied into this path.
                                Note that it's ok for the source and destination Paths to be
                                the same object, so you can easily turn a path into a stroked version
                                of itself.
        @param sourcePath       the path to use as the source
        @param transform        an optional transform to apply to the points from the source path
                                as they are being used
        @param extraAccuracy    if this is greater than 1.0, it will subdivide the path to
                                a higher resolution, which improved the quality if you'll later want
                                to enlarge the stroked path

        @see createDashedStroke
    */
    void createStrokedPath (Path& destPath,
                            const Path& sourcePath,
                            const AffineTransform& transform = AffineTransform::identity,
                            const float extraAccuracy = 1.0f) const throw();

    /** Applies this stroke type to a path, creating a dashed line.

        This is similar to createStrokedPath, but uses the array passed in to
        break the stroke up into a series of dashes.

        @param destPath         the resultant stroked outline shape will be copied into this path.
                                Note that it's ok for the source and destination Paths to be
                                the same object, so you can easily turn a path into a stroked version
                                of itself.
        @param sourcePath       the path to use as the source
        @param dashLengths      An array of alternating on/off lengths. E.g. { 2, 3, 4, 5 } will create
                                a line of length 2, then skip a length of 3, then add a line of length 4,
                                skip 5, and keep repeating this pattern.
        @param numDashLengths   The number of lengths in the dashLengths array. This should really be
                                an even number, otherwise the pattern will get out of step as it
                                repeats.
        @param transform        an optional transform to apply to the points from the source path
                                as they are being used
        @param extraAccuracy    if this is greater than 1.0, it will subdivide the path to
                                a higher resolution, which improved the quality if you'll later want
                                to enlarge the stroked path
    */
    void createDashedStroke (Path& destPath,
                             const Path& sourcePath,
                             const float* dashLengths,
                             int numDashLengths,
                             const AffineTransform& transform = AffineTransform::identity,
                             const float extraAccuracy = 1.0f) const throw();

    /** Returns the stroke thickness. */
    float getStrokeThickness() const throw()                    { return thickness; }

    /** Returns the joint style. */
    JointStyle getJointStyle() const throw()                    { return jointStyle; }

    /** Returns the end-cap style. */
    EndCapStyle getEndStyle() const throw()                     { return endStyle; }

    juce_UseDebuggingNewOperator

    /** Compares the stroke thickness, joint and end styles of two stroke types. */
    bool operator== (const PathStrokeType& other) const throw();

    /** Compares the stroke thickness, joint and end styles of two stroke types. */
    bool operator!= (const PathStrokeType& other) const throw();

private:

    float thickness;
    JointStyle jointStyle;
    EndCapStyle endStyle;
};

#endif   // __JUCE_PATHSTROKETYPE_JUCEHEADER__
/********* End of inlined file: juce_PathStrokeType.h *********/

/********* Start of inlined file: juce_Line.h *********/
#ifndef __JUCE_LINE_JUCEHEADER__
#define __JUCE_LINE_JUCEHEADER__

/**
    Represents a line, using 32-bit float co-ordinates.

    This class contains a bunch of useful methods for various geometric
    tasks.

    @see Point, Rectangle, Path, Graphics::drawLine
*/
class JUCE_API  Line
{
public:

    /** Creates a line, using (0, 0) as its start and end points. */
    Line() throw();

    /** Creates a copy of another line. */
    Line (const Line& other) throw();

    /** Creates a line based on the co-ordinates of its start and end points. */
    Line (const float startX,
          const float startY,
          const float endX,
          const float endY) throw();

    /** Creates a line from its start and end points. */
    Line (const Point& start,
          const Point& end) throw();

    /** Copies a line from another one. */
    const Line& operator= (const Line& other) throw();

    /** Destructor. */
    ~Line() throw();

    /** Returns the x co-ordinate of the line's start point. */
    inline float getStartX() const throw()                              { return startX; }

    /** Returns the y co-ordinate of the line's start point. */
    inline float getStartY() const throw()                              { return startY; }

    /** Returns the x co-ordinate of the line's end point. */
    inline float getEndX() const throw()                                { return endX; }

    /** Returns the y co-ordinate of the line's end point. */
    inline float getEndY() const throw()                                { return endY; }

    /** Returns the line's start point. */
    const Point getStart() const throw();

    /** Returns the line's end point. */
    const Point getEnd() const throw();

    /** Changes this line's start point */
    void setStart (const float newStartX,
                   const float newStartY) throw();

    /** Changes this line's end point */
    void setEnd (const float newEndX,
                 const float newEndY) throw();

    /** Changes this line's start point */
    void setStart (const Point& newStart) throw();

    /** Changes this line's end point */
    void setEnd (const Point& newEnd) throw();

    /** Applies an affine transform to the line's start and end points. */
    void applyTransform (const AffineTransform& transform) throw();

    /** Returns the length of the line. */
    float getLength() const throw();

    /** Returns true if the line's start and end x co-ordinates are the same. */
    bool isVertical() const throw();

    /** Returns true if the line's start and end y co-ordinates are the same. */
    bool isHorizontal() const throw();

    /** Returns the line's angle.

        This value is the number of radians clockwise from the 3 o'clock direction,
        where the line's start point is considered to be at the centre.
    */
    float getAngle() const throw();

    /** Compares two lines. */
    bool operator== (const Line& other) const throw();

    /** Compares two lines. */
    bool operator!= (const Line& other) const throw();

    /** Finds the intersection between two lines.

        @param line             the other line
        @param intersectionX    the x co-ordinate of the point where the lines meet (or
                                where they would meet if they were infinitely long)
                                the intersection (if the lines intersect). If the lines
                                are parallel, this will just be set to the position
                                of one of the line's endpoints.
        @param intersectionY    the y co-ordinate of the point where the lines meet
        @returns    true if the line segments intersect; false if they dont. Even if they
                    don't intersect, the intersection co-ordinates returned will still
                    be valid
    */
    bool intersects (const Line& line,
                     float& intersectionX,
                     float& intersectionY) const throw();

    /** Returns the location of the point which is a given distance along this line.

        @param distanceFromStart    the distance to move along the line from its
                                    start point. This value can be negative or longer
                                    than the line itself
        @see getPointAlongLineProportionally
    */
    const Point getPointAlongLine (const float distanceFromStart) const throw();

    /** Returns a point which is a certain distance along and to the side of this line.

        This effectively moves a given distance along the line, then another distance
        perpendicularly to this, and returns the resulting position.

        @param distanceFromStart    the distance to move along the line from its
                                    start point. This value can be negative or longer
                                    than the line itself
        @param perpendicularDistance    how far to move sideways from the line. If you're
                                    looking along the line from its start towards its
                                    end, then a positive value here will move to the
                                    right, negative value move to the left.
    */
    const Point getPointAlongLine (const float distanceFromStart,
                                   const float perpendicularDistance) const throw();

    /** Returns the location of the point which is a given distance along this line
        proportional to the line's length.

        @param proportionOfLength   the distance to move along the line from its
                                    start point, in multiples of the line's length.
                                    So a value of 0.0 will return the line's start point
                                    and a value of 1.0 will return its end point. (This value
                                    can be negative or greater than 1.0).
        @see getPointAlongLine
    */
    const Point getPointAlongLineProportionally (const float proportionOfLength) const throw();

    /** Returns the smallest distance between this line segment and a given point.

        So if the point is close to the line, this will return the perpendicular
        distance from the line; if the point is a long way beyond one of the line's
        end-point's, it'll return the straight-line distance to the nearest end-point.

        @param x    x position of the point to test
        @param y    y position of the point to test
        @returns the point's distance from the line
        @see getPositionAlongLineOfNearestPoint
    */
    float getDistanceFromLine (const float x,
                               const float y) const throw();

    /** Finds the point on this line which is nearest to a given point, and
        returns its position as a proportional position along the line.

        @param x    x position of the point to test
        @param y    y position of the point to test
        @returns    a value 0 to 1.0 which is the distance along this line from the
                    line's start to the point which is nearest to the point passed-in. To
                    turn this number into a position, use getPointAlongLineProportionally().
        @see getDistanceFromLine, getPointAlongLineProportionally
    */
    float findNearestPointTo (const float x,
                              const float y) const throw();

    /** Returns true if the given point lies above this line.

        The return value is true if the point's y coordinate is less than the y
        coordinate of this line at the given x (assuming the line extends infinitely
        in both directions).
    */
    bool isPointAbove (const float x, const float y) const throw();

    /** Returns a shortened copy of this line.

        This will chop off part of the start of this line by a certain amount, (leaving the
        end-point the same), and return the new line.
    */
    const Line withShortenedStart (const float distanceToShortenBy) const throw();

    /** Returns a shortened copy of this line.

        This will chop off part of the end of this line by a certain amount, (leaving the
        start-point the same), and return the new line.
    */
    const Line withShortenedEnd (const float distanceToShortenBy) const throw();

    /** Cuts off parts of this line to keep the parts that are either inside or
        outside a path.

        Note that this isn't smart enough to cope with situations where the
        line would need to be cut into multiple pieces to correctly clip against
        a re-entrant shape.

        @param path                     the path to clip against
        @param keepSectionOutsidePath   if true, it's the section outside the path
                                        that will be kept; if false its the section inside
                                        the path
        @returns true if the line was changed.
    */
    bool clipToPath (const Path& path,
                     const bool keepSectionOutsidePath) throw();

    juce_UseDebuggingNewOperator

private:
    float startX, startY, endX, endY;
};

#endif   // __JUCE_LINE_JUCEHEADER__
/********* End of inlined file: juce_Line.h *********/

/********* Start of inlined file: juce_Colours.h *********/
#ifndef __JUCE_COLOURS_JUCEHEADER__
#define __JUCE_COLOURS_JUCEHEADER__

/********* Start of inlined file: juce_Colour.h *********/
#ifndef __JUCE_COLOUR_JUCEHEADER__
#define __JUCE_COLOUR_JUCEHEADER__

/********* Start of inlined file: juce_PixelFormats.h *********/
#ifndef __JUCE_PIXELFORMATS_JUCEHEADER__
#define __JUCE_PIXELFORMATS_JUCEHEADER__

#if JUCE_MSVC
  #pragma pack (push, 1)
  #define PACKED
#elif JUCE_GCC
  #define PACKED __attribute__((packed))
#else
  #define PACKED
#endif

/**
    Represents a 32-bit ARGB pixel with premultiplied alpha, and can perform compositing
    operations with it.

    This is used internally by the imaging classes.

    @see PixelRGB
*/
class JUCE_API  PixelARGB
{
public:
    /** Creates a pixel without defining its colour. */
    PixelARGB() throw() {}
    ~PixelARGB() throw() {}

    /** Creates a pixel from a 32-bit argb value.
    */
    PixelARGB (const uint32 argb_) throw()
        : argb (argb_)
    {
    }

    forcedinline uint32 getARGB() const throw()     { return argb; }
    forcedinline uint32 getRB() const throw()       { return 0x00ff00ff & argb; }
    forcedinline uint32 getAG() const throw()       { return 0x00ff00ff & (argb >> 8); }

    forcedinline uint8 getAlpha() const throw()     { return components.a; }
    forcedinline uint8 getRed() const throw()       { return components.r; }
    forcedinline uint8 getGreen() const throw()     { return components.g; }
    forcedinline uint8 getBlue() const throw()      { return components.b; }

    /** Blends another pixel onto this one.

        This takes into account the opacity of the pixel being overlaid, and blends
        it accordingly.
    */
    template <class Pixel>
    forcedinline void blend (const Pixel& src) throw()
    {
        uint32 sargb = src.getARGB();
        const uint32 alpha = 0x100 - (sargb >> 24);

        sargb += 0x00ff00ff & ((getRB() * alpha) >> 8);
        sargb += 0xff00ff00 & (getAG() * alpha);

        argb = sargb;
    }

    /** Blends another pixel onto this one, applying an extra multiplier to its opacity.

        The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
        being used, so this can blend semi-transparently from a PixelRGB argument.
    */
    template <class Pixel>
    forcedinline void blend (const Pixel& src, uint32 extraAlpha) throw()
    {
        ++extraAlpha;

        uint32 sargb = ((extraAlpha * src.getAG()) & 0xff00ff00)
                         | (((extraAlpha * src.getRB()) >> 8) & 0x00ff00ff);

        const uint32 alpha = 0x100 - (sargb >> 24);

        sargb += 0x00ff00ff & ((getRB() * alpha) >> 8);
        sargb += 0xff00ff00 & (getAG() * alpha);

        argb = sargb;
    }

    /** Blends another pixel with this one, creating a colour that is somewhere
        between the two, as specified by the amount.
    */
    template <class Pixel>
    forcedinline void tween (const Pixel& src, const uint32 amount) throw()
    {
        uint32 drb = getRB();
        drb += (((src.getRB() - drb) * amount) >> 8);
        drb &= 0x00ff00ff;

        uint32 dag = getAG();
        dag += (((src.getAG() - dag) * amount) >> 8);
        dag &= 0x00ff00ff;
        dag <<= 8;

        dag |= drb;
        argb = dag;
    }

    /** Copies another pixel colour over this one.

        This doesn't blend it - this colour is simply replaced by the other one.
    */
    template <class Pixel>
    forcedinline void set (const Pixel& src) throw()
    {
        argb = src.getARGB();
    }

    /** Replaces the colour's alpha value with another one. */
    forcedinline void setAlpha (const uint8 newAlpha) throw()
    {
        components.a = newAlpha;
    }

    /** Multiplies the colour's alpha value with another one. */
    forcedinline void multiplyAlpha (int multiplier) throw()
    {
        ++multiplier;

        argb = ((multiplier * getAG()) & 0xff00ff00)
                | (((multiplier * getRB()) >> 8) & 0x00ff00ff);
    }

    forcedinline void multiplyAlpha (const float multiplier) throw()
    {
        multiplyAlpha ((int) (multiplier * 256.0f));
    }

    /** Sets the pixel's colour from individual components. */
    void setARGB (const uint8 a, const uint8 r, const uint8 g, const uint8 b) throw()
    {
        components.b = b;
        components.g = g;
        components.r = r;
        components.a = a;
    }

    /** Premultiplies the pixel's RGB values by its alpha. */
    forcedinline void premultiply() throw()
    {
        const uint32 alpha = components.a;

        if (alpha < 0xff)
        {
            if (alpha == 0)
            {
                components.b = 0;
                components.g = 0;
                components.r = 0;
            }
            else
            {
                components.b = (uint8) ((components.b * alpha + 0x7f) >> 8);
                components.g = (uint8) ((components.g * alpha + 0x7f) >> 8);
                components.r = (uint8) ((components.r * alpha + 0x7f) >> 8);
            }
        }
    }

    /** Unpremultiplies the pixel's RGB values. */
    forcedinline void unpremultiply() throw()
    {
        const uint32 alpha = components.a;

        if (alpha < 0xff)
        {
            if (alpha == 0)
            {
                components.b = 0;
                components.g = 0;
                components.r = 0;
            }
            else
            {
                components.b = (uint8) jmin (0xff, (components.b * 0xff) / alpha);
                components.g = (uint8) jmin (0xff, (components.g * 0xff) / alpha);
                components.r = (uint8) jmin (0xff, (components.r * 0xff) / alpha);
            }
        }
    }

    forcedinline void desaturate() throw()
    {
        if (components.a < 0xff && components.a > 0)
        {
            const int newUnpremultipliedLevel = (0xff * ((int) components.r + (int) components.g + (int) components.b) / (3 * components.a));

            components.r = components.g = components.b
                = (uint8) ((newUnpremultipliedLevel * components.a + 0x7f) >> 8);
        }
        else
        {
            components.r = components.g = components.b
                = (uint8) (((int) components.r + (int) components.g + (int) components.b) / 3);
        }
    }

private:

    union
    {
        uint32 argb;

        struct
        {
#if JUCE_BIG_ENDIAN
            uint8 a : 8, r : 8, g : 8, b : 8;
#else
            uint8 b, g, r, a;
#endif
        } PACKED components;
    };

} PACKED;

/**
    Represents a 24-bit RGB pixel, and can perform compositing operations on it.

    This is used internally by the imaging classes.

    @see PixelARGB
*/
class JUCE_API  PixelRGB
{
public:
    /** Creates a pixel without defining its colour. */
    PixelRGB() throw() {}
    ~PixelRGB() throw() {}

    /** Creates a pixel from a 32-bit argb value.

        (The argb format is that used by PixelARGB)
    */
    PixelRGB (const uint32 argb) throw()
    {
        r = (uint8) (argb >> 16);
        g = (uint8) (argb >> 8);
        b = (uint8) (argb);
    }

    forcedinline uint32 getARGB() const throw()     { return 0xff000000 | b | (g << 8) | (r << 16); }
    forcedinline uint32 getRB() const throw()       { return b | (uint32) (r << 16); }
    forcedinline uint32 getAG() const throw()       { return 0xff0000 | g; }

    forcedinline uint8 getAlpha() const throw()     { return 0xff; }
    forcedinline uint8 getRed() const throw()       { return r; }
    forcedinline uint8 getGreen() const throw()     { return g; }
    forcedinline uint8 getBlue() const throw()      { return b; }

    /** Blends another pixel onto this one.

        This takes into account the opacity of the pixel being overlaid, and blends
        it accordingly.
    */
    forcedinline void blend (const PixelARGB& src) throw()
    {
        uint32 sargb = src.getARGB();
        const uint32 alpha = 0x100 - (sargb >> 24);

        sargb += 0x00ff00ff & ((getRB() * alpha) >> 8);
        sargb += 0x0000ff00 & (g * alpha);

        r = (uint8) (sargb >> 16);
        g = (uint8) (sargb >> 8);
        b = (uint8) sargb;
    }

    forcedinline void blend (const PixelRGB& src) throw()
    {
        set (src);
    }

    /** Blends another pixel onto this one, applying an extra multiplier to its opacity.

        The opacity of the pixel being overlaid is scaled by the extraAlpha factor before
        being used, so this can blend semi-transparently from a PixelRGB argument.
    */
    template <class Pixel>
    forcedinline void blend (const Pixel& src, uint32 extraAlpha) throw()
    {
        ++extraAlpha;
        const uint32 srb = (extraAlpha * src.getRB()) >> 8;
        const uint32 sag = extraAlpha * src.getAG();
        uint32 sargb = (sag & 0xff00ff00) | (srb & 0x00ff00ff);

        const uint32 alpha = 0x100 - (sargb >> 24);

        sargb += 0x00ff00ff & ((getRB() * alpha) >> 8);
        sargb += 0x0000ff00 & (g * alpha);

        b = (uint8) sargb;
        g = (uint8) (sargb >> 8);
        r = (uint8) (sargb >> 16);
    }

    /** Blends another pixel with this one, creating a colour that is somewhere
        between the two, as specified by the amount.
    */
    template <class Pixel>
    forcedinline void tween (const Pixel& src, const uint32 amount) throw()
    {
        uint32 drb = getRB();
        drb += (((src.getRB() - drb) * amount) >> 8);

        uint32 dag = getAG();
        dag += (((src.getAG() - dag) * amount) >> 8);

        b = (uint8) drb;
        g = (uint8) dag;
        r = (uint8) (drb >> 16);
    }

    /** Copies another pixel colour over this one.

        This doesn't blend it - this colour is simply replaced by the other one.
        Because PixelRGB has no alpha channel, any alpha value in the source pixel
        is thrown away.
    */
    template <class Pixel>
    forcedinline void set (const Pixel& src) throw()
    {
        b = src.getBlue();
        g = src.getGreen();
        r = src.getRed();
    }

    /** This method is included for compatibility with the PixelARGB class. */
    forcedinline void setAlpha (const uint8) throw() {}

    /** Multiplies the colour's alpha value with another one. */
    forcedinline void multiplyAlpha (int) throw() {}

    /** Sets the pixel's colour from individual components. */
    void setARGB (const uint8, const uint8 r_, const uint8 g_, const uint8 b_) throw()
    {
        r = r_;
        g = g_;
        b = b_;
    }

    /** Premultiplies the pixel's RGB values by its alpha. */
    forcedinline void premultiply() throw() {}

    /** Unpremultiplies the pixel's RGB values. */
    forcedinline void unpremultiply() throw() {}

    forcedinline void desaturate() throw()
    {
        r = g = b = (uint8) (((int) r + (int) g + (int) b) / 3);
    }

private:

#if JUCE_MAC
    uint8 r, g, b;
#else
    uint8 b, g, r;
#endif

} PACKED;

#if JUCE_MSVC
  #pragma pack (pop)
#endif

#undef PACKED

#endif   // __JUCE_PIXELFORMATS_JUCEHEADER__
/********* End of inlined file: juce_PixelFormats.h *********/

/**
    Represents a colour, also including a transparency value.

    The colour is stored internally as unsigned 8-bit red, green, blue and alpha values.
*/
class JUCE_API  Colour
{
public:

    /** Creates a transparent black colour. */
    Colour() throw();

    /** Creates a copy of another Colour object. */
    Colour (const Colour& other) throw();

    /** Creates a colour from a 32-bit ARGB value.

        The format of this number is:
            ((alpha << 24) | (red << 16) | (green << 16) | blue).

        All components in the range 0x00 to 0xff.
        An alpha of 0x00 is completely transparent, alpha of 0xff is opaque.

        @see getPixelARGB
    */
    explicit Colour (const uint32 argb) throw();

    /** Creates an opaque colour using 8-bit red, green and blue values */
    Colour (const uint8 red,
            const uint8 green,
            const uint8 blue) throw();

    /** Creates an opaque colour using 8-bit red, green and blue values */
    static const Colour fromRGB (const uint8 red,
                                 const uint8 green,
                                 const uint8 blue) throw();

    /** Creates a colour using 8-bit red, green, blue and alpha values. */
    Colour (const uint8 red,
            const uint8 green,
            const uint8 blue,
            const uint8 alpha) throw();

    /** Creates a colour using 8-bit red, green, blue and alpha values. */
    static const Colour fromRGBA (const uint8 red,
                                  const uint8 green,
                                  const uint8 blue,
                                  const uint8 alpha) throw();

    /** Creates a colour from 8-bit red, green, and blue values, and a floating-point alpha.

        Alpha of 0.0 is transparent, alpha of 1.0f is opaque.
        Values outside the valid range will be clipped.
    */
    Colour (const uint8 red,
            const uint8 green,
            const uint8 blue,
            const float alpha) throw();

    /** Creates a colour using 8-bit red, green, blue and float alpha values. */
    static const Colour fromRGBAFloat (const uint8 red,
                                       const uint8 green,
                                       const uint8 blue,
                                       const float alpha) throw();

    /** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha.

        The floating point values must be between 0.0 and 1.0.
        An alpha of 0x00 is completely transparent, alpha of 0xff is opaque.
        Values outside the valid range will be clipped.
    */
    Colour (const float hue,
            const float saturation,
            const float brightness,
            const uint8 alpha) throw();

    /** Creates a colour using floating point hue, saturation, brightness and alpha values.

        All values must be between 0.0 and 1.0.
        Numbers outside the valid range will be clipped.
    */
    Colour (const float hue,
            const float saturation,
            const float brightness,
            const float alpha) throw();

    /** Creates a colour using floating point hue, saturation and brightness values, and an 8-bit alpha.

        The floating point values must be between 0.0 and 1.0.
        An alpha of 0x00 is completely transparent, alpha of 0xff is opaque.
        Values outside the valid range will be clipped.
    */
    static const Colour fromHSV (const float hue,
                                 const float saturation,
                                 const float brightness,
                                 const float alpha) throw();

    /** Destructor. */
    ~Colour() throw();

    /** Copies another Colour object. */
    const Colour& operator= (const Colour& other) throw();

    /** Compares two colours. */
    bool operator== (const Colour& other) const throw();
    /** Compares two colours. */
    bool operator!= (const Colour& other) const throw();

    /** Returns the red component of this colour.

        @returns a value between 0x00 and 0xff.
    */
    uint8 getRed() const throw()                        { return argb.getRed(); }

    /** Returns the green component of this colour.

        @returns a value between 0x00 and 0xff.
    */
    uint8 getGreen() const throw()                      { return argb.getGreen(); }

    /** Returns the blue component of this colour.

        @returns a value between 0x00 and 0xff.
    */
    uint8 getBlue() const throw()                       { return argb.getBlue(); }

    /** Returns the red component of this colour as a floating point value.

        @returns a value between 0.0 and 1.0
    */
    float getFloatRed() const throw();

    /** Returns the green component of this colour as a floating point value.

        @returns a value between 0.0 and 1.0
    */
    float getFloatGreen() const throw();

    /** Returns the blue component of this colour as a floating point value.

        @returns a value between 0.0 and 1.0
    */
    float getFloatBlue() const throw();

    /** Returns a premultiplied ARGB pixel object that represents this colour.
    */
    const PixelARGB getPixelARGB() const throw();

    /** Returns a 32-bit integer that represents this colour.

        The format of this number is:
            ((alpha << 24) | (red << 16) | (green << 16) | blue).
    */
    uint32 getARGB() const throw();

    /** Returns the colour's alpha (opacity).

        Alpha of 0x00 is completely transparent, 0xff is completely opaque.
    */
    uint8 getAlpha() const throw()                      { return argb.getAlpha(); }

    /** Returns the colour's alpha (opacity) as a floating point value.

        Alpha of 0.0 is completely transparent, 1.0 is completely opaque.
    */
    float getFloatAlpha() const throw();

    /** Returns true if this colour is completely opaque.

        Equivalent to (getAlpha() == 0xff).
    */
    bool isOpaque() const throw();

    /** Returns true if this colour is completely transparent.

        Equivalent to (getAlpha() == 0x00).
    */
    bool isTransparent() const throw();

    /** Returns a colour that's the same colour as this one, but with a new alpha value. */
    const Colour withAlpha (const uint8 newAlpha) const throw();

    /** Returns a colour that's the same colour as this one, but with a new alpha value. */
    const Colour withAlpha (const float newAlpha) const throw();

    /** Returns a colour that's the same colour as this one, but with a modified alpha value.

        The new colour's alpha will be this object's alpha multiplied by the value passed-in.
    */
    const Colour withMultipliedAlpha (const float alphaMultiplier) const throw();

    /** Returns a colour that is the result of alpha-compositing a new colour over this one.

        If the foreground colour is semi-transparent, it is blended onto this colour
        accordingly.
    */
    const Colour overlaidWith (const Colour& foregroundColour) const throw();

    /** Returns the colour's hue component.
        The value returned is in the range 0.0 to 1.0
    */
    float getHue() const throw();

    /** Returns the colour's saturation component.
        The value returned is in the range 0.0 to 1.0
    */
    float getSaturation() const throw();

    /** Returns the colour's brightness component.
        The value returned is in the range 0.0 to 1.0
    */
    float getBrightness() const throw();

    /** Returns the colour's hue, saturation and brightness components all at once.
        The values returned are in the range 0.0 to 1.0
    */
    void getHSB (float& hue,
                 float& saturation,
                 float& brightness) const throw();

    /** Returns a copy of this colour with a different hue. */
    const Colour withHue (const float newHue) const throw();

    /** Returns a copy of this colour with a different saturation. */
    const Colour withSaturation (const float newSaturation) const throw();

    /** Returns a copy of this colour with a different brightness.
        @see brighter, darker, withMultipliedBrightness
    */
    const Colour withBrightness (const float newBrightness) const throw();

    /** Returns a copy of this colour with it hue rotated.

        The new colour's hue is ((this->getHue() + amountToRotate) % 1.0)

        @see brighter, darker, withMultipliedBrightness
    */
    const Colour withRotatedHue (const float amountToRotate) const throw();

    /** Returns a copy of this colour with its saturation multiplied by the given value.

        The new colour's saturation is (this->getSaturation() * multiplier)
        (the result is clipped to legal limits).
    */
    const Colour withMultipliedSaturation (const float multiplier) const throw();

    /** Returns a copy of this colour with its brightness multiplied by the given value.

        The new colour's saturation is (this->getBrightness() * multiplier)
        (the result is clipped to legal limits).
    */
    const Colour withMultipliedBrightness (const float amount) const throw();

    /** Returns a brighter version of this colour.

        @param amountBrighter   how much brighter to make it - a value from 0 to 1.0 where 0 is
                                unchanged, and higher values make it brighter
        @see withMultipliedBrightness
    */
    const Colour brighter (float amountBrighter = 0.4f) const throw();

    /** Returns a darker version of this colour.

        @param amountDarker     how much darker to make it - a value from 0 to 1.0 where 0 is
                                unchanged, and higher values make it darker
        @see withMultipliedBrightness
    */
    const Colour darker (float amountDarker = 0.4f) const throw();

    /** Returns a colour that will be clearly visible against this colour.

        The amount parameter indicates how contrasting the new colour should
        be, so e.g. Colours::black.contrasting (0.1f) will return a colour
        that's just a little bit lighter; Colours::black.contrasting (1.0f) will
        return white; Colours::white.contrasting (1.0f) will return black, etc.
    */
    const Colour contrasting (const float amount = 1.0f) const throw();

    /** Returns a colour that contrasts against two colours.

        Looks for a colour that contrasts with both of the colours passed-in.

        Handy for things like choosing a highlight colour in text editors, etc.
    */
    static const Colour contrasting (const Colour& colour1,
                                     const Colour& colour2) throw();

    /** Returns an opaque shade of grey.

        @param brightness the level of grey to return - 0 is black, 1.0 is white
    */
    static const Colour greyLevel (const float brightness) throw();

    /** Returns a stringified version of this colour.

        The string can be turned back into a colour using the fromString() method.
    */
    const String toString() const throw();

    /** Reads the colour from a string that was created with toString().
    */
    static const Colour fromString (const String& encodedColourString);

    juce_UseDebuggingNewOperator

private:
    PixelARGB argb;
};

#endif   // __JUCE_COLOUR_JUCEHEADER__
/********* End of inlined file: juce_Colour.h *********/

/**
    Contains a set of predefined named colours (mostly standard HTML colours)

    @see Colour, Colours::greyLevel
*/
class Colours
{
public:
    static JUCE_API const Colour

    transparentBlack,   /**< ARGB = 0x00000000 */
    transparentWhite,   /**< ARGB = 0x00ffffff */

    black,              /**< ARGB = 0xff000000 */
    white,              /**< ARGB = 0xffffffff */
    blue,               /**< ARGB = 0xff0000ff */
    grey,               /**< ARGB = 0xff808080 */
    green,              /**< ARGB = 0xff008000 */
    red,                /**< ARGB = 0xffff0000 */
    yellow,             /**< ARGB = 0xffffff00 */

    aliceblue,              antiquewhite,       aqua,               aquamarine,
    azure,                  beige,              bisque,             blanchedalmond,
    blueviolet,             brown,              burlywood,          cadetblue,
    chartreuse,             chocolate,          coral,              cornflowerblue,
    cornsilk,               crimson,            cyan,               darkblue,
    darkcyan,               darkgoldenrod,      darkgrey,           darkgreen,
    darkkhaki,              darkmagenta,        darkolivegreen,     darkorange,
    darkorchid,             darkred,            darksalmon,         darkseagreen,
    darkslateblue,          darkslategrey,      darkturquoise,      darkviolet,
    deeppink,               deepskyblue,        dimgrey,            dodgerblue,
    firebrick,              floralwhite,        forestgreen,        fuchsia,
    gainsboro,              gold,               goldenrod,          greenyellow,
    honeydew,               hotpink,            indianred,          indigo,
    ivory,                  khaki,              lavender,           lavenderblush,
    lemonchiffon,           lightblue,          lightcoral,         lightcyan,
    lightgoldenrodyellow,   lightgreen,         lightgrey,          lightpink,
    lightsalmon,            lightseagreen,      lightskyblue,       lightslategrey,
    lightsteelblue,         lightyellow,        lime,               limegreen,
    linen,                  magenta,            maroon,             mediumaquamarine,
    mediumblue,             mediumorchid,       mediumpurple,       mediumseagreen,
    mediumslateblue,        mediumspringgreen,  mediumturquoise,    mediumvioletred,
    midnightblue,           mintcream,          mistyrose,          navajowhite,
    navy,                   oldlace,            olive,              olivedrab,
    orange,                 orangered,          orchid,             palegoldenrod,
    palegreen,              paleturquoise,      palevioletred,      papayawhip,
    peachpuff,              peru,               pink,               plum,
    powderblue,             purple,             rosybrown,          royalblue,
    saddlebrown,            salmon,             sandybrown,         seagreen,
    seashell,               sienna,             silver,             skyblue,
    slateblue,              slategrey,          snow,               springgreen,
    steelblue,              tan,                teal,               thistle,
    tomato,                 turquoise,          violet,             wheat,
    whitesmoke,             yellowgreen;

    /** Attempts to look up a string in the list of known colour names, and return
        the appropriate colour.

        A non-case-sensitive search is made of the list of predefined colours, and
        if a match is found, that colour is returned. If no match is found, the
        colour passed in as the defaultColour parameter is returned.
    */
    static JUCE_API const Colour findColourForName (const String& colourName,
                                                    const Colour& defaultColour);

private:

    // this isn't a class you should ever instantiate - it's just here for the
    // static values in it.
    Colours();
};

#endif   // __JUCE_COLOURS_JUCEHEADER__
/********* End of inlined file: juce_Colours.h *********/

/********* Start of inlined file: juce_SolidColourBrush.h *********/
#ifndef __JUCE_SOLIDCOLOURBRUSH_JUCEHEADER__
#define __JUCE_SOLIDCOLOURBRUSH_JUCEHEADER__

/********* Start of inlined file: juce_Brush.h *********/
#ifndef __JUCE_BRUSH_JUCEHEADER__
#define __JUCE_BRUSH_JUCEHEADER__

class Path;
class AffineTransform;
class LowLevelGraphicsContext;
class Image;
class Graphics;

/**
    A brush is used to fill areas with colours, patterns, or images.

    The Graphics class has an idea of a current brush which it uses to render
    shapes, rectangles, lines, text, etc.

    This is the base class - there are subclasses for useful types of fill pattern,
    and applications can define their own brushes too.

    @see Graphics::setBrush, SolidColourBrush, GradientBrush, ImageBrush
*/
class JUCE_API  Brush
{
protected:

    /** Creates a Brush.

        (Nothing much happens in the base class).
    */
    Brush() throw();

public:
    /** Destructor. */
    virtual ~Brush() throw();

    /** Creates a copy of whatever class of Brush this is. */
    virtual Brush* createCopy() const throw() = 0;

    /** Does whatever is relevent to transform the geometry of this brush. */
    virtual void applyTransform (const AffineTransform& transform) throw() = 0;

    /** Does whatever is relevent to change the opacity of this brush. */
    virtual void multiplyOpacity (const float multiple) throw() = 0;

    /** Must return true if this brush won't draw any pixels. */
    virtual bool isInvisible() const throw() = 0;

    virtual void paintPath (LowLevelGraphicsContext& context,
                            const Path& path, const AffineTransform& transform) throw() = 0;

    virtual void paintRectangle (LowLevelGraphicsContext& context,
                                 int x, int y, int w, int h) throw() = 0;

    virtual void paintAlphaChannel (LowLevelGraphicsContext& context,
                                    const Image& alphaChannelImage, int imageX, int imageY,
                                    int x, int y, int w, int h) throw() = 0;

    virtual void paintVerticalLine (LowLevelGraphicsContext& context,
                                    int x, float y1, float y2) throw();

    virtual void paintHorizontalLine (LowLevelGraphicsContext& context,
                                      int y, float x1, float x2) throw();

    virtual void paintLine (LowLevelGraphicsContext& context,
                            float x1, float y1, float x2, float y2) throw();

private:

    Brush (const Brush&);
    const Brush& operator= (const Brush&);
};

#endif   // __JUCE_BRUSH_JUCEHEADER__
/********* End of inlined file: juce_Brush.h *********/

/**
    A Brush that fills its area with a solid (or semi-transparent) colour.

    An application won't normally need to use this class directly, as drawing
    with solid colours is taken care of automatically by the Graphics class
    (it actually uses one of these brushes internally when you set the colour
    with the Graphics::setColour() method).

    @see Brush, Graphics::setBrush, GradientBrush, ImageBrush
*/
class JUCE_API  SolidColourBrush  : public Brush
{
public:

    /** Creates a SolidColourBrush to draw with the given colour.

        The colour can be changed later with the setColour() method.
    */
    SolidColourBrush (const Colour& colour) throw();

    /** Creates a SolidColourBrush set to black.

        The colour can be changed later with the setColour() method.
    */
    SolidColourBrush() throw();

    /** Destructor. */
    ~SolidColourBrush() throw();

    /** Returns the colour currently being used. */
    const Colour& getColour() const throw()             { return colour; }

    /** Sets the colour to use for drawing. */
    void setColour (const Colour& newColour) throw()    { colour = newColour; }

    Brush* createCopy() const throw();

    void applyTransform (const AffineTransform& transform) throw();

    bool isInvisible() const throw();

    void multiplyOpacity (const float multiple) throw();

    void paintPath (LowLevelGraphicsContext& context,
                    const Path& path, const AffineTransform& transform) throw();

    void paintRectangle (LowLevelGraphicsContext& context,
                         int x, int y, int w, int h) throw();

    void paintAlphaChannel (LowLevelGraphicsContext& context,
                            const Image& alphaChannelImage, int imageX, int imageY,
                            int x, int y, int w, int h) throw();

    void paintVerticalLine (LowLevelGraphicsContext& context,
                            int x, float y1, float y2) throw();

    void paintHorizontalLine (LowLevelGraphicsContext& context,
                              int y, float x1, float x2) throw();

    void paintLine (LowLevelGraphicsContext& context,
                    float x1, float y1, float x2, float y2) throw();

    juce_UseDebuggingNewOperator

private:
    Colour colour;

    SolidColourBrush (const SolidColourBrush&);
    const SolidColourBrush& operator= (const SolidColourBrush&);
};

#endif   // __JUCE_SOLIDCOLOURBRUSH_JUCEHEADER__
/********* End of inlined file: juce_SolidColourBrush.h *********/

/********* Start of inlined file: juce_RectanglePlacement.h *********/
#ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__
#define __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__

/**
    Defines the method used to postion some kind of rectangular object within
    a rectangular viewport.

    Although similar to Justification, this is more specific, and has some extra
    options.
*/
class JUCE_API  RectanglePlacement
{
public:

    /** Creates a RectanglePlacement object using a combination of flags. */
    inline RectanglePlacement (const int flags_) throw()  : flags (flags_) {}

    /** Creates a copy of another Justification object. */
    RectanglePlacement (const RectanglePlacement& other) throw();

    /** Copies another Justification object. */
    const RectanglePlacement& operator= (const RectanglePlacement& other) throw();

    /** Flag values that can be combined and used in the constructor. */
    enum
    {

        /** Indicates that the source rectangle's left edge should be aligned with the left edge of the target rectangle. */
        xLeft                                   = 1,

        /** Indicates that the source rectangle's right edge should be aligned with the right edge of the target rectangle. */
        xRight                                  = 2,

        /** Indicates that the source should be placed in the centre between the left and right
            sides of the available space. */
        xMid                                    = 4,

        /** Indicates that the source's top edge should be aligned with the top edge of the
            destination rectangle. */
        yTop                                    = 8,

        /** Indicates that the source's bottom edge should be aligned with the bottom edge of the
            destination rectangle. */
        yBottom                                 = 16,

        /** Indicates that the source should be placed in the centre between the top and bottom
            sides of the available space. */
        yMid                                    = 32,

        /** If this flag is set, then the source rectangle will be resized to completely fill
            the destination rectangle, and all other flags are ignored.
        */
        stretchToFit                            = 64,

        /** If this flag is set, then the source rectangle will be resized so that it is the
            minimum size to completely fill the destination rectangle, without changing its
            aspect ratio. This means that some of the source rectangle may fall outside
            the destination.

            If this flag is not set, the source will be given the maximum size at which none
            of it falls outside the destination rectangle.
        */
        fillDestination                         = 128,

        /** Indicates that the source rectangle can be reduced in size if required, but should
            never be made larger than its original size.
        */
        onlyReduceInSize                        = 256,

        /** Indicates that the source rectangle can be enlarged if required, but should
            never be made smaller than its original size.
        */
        onlyIncreaseInSize                      = 512,

        /** Indicates that the source rectangle's size should be left unchanged.
        */
        doNotResize                             = (onlyIncreaseInSize | onlyReduceInSize),

        /** A shorthand value that is equivalent to (xMid | yMid). */
        centred                                 = 4 + 32
    };

    /** Returns the raw flags that are set for this object. */
    inline int getFlags() const throw()                             { return flags; }

    /** Tests a set of flags for this object.

        @returns true if any of the flags passed in are set on this object.
    */
    inline bool testFlags (const int flagsToTest) const throw()     { return (flags & flagsToTest) != 0; }

    /** Adjusts the position and size of a rectangle to fit it into a space.

        The source rectangle co-ordinates will be adjusted so that they fit into
        the destination rectangle based on this object's flags.
    */
    void applyTo (double& sourceX,
                  double& sourceY,
                  double& sourceW,
                  double& sourceH,
                  const double destinationX,
                  const double destinationY,
                  const double destinationW,
                  const double destinationH) const throw();

    /** Returns the transform that should be applied to these source co-ordinates to fit them
        into the destination rectangle using the current flags.
    */
    const AffineTransform getTransformToFit (float sourceX,
                                             float sourceY,
                                             float sourceW,
                                             float sourceH,
                                             const float destinationX,
                                             const float destinationY,
                                             const float destinationW,
                                             const float destinationH) const throw();

private:

    int flags;
};

#endif   // __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__
/********* End of inlined file: juce_RectanglePlacement.h *********/

class LowLevelGraphicsContext;
class Image;
class RectangleList;

/**
    A graphics context, used for drawing a component or image.

    When a Component needs painting, a Graphics context is passed to its
    Component::paint() method, and this you then call methods within this
    object to actually draw the component's content.

    A Graphics can also be created from an image, to allow drawing directly onto
    that image.

    @see Component::paint
*/
class JUCE_API  Graphics
{
public:

    /** Creates a Graphics object to draw directly onto the given image.

        The graphics object that is created will be set up to draw onto the image,
        with the context's clipping area being the entire size of the image, and its
        origin being the image's origin. To draw into a subsection of an image, use the
        reduceClipRegion() and setOrigin() methods.

        Obviously you shouldn't delete the image before this context is deleted.
    */
    Graphics (Image& imageToDrawOnto) throw();

    /** Destructor. */
    ~Graphics() throw();

    /** Changes the current drawing colour.

        This sets the colour that will now be used for drawing operations - it also
        sets the opacity to that of the colour passed-in.

        If a brush is being used when this method is called, the brush will be deselected,
        and any subsequent drawing will be done with a solid colour brush instead.

        @see setOpacity, setBrush, getColour
    */
    void setColour (const Colour& newColour) throw();

    /** Returns the colour that's currently being used.

        This will return the last colour set by setColour(), even if the colour's not
        currently being used for drawing because a brush has been selected instead.

        @see setColour
    */
    const Colour& getCurrentColour() const throw();

    /** Changes the opacity to use with the current colour.

        If a solid colour is being used for drawing, this changes its opacity (and this
        will be reflected by calls to the getColour() method).

        A value of 0.0 is completely transparent, 1.0 is completely opaque.
    */
    void setOpacity (const float newOpacity) throw();

    /** Changes the current brush to use for drawing.

        If a null pointer is passed in, the context will revert to using a solid
        colour for drawing (using the last colour set by setColour()).

        If a brush is passed in, a copy of it will be used for subsequent drawing
        operations until setColour() or setBrush() is called.

        @see SolidColourBrush, GradientBrush, ImageBrush, Brush
    */
    void setBrush (const Brush* const newBrush) throw();

    /** Changes the font to use for subsequent text-drawing functions.

        Note there's also a setFont (float, int) method to quickly change the size and
        style of the current font.

        @see drawSingleLineText, drawMultiLineText, drawTextAsPath, drawText, drawFittedText
    */
    void setFont (const Font& newFont) throw();

    /** Changes the size and style of the currently-selected font.

        This is a convenient shortcut that changes the context's current font to a
        different size or style. The typeface won't be changed.

        @see Font
    */
    void setFont (const float newFontHeight,
                  const int fontStyleFlags = Font::plain) throw();

    /** Returns the font that's currently being used for text operations.

        @see setFont
    */
    const Font& getCurrentFont() const throw();

    /** Draws a one-line text string.

        This will use the current colour (or brush) to fill the text. The font is the last
        one specified by setFont().

        @param text         the string to draw
        @param startX       the position to draw the left-hand edge of the text
        @param baselineY    the position of the text's baseline
        @see drawMultiLineText, drawText, drawFittedText, GlyphArrangement::addLineOfText
    */
    void drawSingleLineText (const String& text,
                             const int startX,
                             const int baselineY) const throw();

    /** Draws text across multiple lines.

        This will break the text onto a new line where there's a new-line or
        carriage-return character, or at a word-boundary when the text becomes wider
        than the size specified by the maximumLineWidth parameter.

        @see setFont, drawSingleLineText, drawFittedText, GlyphArrangement::addJustifiedText
    */
    void drawMultiLineText (const String& text,
                            const int startX,
                            const int baselineY,
                            const int maximumLineWidth) const throw();

    /** Renders a string of text as a vector path.

        This allows a string to be transformed with an arbitrary AffineTransform and
        rendered using the current colour/brush. It's much slower than the normal text methods
        but more accurate.

        @see setFont
    */
    void drawTextAsPath (const String& text,
                         const AffineTransform& transform) const throw();

    /** Draws a line of text within a specified rectangle.

        The text will be positioned within the rectangle based on the justification
        flags passed-in. If the string is too long to fit inside the rectangle, it will
        either be truncated or will have ellipsis added to its end (if the useEllipsesIfTooBig
        flag is true).

        @see drawSingleLineText, drawFittedText, drawMultiLineText, GlyphArrangement::addJustifiedText
    */
    void drawText (const String& text,
                   const int x,
                   const int y,
                   const int width,
                   const int height,
                   const Justification& justificationType,
                   const bool useEllipsesIfTooBig) const throw();

    /** Tries to draw a text string inside a given space.

        This does its best to make the given text readable within the specified rectangle,
        so it useful for labelling things.

        If the text is too big, it'll be squashed horizontally or broken over multiple lines
        if the maximumLinesToUse value allows this. If the text just won't fit into the space,
        it'll cram as much as possible in there, and put some ellipsis at the end to show that
        it's been truncated.

        A Justification parameter lets you specify how the text is laid out within the rectangle,
        both horizontally and vertically.

        The minimumHorizontalScale parameter specifies how much the text can be squashed horizontally
        to try to squeeze it into the space. If you don't want any horizontal scaling to occur, you
        can set this value to 1.0f.

        @see GlyphArrangement::addFittedText
    */
    void drawFittedText (const String& text,
                         const int x,
                         const int y,
                         const int width,
                         const int height,
                         const Justification& justificationFlags,
                         const int maximumNumberOfLines,
                         const float minimumHorizontalScale = 0.7f) const throw();

    /** Fills the context's entire clip region with the current colour or brush.

        (See also the fillAll (const Colour&) method which is a quick way of filling
        it with a given colour).
    */
    void fillAll() const throw();

    /** Fills the context's entire clip region with a given colour.

        This leaves the context's current colour and brush unchanged, it just
        uses the specified colour temporarily.
    */
    void fillAll (const Colour& colourToUse) const throw();

    /** Fills a rectangle with the current colour or brush.

        @see drawRect, fillRoundedRectangle
    */
    void fillRect (int x,
                   int y,
                   int width,
                   int height) const throw();

    /** Fills a rectangle with the current colour or brush. */
    void fillRect (const Rectangle& rectangle) const throw();

    /** Fills a rectangle with the current colour or brush.

        This uses sub-pixel positioning so is slower than the fillRect method which
        takes integer co-ordinates.
    */
    void fillRect (const float x,
                   const float y,
                   const float width,
                   const float height) const throw();

    /** Uses the current colour or brush to fill a rectangle with rounded corners.

        @see drawRoundedRectangle, Path::addRoundedRectangle
    */
    void fillRoundedRectangle (const float x,
                               const float y,
                               const float width,
                               const float height,
                               const float cornerSize) const throw();

    /** Uses the current colour or brush to fill a rectangle with rounded corners.

        @see drawRoundedRectangle, Path::addRoundedRectangle
    */
    void fillRoundedRectangle (const Rectangle& rectangle,
                               const float cornerSize) const throw();

    /** Fills a rectangle with a checkerboard pattern, alternating between two colours.
    */
    void fillCheckerBoard (int x, int y,
                           int width, int height,
                           const int checkWidth,
                           const int checkHeight,
                           const Colour& colour1,
                           const Colour& colour2) const throw();

    /** Draws four lines to form a rectangular outline, using the current colour or brush.

        The lines are drawn inside the given rectangle, and greater line thicknesses
        extend inwards.

        @see fillRect
    */
    void drawRect (const int x,
                   const int y,
                   const int width,
                   const int height,
                   const int lineThickness = 1) const throw();

    /** Draws four lines to form a rectangular outline, using the current colour or brush.

        The lines are drawn inside the given rectangle, and greater line thicknesses
        extend inwards.

        @see fillRect
    */
    void drawRect (const float x,
                   const float y,
                   const float width,
                   const float height,
                   const float lineThickness = 1.0f) const throw();

    /** Draws four lines to form a rectangular outline, using the current colour or brush.

        The lines are drawn inside the given rectangle, and greater line thicknesses
        extend inwards.

        @see fillRect
    */
    void drawRect (const Rectangle& rectangle,
                   const int lineThickness = 1) const throw();

    /** Uses the current colour or brush to draw the outline of a rectangle with rounded corners.

        @see fillRoundedRectangle, Path::addRoundedRectangle
    */
    void drawRoundedRectangle (const float x,
                               const float y,
                               const float width,
                               const float height,
                               const float cornerSize,
                               const float lineThickness) const throw();

    /** Uses the current colour or brush to draw the outline of a rectangle with rounded corners.

        @see fillRoundedRectangle, Path::addRoundedRectangle
    */
    void drawRoundedRectangle (const Rectangle& rectangle,
                               const float cornerSize,
                               const float lineThickness) const throw();

    /** Draws a 3D raised (or indented) bevel using two colours.

        The bevel is drawn inside the given rectangle, and greater bevel thicknesses
        extend inwards.

        The top-left colour is used for the top- and left-hand edges of the
        bevel; the bottom-right colour is used for the bottom- and right-hand
        edges.

        If useGradient is true, then the bevel fades out to make it look more curved
        and less angular. If sharpEdgeOnOutside is true, the outside of the bevel is
        sharp, and it fades towards the centre; if sharpEdgeOnOutside is false, then
        the centre edges are sharp and it fades towards the outside.
    */
    void drawBevel (const int x,
                    const int y,
                    const int width,
                    const int height,
                    const int bevelThickness,
                    const Colour& topLeftColour = Colours::white,
                    const Colour& bottomRightColour = Colours::black,
                    const bool useGradient = true,
                    const bool sharpEdgeOnOutside = true) const throw();

    /** Draws a pixel using the current colour or brush.
    */
    void setPixel (int x, int y) const throw();

    /** Fills an ellipse with the current colour or brush.

        The ellipse is drawn to fit inside the given rectangle.

        @see drawEllipse, Path::addEllipse
    */
    void fillEllipse (const float x,
                      const float y,
                      const float width,
                      const float height) const throw();

    /** Draws an elliptical stroke using the current colour or brush.

        @see fillEllipse, Path::addEllipse
    */
    void drawEllipse (const float x,
                      const float y,
                      const float width,
                      const float height,
                      const float lineThickness) const throw();

    /** Draws a line between two points.

        The line is 1 pixel wide and drawn with the current colour or brush.
    */
    void drawLine (float startX,
                   float startY,
                   float endX,
                   float endY) const throw();

    /** Draws a line between two points with a given thickness.

        @see Path::addLineSegment
    */
    void drawLine (const float startX,
                   const float startY,
                   const float endX,
                   const float endY,
                   const float lineThickness) const throw();

    /** Draws a line between two points.

        The line is 1 pixel wide and drawn with the current colour or brush.
    */
    void drawLine (const Line& line) const throw();

    /** Draws a line between two points with a given thickness.

        @see Path::addLineSegment
    */
    void drawLine (const Line& line,
                   const float lineThickness) const throw();

    /** Draws a dashed line using a custom set of dash-lengths.

        @param startX           the line's start x co-ordinate
        @param startY           the line's start y co-ordinate
        @param endX             the line's end x co-ordinate
        @param endY             the line's end y co-ordinate
        @param dashLengths      a series of lengths to specify the on/off lengths - e.g.
                                { 4, 5, 6, 7 } will draw a line of 4 pixels, skip 5 pixels,
                                draw 6 pixels, skip 7 pixels, and then repeat.
        @param numDashLengths   the number of elements in the array (this must be an even number).
        @param lineThickness    the thickness of the line to draw
        @see PathStrokeType::createDashedStroke
    */
    void drawDashedLine (const float startX,
                         const float startY,
                         const float endX,
                         const float endY,
                         const float* const dashLengths,
                         const int numDashLengths,
                         const float lineThickness = 1.0f) const throw();

    /** Draws a vertical line of pixels at a given x position.

        The x position is an integer, but the top and bottom of the line can be sub-pixel
        positions, and these will be anti-aliased if necessary.
    */
    void drawVerticalLine (const int x, float top, float bottom) const throw();

    /** Draws a horizontal line of pixels at a given y position.

        The y position is an integer, but the left and right ends of the line can be sub-pixel
        positions, and these will be anti-aliased if necessary.
    */
    void drawHorizontalLine (const int y, float left, float right) const throw();

    /** Fills a path using the currently selected colour or brush.
    */
    void fillPath (const Path& path,
                   const AffineTransform& transform = AffineTransform::identity) const throw();

    /** Draws a path's outline using the currently selected colour or brush.
    */
    void strokePath (const Path& path,
                     const PathStrokeType& strokeType,
                     const AffineTransform& transform = AffineTransform::identity) const throw();

    /** Draws a line with an arrowhead.

        @param startX           the line's start x co-ordinate
        @param startY           the line's start y co-ordinate
        @param endX             the line's end x co-ordinate (the tip of the arrowhead)
        @param endY             the line's end y co-ordinate (the tip of the arrowhead)
        @param lineThickness    the thickness of the line
        @param arrowheadWidth   the width of the arrow head (perpendicular to the line)
        @param arrowheadLength  the length of the arrow head (along the length of the line)
    */
    void drawArrow (const float startX,
                    const float startY,
                    const float endX,
                    const float endY,
                    const float lineThickness,
                    const float arrowheadWidth,
                    const float arrowheadLength) const throw();

    /** Types of rendering quality that can be specified when drawing images.

        @see blendImage, Graphics::setImageResamplingQuality
    */
    enum ResamplingQuality
    {
        lowResamplingQuality     = 0,    /**< Just uses a nearest-neighbour algorithm for resampling. */
        mediumResamplingQuality  = 1,    /**< Uses bilinear interpolation for upsampling and area-averaging for downsampling. */
        highResamplingQuality    = 2     /**< Uses bicubic interpolation for upsampling and area-averaging for downsampling. */
    };

    /** Changes the quality that will be used when resampling images.

        By default a Graphics object will be set to mediumRenderingQuality.

        @see Graphics::drawImage, Graphics::drawImageTransformed, Graphics::drawImageWithin
    */
    void setImageResamplingQuality (const ResamplingQuality newQuality) throw();

    /** Draws an image.

        This will draw the whole of an image, positioning its top-left corner at the
        given co-ordinates, and keeping its size the same. This is the simplest image
        drawing method - the others give more control over the scaling and clipping
        of the images.

        Images are composited using the context's current opacity, so if you
        don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f)
        (or setColour() with an opaque colour) before drawing images.
    */
    void drawImageAt (const Image* const imageToDraw,
                      const int topLeftX,
                      const int topLeftY,
                      const bool fillAlphaChannelWithCurrentBrush = false) const throw();

    /** Draws part of an image, rescaling it to fit in a given target region.

        The specified area of the source image is rescaled and drawn to fill the
        specifed destination rectangle.

        Images are composited using the context's current opacity, so if you
        don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f)
        (or setColour() with an opaque colour) before drawing images.

        @param imageToDraw      the image to overlay
        @param destX            the left of the destination rectangle
        @param destY            the top of the destination rectangle
        @param destWidth        the width of the destination rectangle
        @param destHeight       the height of the destination rectangle
        @param sourceX          the left of the rectangle to copy from the source image
        @param sourceY          the top of the rectangle to copy from the source image
        @param sourceWidth      the width of the rectangle to copy from the source image
        @param sourceHeight     the height of the rectangle to copy from the source image
        @param fillAlphaChannelWithCurrentBrush     if true, then instead of drawing the source image's pixels,
                                                    the source image's alpha channel is used as a mask with
                                                    which to fill the destination using the current colour
                                                    or brush. (If the source is has no alpha channel, then
                                                    it will just fill the target with a solid rectangle)
        @see setImageResamplingQuality, drawImageAt, drawImageWithin, fillAlphaMap
    */
    void drawImage (const Image* const imageToDraw,
                    int destX,
                    int destY,
                    int destWidth,
                    int destHeight,
                    int sourceX,
                    int sourceY,
                    int sourceWidth,
                    int sourceHeight,
                    const bool fillAlphaChannelWithCurrentBrush = false) const throw();

    /** Draws part of an image, having applied an affine transform to it.

        This lets you throw the image around in some wacky ways, rotate it, shear,
        scale it, etc.

        A clipping subregion is specified within the source image and no pixels
        outside this region will be used.

        Images are composited using the context's current opacity, so if you
        don't want it to be drawn semi-transparently, be sure to call setOpacity (1.0f)
        (or setColour() with an opaque colour) before drawing images.

        If fillAlphaChannelWithCurrentBrush is set to true, then the image's RGB channels
        are ignored and it is filled with the current brush, masked by its alpha channel.

        @see setImageResamplingQuality, drawImage
    */
    void drawImageTransformed (const Image* const imageToDraw,
                               int sourceClipX,
                               int sourceClipY,
                               int sourceClipWidth,
                               int sourceClipHeight,
                               const AffineTransform& transform,
                               const bool fillAlphaChannelWithCurrentBrush = false) const throw();

    /** Draws an image to fit within a designated rectangle.

        If the image is too big or too small for the space, it will be rescaled
        to fit as nicely as it can do without affecting its aspect ratio. It will
        then be placed within the target rectangle according to the justification flags
        specified.

        @param imageToDraw              the source image to draw
        @param destX                    top-left of the target rectangle to fit it into
        @param destY                    top-left of the target rectangle to fit it into
        @param destWidth                size of the target rectangle to fit the image into
        @param destHeight               size of the target rectangle to fit the image into
        @param placementWithinTarget    this specifies how the image should be positioned
                                        within the target rectangle - see the RectanglePlacement
                                        class for more details about this.
        @param fillAlphaChannelWithCurrentBrush     if true, then instead of drawing the image, just its
                                                    alpha channel will be used as a mask with which to
                                                    draw with the current brush or colour. This is
                                                    similar to fillAlphaMap(), and see also drawImage()
        @see setImageResamplingQuality, drawImage, drawImageTransformed, drawImageAt, RectanglePlacement
    */
    void drawImageWithin (const Image* const imageToDraw,
                          const int destX,
                          const int destY,
                          const int destWidth,
                          const int destHeight,
                          const RectanglePlacement& placementWithinTarget,
                          const bool fillAlphaChannelWithCurrentBrush = false) const throw();

    /** Returns the position of the bounding box for the current clipping region.

        @see getClipRegion, clipRegionIntersects
    */
    const Rectangle getClipBounds() const throw();

    /** Checks whether a rectangle overlaps the context's clipping region.

        If this returns false, no part of the given area can be drawn onto, so this
        method can be used to optimise a component's paint() method, by letting it
        avoid drawing complex objects that aren't within the region being repainted.
    */
    bool clipRegionIntersects (const int x, const int y, const int width, const int height) const throw();

    /** Intersects the current clipping region with another region.

        @returns true if the resulting clipping region is non-zero in size
        @see setOrigin, clipRegionIntersects, getClipLeft, getClipRight, getClipWidth, getClipHeight
    */
    bool reduceClipRegion (const int x, const int y,
                           const int width, const int height) throw();

    /** Intersects the current clipping region with a rectangle list region.

        @returns true if the resulting clipping region is non-zero in size
        @see setOrigin, clipRegionIntersects, getClipLeft, getClipRight, getClipWidth, getClipHeight
    */
    bool reduceClipRegion (const RectangleList& clipRegion) throw();

    /** Excludes a rectangle to stop it being drawn into. */
    void excludeClipRegion (const int x, const int y,
                            const int width, const int height) throw();

    /** Returns true if no drawing can be done because the clip region is zero. */
    bool isClipEmpty() const throw();

    /** Saves the current graphics state on an internal stack.

        To restore the state, use restoreState().
    */
    void saveState() throw();

    /** Restores a graphics state that was previously saved with saveState().
    */
    void restoreState() throw();

    /** Moves the position of the context's origin.

        This changes the position that the context considers to be (0, 0) to
        the specified position.

        So if you call setOrigin (100, 100), then the position that was previously
        referred to as (100, 100) will subsequently be considered to be (0, 0).

        @see reduceClipRegion
    */
    void setOrigin (const int newOriginX,
                    const int newOriginY) throw();

    /** Resets the current colour, brush, and font to default settings. */
    void resetToDefaultState() throw();

    /** Returns true if this context is drawing to a vector-based device, such as a printer. */
    bool isVectorDevice() const throw();

    juce_UseDebuggingNewOperator

    /** Create a graphics that uses a given low-level renderer.

        For internal use only.

        NB. The context will NOT be deleted by this object when it is deleted.
    */
    Graphics (LowLevelGraphicsContext* const internalContext) throw();

    /** @internal */
    LowLevelGraphicsContext* getInternalContext() const throw()     { return context; }

private:

    LowLevelGraphicsContext* const context;
    const bool ownsContext;

    struct GraphicsState
    {
        GraphicsState() throw();
        GraphicsState (const GraphicsState&) throw();
        ~GraphicsState() throw();

        Colour colour;
        Brush* brush;
        Font font;
        ResamplingQuality quality;
    };

    GraphicsState* state;
    OwnedArray <GraphicsState> stateStack;
    bool saveStatePending;

    void saveStateIfPending() throw();

    const Graphics& operator= (const Graphics& other);
    Graphics (const Graphics&);
};

#endif   // __JUCE_GRAPHICS_JUCEHEADER__
/********* End of inlined file: juce_Graphics.h *********/

/**
    A graphical effect filter that can be applied to components.

    An ImageEffectFilter can be applied to the image that a component
    paints before it hits the screen.

    This is used for adding effects like shadows, blurs, etc.

    @see Component::setComponentEffect
*/
class JUCE_API  ImageEffectFilter
{
public:

    /** Overridden to render the effect.

        The implementation of this method must use the image that is passed in
        as its source, and should render its output to the graphics context passed in.

        @param sourceImage      the image that the source component has just rendered with
                                its paint() method. The image may or may not have an alpha
                                channel, depending on whether the component is opaque.
        @param destContext      the graphics context to use to draw the resultant image.
    */
    virtual void applyEffect (Image& sourceImage,
                              Graphics& destContext) = 0;

    /** Destructor. */
    virtual ~ImageEffectFilter() {}

};

#endif   // __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__
/********* End of inlined file: juce_ImageEffectFilter.h *********/

/********* Start of inlined file: juce_RectangleList.h *********/
#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__
#define __JUCE_RECTANGLELIST_JUCEHEADER__

/**
    Maintains a set of rectangles as a complex region.

    This class allows a set of rectangles to be treated as a solid shape, and can
    add and remove rectangular sections of it, and simplify overlapping or
    adjacent rectangles.

    @see Rectangle
*/
class JUCE_API  RectangleList
{
public:

    /** Creates an empty RectangleList */
    RectangleList() throw();

    /** Creates a copy of another list */
    RectangleList (const RectangleList& other) throw();

    /** Creates a list containing just one rectangle. */
    RectangleList (const Rectangle& rect) throw();

    /** Copies this list from another one. */
    const RectangleList& operator= (const RectangleList& other) throw();

    /** Destructor. */
    ~RectangleList() throw();

    /** Returns true if the region is empty. */
    bool isEmpty() const throw();

    /** Returns the number of rectangles in the list. */
    int getNumRectangles() const throw()                        { return rects.size(); }

    /** Returns one of the rectangles at a particular index.

        @returns    the rectangle at the index, or an empty rectangle if the
                    index is out-of-range.
    */
    const Rectangle getRectangle (const int index) const throw();

    /** Removes all rectangles to leave an empty region. */
    void clear() throw();

    /** Merges a new rectangle into the list.

        The rectangle being added will first be clipped to remove any parts of it
        that overlap existing rectangles in the list.
    */
    void add (const int x, const int y,
              const int w, const int h) throw();

    /** Merges a new rectangle into the list.

        The rectangle being added will first be clipped to remove any parts of it
        that overlap existing rectangles in the list, and adjacent rectangles will be
        merged into it.
    */
    void add (const Rectangle& rect) throw();

    /** Dumbly adds a rectangle to the list without checking for overlaps.

        This simply adds the rectangle to the end, it doesn't merge it or remove
        any overlapping bits.
    */
    void addWithoutMerging (const Rectangle& rect) throw();

    /** Merges another rectangle list into this one.

        Any overlaps between the two lists will be clipped, so that the result is
        the union of both lists.
    */
    void add (const RectangleList& other) throw();

    /** Removes a rectangular region from the list.

        Any rectangles in the list which overlap this will be clipped and subdivided
        if necessary.
    */
    void subtract (const Rectangle& rect) throw();

    /** Removes all areas in another RectangleList from this one.

        Any rectangles in the list which overlap this will be clipped and subdivided
        if necessary.
    */
    void subtract (const RectangleList& otherList) throw();

    /** Removes any areas of the region that lie outside a given rectangle.

        Any rectangles in the list which overlap this will be clipped and subdivided
        if necessary.

        Returns true if the resulting region is not empty, false if it is empty.

        @see getIntersectionWith
    */
    bool clipTo (const Rectangle& rect) throw();

    /** Removes any areas of the region that lie outside a given rectangle list.

        Any rectangles in this object which overlap the specified list will be clipped
        and subdivided if necessary.

        Returns true if the resulting region is not empty, false if it is empty.

        @see getIntersectionWith
    */
    bool clipTo (const RectangleList& other) throw();

    /** Creates a region which is the result of clipping this one to a given rectangle.

        Unlike the other clipTo method, this one doesn't affect this object - it puts the
        resulting region into the list whose reference is passed-in.

        Returns true if the resulting region is not empty, false if it is empty.

        @see clipTo
    */
    bool getIntersectionWith (const Rectangle& rect, RectangleList& destRegion) const throw();

    /** Swaps the contents of this and another list.

        This swaps their internal pointers, so is hugely faster than using copy-by-value
        to swap them.
    */
    void swapWith (RectangleList& otherList) throw();

    /** Checks whether the region contains a given point.

        @returns true if the point lies within one of the rectangles in the list
    */
    bool containsPoint (const int x, const int y) const throw();

    /** Checks whether the region contains the whole of a given rectangle.

        @returns    true all parts of the rectangle passed in lie within the region
                    defined by this object
        @see intersectsRectangle, containsPoint
    */
    bool containsRectangle (const Rectangle& rectangleToCheck) const throw();

    /** Checks whether the region contains any part of a given rectangle.

        @returns    true if any part of the rectangle passed in lies within the region
                    defined by this object
        @see containsRectangle
    */
    bool intersectsRectangle (const Rectangle& rectangleToCheck) const throw();

    /** Checks whether this region intersects any part of another one.

        @see intersectsRectangle
    */
    bool intersects (const RectangleList& other) const throw();

    /** Returns the smallest rectangle that can enclose the whole of this region. */
    const Rectangle getBounds() const throw();

    /** Optimises the list into a minimum number of constituent rectangles.

        This will try to combine any adjacent rectangles into larger ones where
        possible, to simplify lists that might have been fragmented by repeated
        add/subtract calls.
    */
    void consolidate() throw();

    /** Adds an x and y value to all the co-ordinates. */
    void offsetAll (const int dx, const int dy) throw();

    /** Creates a Path object to represent this region. */
    const Path toPath() const throw();

    /** An iterator for accessing all the rectangles in a RectangleList. */
    class Iterator
    {
    public:

        Iterator (const RectangleList& list) throw();
        ~Iterator() throw();

        /** Advances to the next rectangle, and returns true if it's not finished.

            Call this before using getRectangle() to find the rectangle that was returned.
        */
        bool next() throw();

        /** Returns the current rectangle. */
        const Rectangle* getRectangle() const throw()       { return current; }

        juce_UseDebuggingNewOperator

    private:
        const Rectangle* current;
        const RectangleList& owner;
        int index;

        Iterator (const Iterator&);
        const Iterator& operator= (const Iterator&);
    };

    juce_UseDebuggingNewOperator

private:
    friend class Iterator;
    Array <Rectangle> rects;
};

#endif   // __JUCE_RECTANGLELIST_JUCEHEADER__
/********* End of inlined file: juce_RectangleList.h *********/

/********* Start of inlined file: juce_BorderSize.h *********/
#ifndef __JUCE_BORDERSIZE_JUCEHEADER__
#define __JUCE_BORDERSIZE_JUCEHEADER__

/**
    Specifies a set of gaps to be left around the sides of a rectangle.

    This is basically the size of the spaces at the top, bottom, left and right of
    a rectangle. It's used by various component classes to specify borders.

    @see Rectangle
*/
class JUCE_API  BorderSize
{
public:

    /** Creates a null border.

        All sizes are left as 0.
    */
    BorderSize() throw();

    /** Creates a copy of another border. */
    BorderSize (const BorderSize& other) throw();

    /** Creates a border with the given gaps. */
    BorderSize (const int topGap,
                const int leftGap,
                const int bottomGap,
                const int rightGap) throw();

    /** Creates a border with the given gap on all sides. */
    BorderSize (const int allGaps) throw();

    /** Destructor. */
    ~BorderSize() throw();

    /** Returns the gap that should be left at the top of the region. */
    int getTop() const throw()                          { return top; }

    /** Returns the gap that should be left at the top of the region. */
    int getLeft() const throw()                         { return left; }

    /** Returns the gap that should be left at the top of the region. */
    int getBottom() const throw()                       { return bottom; }

    /** Returns the gap that should be left at the top of the region. */
    int getRight() const throw()                        { return right; }

    /** Returns the sum of the top and bottom gaps. */
    int getTopAndBottom() const throw()                 { return top + bottom; }

    /** Returns the sum of the left and right gaps. */
    int getLeftAndRight() const throw()                 { return left + right; }

    /** Changes the top gap. */
    void setTop (const int newTopGap) throw();

    /** Changes the left gap. */
    void setLeft (const int newLeftGap) throw();

    /** Changes the bottom gap. */
    void setBottom (const int newBottomGap) throw();

    /** Changes the right gap. */
    void setRight (const int newRightGap) throw();

    /** Returns a rectangle with these borders removed from it. */
    const Rectangle subtractedFrom (const Rectangle& original) const throw();

    /** Removes this border from a given rectangle. */
    void subtractFrom (Rectangle& rectangle) const throw();

    /** Returns a rectangle with these borders added around it. */
    const Rectangle addedTo (const Rectangle& original) const throw();

    /** Adds this border around a given rectangle. */
    void addTo (Rectangle& original) const throw();

    bool operator== (const BorderSize& other) const throw();
    bool operator!= (const BorderSize& other) const throw();

    juce_UseDebuggingNewOperator

private:
    int top, left, bottom, right;
};

#endif   // __JUCE_BORDERSIZE_JUCEHEADER__
/********* End of inlined file: juce_BorderSize.h *********/

/********* Start of inlined file: juce_ComponentPeer.h *********/
#ifndef __JUCE_COMPONENTPEER_JUCEHEADER__
#define __JUCE_COMPONENTPEER_JUCEHEADER__

class Component;
class Graphics;

/********* Start of inlined file: juce_MessageListener.h *********/
#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__
#define __JUCE_MESSAGELISTENER_JUCEHEADER__

/********* Start of inlined file: juce_Message.h *********/
#ifndef __JUCE_MESSAGE_JUCEHEADER__
#define __JUCE_MESSAGE_JUCEHEADER__

class MessageListener;
class MessageManager;

/** The base class for objects that can be delivered to a MessageListener.

    The simplest Message object contains a few integer and pointer parameters
    that the user can set, and this is enough for a lot of purposes. For passing more
    complex data, subclasses of Message can also be used.

    @see MessageListener, MessageManager, ActionListener, ChangeListener
*/
class JUCE_API  Message
{
public:

    /** Creates an uninitialised message.

        The class's variables will also be left uninitialised.
    */
    Message() throw();

    /** Creates a message object, filling in the member variables.

        The corresponding public member variables will be set from the parameters
        passed in.
    */
    Message (const int intParameter1,
             const int intParameter2,
             const int intParameter3,
             void* const pointerParameter) throw();

    /** Destructor. */
    virtual ~Message() throw();

    // These values can be used for carrying simple data that the application needs to
    // pass around. For more complex messages, just create a subclass.

    int intParameter1;          /**< user-defined integer value. */
    int intParameter2;          /**< user-defined integer value. */
    int intParameter3;          /**< user-defined integer value. */
    void* pointerParameter;     /**< user-defined pointer value. */

    juce_UseDebuggingNewOperator

private:
    friend class MessageListener;
    friend class MessageManager;
    MessageListener* messageRecipient;

    Message (const Message&);
    const Message& operator= (const Message&);
};

#endif   // __JUCE_MESSAGE_JUCEHEADER__
/********* End of inlined file: juce_Message.h *********/

/**
    MessageListener subclasses can post and receive Message objects.

    @see Message, MessageManager, ActionListener, ChangeListener
*/
class JUCE_API  MessageListener
{
protected:

    /** Creates a MessageListener. */
    MessageListener() throw();

public:

    /** Destructor.

        When a MessageListener is deleted, it removes itself from a global list
        of registered listeners, so that the isValidMessageListener() method
        will no longer return true.
    */
    virtual ~MessageListener();

    /** This is the callback method that receives incoming messages.

        This is called by the MessageManager from its dispatch loop.

        @see postMessage
    */
    virtual void handleMessage (const Message& message) = 0;

    /** Sends a message to the message queue, for asynchronous delivery to this listener
        later on.

        This method can be called safely by any thread.

        @param message      the message object to send - this will be deleted
                            automatically by the message queue, so don't keep any
                            references to it after calling this method.
        @see handleMessage
    */
    void postMessage (Message* const message) const throw();

    /** Checks whether this MessageListener has been deleted.

        Although not foolproof, this method is safe to call on dangling or null
        pointers. A list of active MessageListeners is kept internally, so this
        checks whether the object is on this list or not.

        Note that it's possible to get a false-positive here, if an object is
        deleted and another is subsequently created that happens to be at the
        exact same memory location, but I can't think of a good way of avoiding
        this.
    */
    bool isValidMessageListener() const throw();
};

#endif   // __JUCE_MESSAGELISTENER_JUCEHEADER__
/********* End of inlined file: juce_MessageListener.h *********/

class ComponentBoundsConstrainer;
class ComponentDeletionWatcher;

/**
    The base class for window objects that wrap a component as a real operating
    system object.

    This is an abstract base class - the platform specific code contains default
    implementations of it that create and manage windows.

    @see Component::createNewPeer
*/
class JUCE_API  ComponentPeer    : public MessageListener
{
public:

    /** A combination of these flags is passed to the ComponentPeer constructor. */
    enum StyleFlags
    {
        windowAppearsOnTaskbar      = (1 << 0),    /**< Indicates that the window should have a corresponding
                                                        entry on the taskbar (ignored on MacOSX) */
        windowIsTemporary           = (1 << 1),    /**< Indicates that the window is a temporary popup, like a menu,
                                                        tooltip, etc. */
        windowIgnoresMouseClicks    = (1 << 2),    /**< Indicates that the window should let mouse clicks pass
                                                        through it (may not be possible on some platforms). */
        windowHasTitleBar           = (1 << 3),    /**< Indicates that the window should have a normal OS-specific
                                                        title bar and frame\. if not specified, the window will be
                                                        borderless. */
        windowIsResizable           = (1 << 4),    /**< Indicates that the window should have a resizable border. */
        windowHasMinimiseButton     = (1 << 5),    /**< Indicates that if the window has a title bar, it should have a
                                                        minimise button on it. */
        windowHasMaximiseButton     = (1 << 6),    /**< Indicates that if the window has a title bar, it should have a
                                                        maximise button on it. */
        windowHasCloseButton        = (1 << 7),    /**< Indicates that if the window has a title bar, it should have a
                                                        close button on it. */
        windowHasDropShadow         = (1 << 8),    /**< Indicates that the window should have a drop-shadow (this may
                                                        not be possible on all platforms). */
        windowRepaintedExplictly    = (1 << 9),    /**< Not intended for public use - this tells a window not to
                                                        do its own repainting, but only to repaint when the
                                                        performAnyPendingRepaintsNow() method is called. */
        windowIgnoresKeyPresses     = (1 << 10),   /**< Tells the window not to catch any keypresses. This can
                                                        be used for things like plugin windows, to stop them interfering
                                                        with the host's shortcut keys */
        windowIsSemiTransparent     = (1 << 31)    /**< Not intended for public use - makes a window transparent. */

    };

    /** Creates a peer.

        The component is the one that we intend to represent, and the style flags are
        a combination of the values in the StyleFlags enum
    */
    ComponentPeer (Component* const component,
                   const int styleFlags) throw();

    /** Destructor. */
    virtual ~ComponentPeer();

    /** Returns the component being represented by this peer. */
    Component* getComponent() const throw()                 { return component; }

    /** Returns the set of style flags that were set when the window was created.

        @see Component::addToDesktop
    */
    int getStyleFlags() const throw()                       { return styleFlags; }

    /** Returns the raw handle to whatever kind of window is being used.

        On windows, this is probably a HWND, on the mac, it's likely to be a WindowRef,
        but rememeber there's no guarantees what you'll get back.
    */
    virtual void* getNativeHandle() const = 0;

    /** Shows or hides the window. */
    virtual void setVisible (bool shouldBeVisible) = 0;

    /** Changes the title of the window. */
    virtual void setTitle (const String& title) = 0;

    /** Moves the window without changing its size.

        If the native window is contained in another window, then the co-ordinates are
        relative to the parent window's origin, not the screen origin.

        This should result in a callback to handleMovedOrResized().
    */
    virtual void setPosition (int x, int y) = 0;

    /** Resizes the window without changing its position.

        This should result in a callback to handleMovedOrResized().
    */
    virtual void setSize (int w, int h) = 0;

    /** Moves and resizes the window.

        If the native window is contained in another window, then the co-ordinates are
        relative to the parent window's origin, not the screen origin.

        This should result in a callback to handleMovedOrResized().
    */
    virtual void setBounds (int x, int y, int w, int h, const bool isNowFullScreen) = 0;

    /** Returns the current position and size of the window.

        If the native window is contained in another window, then the co-ordinates are
        relative to the parent window's origin, not the screen origin.
    */
    virtual void getBounds (int& x, int& y, int& w, int& h) const = 0;

    /** Returns the x-position of this window, relative to the screen's origin. */
    virtual int getScreenX() const = 0;

    /** Returns the y-position of this window, relative to the screen's origin. */
    virtual int getScreenY() const = 0;

    /** Converts a position relative to the top-left of this component to screen co-ordinates. */
    virtual void relativePositionToGlobal (int& x, int& y) = 0;

    /** Converts a screen co-ordinate to a position relative to the top-left of this component. */
    virtual void globalPositionToRelative (int& x, int& y) = 0;

    /** Minimises the window. */
    virtual void setMinimised (bool shouldBeMinimised) = 0;

    /** True if the window is currently minimised. */
    virtual bool isMinimised() const = 0;

    /** Enable/disable fullscreen mode for the window. */
    virtual void setFullScreen (bool shouldBeFullScreen) = 0;

    /** True if the window is currently full-screen. */
    virtual bool isFullScreen() const = 0;

    /** Sets the size to restore to if fullscreen mode is turned off. */
    void setNonFullScreenBounds (const Rectangle& newBounds) throw();

    /** Returns the size to restore to if fullscreen mode is turned off. */
    const Rectangle& getNonFullScreenBounds() const throw();

    /** Attempts to change the icon associated with this window.
    */
    virtual void setIcon (const Image& newIcon) = 0;

    /** Sets a constrainer to use if the peer can resize itself.

        The constrainer won't be deleted by this object, so the caller must manage its lifetime.
    */
    void setConstrainer (ComponentBoundsConstrainer* const newConstrainer) throw();

    /** Returns the current constrainer, if one has been set. */
    ComponentBoundsConstrainer* getConstrainer() const throw()              { return constrainer; }

    /** Checks if a point is in the window.

        Coordinates are relative to the top-left of this window. If trueIfInAChildWindow
        is false, then this returns false if the point is actually inside a child of this
        window.
    */
    virtual bool contains (int x, int y, bool trueIfInAChildWindow) const = 0;

    /** Returns the size of the window frame that's around this window.

        Whether or not the window has a normal window frame depends on the flags
        that were set when the window was created by Component::addToDesktop()
    */
    virtual const BorderSize getFrameSize() const = 0;

    /** This is called when the window's bounds change.

        A peer implementation must call this when the window is moved and resized, so that
        this method can pass the message on to the component.
    */
    void handleMovedOrResized();

    /** This is called if the screen resolution changes.

        A peer implementation must call this if the monitor arrangement changes or the available
        screen size changes.
    */
    void handleScreenSizeChange();

    /** This is called to repaint the component into the given context. */
    void handlePaint (LowLevelGraphicsContext& contextToPaintTo);

    /** Sets this window to either be always-on-top or normal.

        Some kinds of window might not be able to do this, so should return false.
    */
    virtual bool setAlwaysOnTop (bool alwaysOnTop) = 0;

    /** Brings the window to the top, optionally also giving it focus. */
    virtual void toFront (bool makeActive) = 0;

    /** Moves the window to be just behind another one. */
    virtual void toBehind (ComponentPeer* other) = 0;

    /** Called when the window is brought to the front, either by the OS or by a call
        to toFront().
    */
    void handleBroughtToFront();

    /** True if the window has the keyboard focus. */
    virtual bool isFocused() const = 0;

    /** Tries to give the window keyboard focus. */
    virtual void grabFocus() = 0;

    /** Tells the window that text input may be required at the given position.

        This may cause things like a virtual on-screen keyboard to appear, depending
        on the OS.
    */
    virtual void textInputRequired (int x, int y) = 0;

    /** Called when the window gains keyboard focus. */
    void handleFocusGain();
    /** Called when the window loses keyboard focus. */
    void handleFocusLoss();

    Component* getLastFocusedSubcomponent() const throw();

    /** Called when a key is pressed.

        For keycode info, see the KeyPress class.
        Returns true if the keystroke was used.
    */
    bool handleKeyPress (const int keyCode,
                         const juce_wchar textCharacter);

    /** Called whenever a key is pressed or released.
        Returns true if the keystroke was used.
    */
    bool handleKeyUpOrDown (const bool isKeyDown);

    /** Called whenever a modifier key is pressed or released. */
    void handleModifierKeysChange();

    /** Invalidates a region of the window to be repainted asynchronously. */
    virtual void repaint (int x, int y, int w, int h) = 0;

    /** This can be called (from the message thread) to cause the immediate redrawing
        of any areas of this window that need repainting.

        You shouldn't ever really need to use this, it's mainly for special purposes
        like supporting audio plugins where the host's event loop is out of our control.
    */
    virtual void performAnyPendingRepaintsNow() = 0;

    void handleMouseEnter (int x, int y, const int64 time);
    void handleMouseMove  (int x, int y, const int64 time);
    void handleMouseDown  (int x, int y, const int64 time);
    void handleMouseDrag  (int x, int y, const int64 time);
    void handleMouseUp    (const int oldModifiers, int x, int y, const int64 time);
    void handleMouseExit  (int x, int y, const int64 time);
    void handleMouseWheel (const int amountX, const int amountY, const int64 time);

    /** Causes a mouse-move callback to be made asynchronously. */
    void sendFakeMouseMove() throw();

    void handleUserClosingWindow();

    void handleFileDragMove (const StringArray& files, int x, int y);
    void handleFileDragExit (const StringArray& files);
    void handleFileDragDrop (const StringArray& files, int x, int y);

    /** Resets the masking region.

        The subclass should call this every time it's about to call the handlePaint
        method.

        @see addMaskedRegion
    */
    void clearMaskedRegion() throw();

    /** Adds a rectangle to the set of areas not to paint over.

        A component can call this on its peer during its paint() method, to signal
        that the painting code should ignore a given region. The reason
        for this is to stop embedded windows (such as OpenGL) getting painted over.

        The masked region is cleared each time before a paint happens, so a component
        will have to make sure it calls this every time it's painted.
    */
    void addMaskedRegion (int x, int y, int w, int h) throw();

    /** Returns the number of currently-active peers.

        @see getPeer
    */
    static int getNumPeers() throw();

    /** Returns one of the currently-active peers.

        @see getNumPeers
    */
    static ComponentPeer* getPeer (const int index) throw();

    /** Checks if this peer object is valid.

        @see getNumPeers
    */
    static bool isValidPeer (const ComponentPeer* const peer) throw();

    static void bringModalComponentToFront();

    juce_UseDebuggingNewOperator

protected:
    Component* const component;
    const int styleFlags;
    RectangleList maskedRegion;
    Rectangle lastNonFullscreenBounds;
    uint32 lastPaintTime;
    ComponentBoundsConstrainer* constrainer;

    static void updateCurrentModifiers() throw();

    /** @internal */
    void handleMessage (const Message& message);

private:

    Component* lastFocusedComponent;
    ComponentDeletionWatcher* dragAndDropTargetComponent;
    Component* lastDragAndDropCompUnderMouse;
    bool fakeMouseMessageSent : 1, isWindowMinimised : 1;

    friend class Component;
    static ComponentPeer* getPeerFor (const Component* const component) throw();

    void setLastDragDropTarget (Component* comp);

    ComponentPeer (const ComponentPeer&);
    const ComponentPeer& operator= (const ComponentPeer&);
};

#endif   // __JUCE_COMPONENTPEER_JUCEHEADER__
/********* End of inlined file: juce_ComponentPeer.h *********/

class LookAndFeel;

/**
    The base class for all JUCE user-interface objects.

*/
class JUCE_API  Component  : public MouseListener,
                             protected MessageListener
{
public:

    /** Creates a component.

        To get it to actually appear, you'll also need to:
        - Either add it to a parent component or use the addToDesktop() method to
          make it a desktop window
        - Set its size and position to something sensible
        - Use setVisible() to make it visible

        And for it to serve any useful purpose, you'll need to write a
        subclass of Component or use one of the other types of component from
        the library.
    */
    Component() throw();

    /** Destructor.

        Note that when a component is deleted, any child components it might
        contain are NOT deleted unless you explicitly call deleteAllChildren() first.
    */
    virtual ~Component();

    /** Creates a component, setting its name at the same time.

        @see getName, setName
    */
    Component (const String& componentName) throw();

    /** Returns the name of this component.

        @see setName
    */
    const String& getName() const throw()                   { return componentName_; }

    /** Sets the name of this component.

        When the name changes, all registered ComponentListeners will receive a
        ComponentListener::componentNameChanged() callback.

        @see getName
    */
    virtual void setName (const String& newName);

    /** Checks whether this Component object has been deleted.

        This will check whether this object is still a valid component, or whether
        it's been deleted.

        It's safe to call this on null or dangling pointers, but note that there is a
        small risk if another new (but different) component has been created at the
        same memory address which this one occupied, this methods can return a
        false positive.
    */
    bool isValidComponent() const throw();

    /** Makes the component visible or invisible.

        This method will show or hide the component.
        Note that components default to being non-visible when first created.
        Also note that visible components won't be seen unless all their parent components
        are also visible.

        This method will call visibilityChanged() and also componentVisibilityChanged()
        for any component listeners that are interested in this component.

        @param shouldBeVisible  whether to show or hide the component
        @see isVisible, isShowing, visibilityChanged, ComponentListener::componentVisibilityChanged
    */
    virtual void setVisible (bool shouldBeVisible);

    /** Tests whether the component is visible or not.

        this doesn't necessarily tell you whether this comp is actually on the screen
        because this depends on whether all the parent components are also visible - use
        isShowing() to find this out.

        @see isShowing, setVisible
    */
    bool isVisible() const throw()                          { return flags.visibleFlag; }

    /** Called when this component's visiblility changes.

        @see setVisible, isVisible
    */
    virtual void visibilityChanged();

    /** Tests whether this component and all its parents are visible.

        @returns    true only if this component and all its parents are visible.
        @see isVisible
    */
    bool isShowing() const throw();

    /** Makes a component invisible using a groovy fade-out and animated zoom effect.

        To do this, this function will cunningly:
            - take a snapshot of the component as it currently looks
            - call setVisible(false) on the component
            - replace it with a special component that will continue drawing the
              snapshot, animating it and gradually making it more transparent
            - when it's gone, the special component will also be deleted

        As soon as this method returns, the component can be safely removed and deleted
        leaving the proxy to do the fade-out, so it's even ok to call this in a
        component's destructor.

        Passing non-zero x and y values will cause the ghostly component image to
        also whizz off by this distance while fading out. If the scale factor is
        not 1.0, it will also zoom from the component's current size to this new size.

        One thing to be careful about is that the parent component must be able to cope
        with this unknown component type being added to it.
    */
    void fadeOutComponent (const int lengthOfFadeOutInMilliseconds,
                           const int deltaXToMove = 0,
                           const int deltaYToMove = 0,
                           const float scaleFactorAtEnd = 1.0f);

    /** Makes this component appear as a window on the desktop.

        Note that before calling this, you should make sure that the component's opacity is
        set correctly using setOpaque(). If the component is non-opaque, the windowing
        system will try to create a special transparent window for it, which will generally take
        a lot more CPU to operate (and might not even be possible on some platforms).

        If the component is inside a parent component at the time this method is called, it
        will be first be removed from that parent. Likewise if a component on the desktop
        is subsequently added to another component, it'll be removed from the desktop.

        @param windowStyleFlags             a combination of the flags specified in the
                                            ComponentPeer::StyleFlags enum, which define the
                                            window's characteristics.
        @param nativeWindowToAttachTo       this allows an OS object to be passed-in as the window
                                            in which the juce component should place itself. On Windows,
                                            this would be a HWND, a HIViewRef on the Mac. Not necessarily
                                            supported on all platforms, and best left as 0 unless you know
                                            what you're doing
        @see removeFromDesktop, isOnDesktop, userTriedToCloseWindow,
             getPeer, ComponentPeer::setMinimised, ComponentPeer::StyleFlags,
             ComponentPeer::getStyleFlags, ComponentPeer::setFullScreen
    */
    virtual void addToDesktop (int windowStyleFlags,
                               void* nativeWindowToAttachTo = 0);

    /** If the component is currently showing on the desktop, this will hide it.

        You can also use setVisible() to hide a desktop window temporarily, but
        removeFromDesktop() will free any system resources that are being used up.

        @see addToDesktop, isOnDesktop
    */
    void removeFromDesktop();

    /** Returns true if this component is currently showing on the desktop.

        @see addToDesktop, removeFromDesktop
    */
    bool isOnDesktop() const throw();

    /** Returns the heavyweight window that contains this component.

        If this component is itself on the desktop, this will return the window
        object that it is using. Otherwise, it will return the window of
        its top-level parent component.

        This may return 0 if there isn't a desktop component.

        @see addToDesktop, isOnDesktop
    */
    ComponentPeer* getPeer() const throw();

    /** For components on the desktop, this is called if the system wants to close the window.

        This is a signal that either the user or the system wants the window to close. The
        default implementation of this method will trigger an assertion to warn you that your
        component should do something about it, but you can override this to ignore the event
        if you want.
    */
    virtual void userTriedToCloseWindow();

    /** Called for a desktop component which has just been minimised or un-minimised.

        This will only be called for components on the desktop.

        @see getPeer, ComponentPeer::setMinimised, ComponentPeer::isMinimised
    */
    virtual void minimisationStateChanged (bool isNowMinimised);

    /** Brings the component to the front of its siblings.

        If some of the component's siblings have had their 'always-on-top' flag set,
        then they will still be kept in front of this one (unless of course this
        one is also 'always-on-top').

        @param shouldAlsoGainFocus  if true, this will also try to assign keyboard focus
                                    to the component (see grabKeyboardFocus() for more details)
        @see toBack, toBehind, setAlwaysOnTop
    */
    void toFront (const bool shouldAlsoGainFocus);

    /** Changes this component's z-order to be at the back of all its siblings.

        If the component is set to be 'always-on-top', it will only be moved to the
        back of the other other 'always-on-top' components.

        @see toFront, toBehind, setAlwaysOnTop
    */
    void toBack();

    /** Changes this component's z-order so that it's just behind another component.

        @see toFront, toBack
    */
    void toBehind (Component* const other);

    /** Sets whether the component should always be kept at the front of its siblings.

        @see isAlwaysOnTop
    */
    void setAlwaysOnTop (const bool shouldStayOnTop);

    /** Returns true if this component is set to always stay in front of its siblings.

        @see setAlwaysOnTop
    */
    bool isAlwaysOnTop() const throw();

    /** Returns the x co-ordinate of the component's left edge.

        This is a distance in pixels from the left edge of the component's parent.

        @see getScreenX
    */
    inline int getX() const throw()                         { return bounds_.getX(); }

    /** Returns the y co-ordinate of the top of this component.

        This is a distance in pixels from the top edge of the component's parent.

        @see getScreenY
    */
    inline int getY() const throw()                         { return bounds_.getY(); }

    /** Returns the component's width in pixels. */
    inline int getWidth() const throw()                     { return bounds_.getWidth(); }

    /** Returns the component's height in pixels. */
    inline int getHeight() const throw()                    { return bounds_.getHeight(); }

    /** Returns the x co-ordinate of the component's right-hand edge.

        This is a distance in pixels from the left edge of the component's parent.
    */
    int getRight() const throw()                            { return bounds_.getRight(); }

    /** Returns the y co-ordinate of the bottom edge of this component.

        This is a distance in pixels from the top edge of the component's parent.
    */
    int getBottom() const throw()                           { return bounds_.getBottom(); }

    /** Returns this component's bounding box.

        The rectangle returned is relative to the top-left of the component's parent.
    */
    const Rectangle& getBounds() const throw()              { return bounds_; }

    /** Returns the region of this component that's not obscured by other, opaque components.

        The RectangleList that is returned represents the area of this component
        which isn't covered by opaque child components.

        If includeSiblings is true, it will also take into account any siblings
        that may be overlapping the component.
    */
    void getVisibleArea (RectangleList& result,
                         const bool includeSiblings) const;

    /** Returns this component's x co-ordinate relative the the screen's top-left origin.

        @see getX, relativePositionToGlobal
    */
    int getScreenX() const throw();

    /** Returns this component's y co-ordinate relative the the screen's top-left origin.

        @see getY, relativePositionToGlobal
    */
    int getScreenY() const throw();

    /** Converts a position relative to this component's top-left into a screen co-ordinate.

        @see globalPositionToRelative, relativePositionToOtherComponent
    */
    void relativePositionToGlobal (int& x, int& y) const throw();

    /** Converts a screen co-ordinate into a position relative to this component's top-left.

        @see relativePositionToGlobal, relativePositionToOtherComponent
    */
    void globalPositionToRelative (int& x, int& y) const throw();

    /** Converts a position relative to this component's top-left into a position
        relative to another component's top-left.

        @see relativePositionToGlobal, globalPositionToRelative
    */
    void relativePositionToOtherComponent (const Component* const targetComponent,
                                           int& x, int& y) const throw();

    /** Moves the component to a new position.

        Changes the component's top-left position (without changing its size).
        The position is relative to the top-left of the component's parent.

        If the component actually moves, this method will make a synchronous call to moved().

        @see setBounds, ComponentListener::componentMovedOrResized
    */
    void setTopLeftPosition (const int x, const int y);

    /** Moves the component to a new position.

        Changes the position of the component's top-right corner (keeping it the same size).
        The position is relative to the top-left of the component's parent.

        If the component actually moves, this method will make a synchronous call to moved().
    */
    void setTopRightPosition (const int x, const int y);

    /** Changes the size of the component.

        A synchronous call to resized() will be occur if the size actually changes.
    */
    void setSize (const int newWidth, const int newHeight);

    /** Changes the component's position and size.

        The co-ordinates are relative to the top-left of the component's parent, or relative
        to the origin of the screen is the component is on the desktop.

        If this method changes the component's top-left position, it will make a synchronous
        call to moved(). If it changes the size, it will also make a call to resized().

        @see setTopLeftPosition, setSize, ComponentListener::componentMovedOrResized
    */
    void setBounds (int x, int y, int width, int height);

    /** Changes the component's position and size.

        @see setBounds
    */
    void setBounds (const Rectangle& newBounds);

    /** Changes the component's position and size in terms of fractions of its parent's size.

        The values are factors of the parent's size, so for example
        setBoundsRelative (0.2f, 0.2f, 0.5f, 0.5f) would give it half the
        width and height of the parent, with its top-left position 20% of
        the way across and down the parent.
    */
    void setBoundsRelative (const float proportionalX, const float proportionalY,
                            const float proportionalWidth, const float proportionalHeight);

    /** Changes the component's position and size based on the amount of space to leave around it.

        This will position the component within its parent, leaving the specified number of
        pixels around each edge.
    */
    void setBoundsInset (const BorderSize& borders);

    /** Positions the component within a given rectangle, keeping its proportions
        unchanged.

        If onlyReduceInSize is false, the component will be resized to fill as much of the
        rectangle as possible without changing its aspect ratio (the component's
        current size is used to determine its aspect ratio, so a zero-size component
        won't work here). If onlyReduceInSize is true, it will only be resized if it's
        too big to fit inside the rectangle.

        It will then be positioned within the rectangle according to the justification flags
        specified.
    */
    void setBoundsToFit (int x, int y, int width, int height,
                         const Justification& justification,
                         const bool onlyReduceInSize);

    /** Changes the position of the component's centre.

        Leaves the component's size unchanged, but sets the position of its centre
        relative to its parent's top-left.
    */
    void setCentrePosition (const int x, const int y);

    /** Changes the position of the component's centre.

        Leaves the position unchanged, but positions its centre relative to its
        parent's size. E.g. setCentreRelative (0.5f, 0.5f) would place it centrally in
        its parent.
    */
    void setCentreRelative (const float x, const float y);

    /** Changes the component's size and centres it within its parent.

        After changing the size, the component will be moved so that it's
        centred within its parent.
    */
    void centreWithSize (const int width, const int height);

    /** Returns a proportion of the component's width.

        This is a handy equivalent of (getWidth() * proportion).
    */
    int proportionOfWidth (const float proportion) const throw();

    /** Returns a proportion of the component's height.

        This is a handy equivalent of (getHeight() * proportion).
    */
    int proportionOfHeight (const float proportion) const throw();

    /** Returns the width of the component's parent.

        If the component has no parent (i.e. if it's on the desktop), this will return
        the width of the screen.
    */
    int getParentWidth() const throw();

    /** Returns the height of the component's parent.

        If the component has no parent (i.e. if it's on the desktop), this will return
        the height of the screen.
    */
    int getParentHeight() const throw();

    /** Returns the screen co-ordinates of the monitor that contains this component.

        If there's only one monitor, this will return its size - if there are multiple
        monitors, it will return the area of the monitor that contains the component's
        centre.
    */
    const Rectangle getParentMonitorArea() const throw();

    /** Returns the number of child components that this component contains.

        @see getChildComponent, getIndexOfChildComponent
    */
    int getNumChildComponents() const throw();

    /** Returns one of this component's child components, by it index.

        The component with index 0 is at the back of the z-order, the one at the
        front will have index (getNumChildComponents() - 1).

        If the index is out-of-range, this will return a null pointer.

        @see getNumChildComponents, getIndexOfChildComponent
    */
    Component* getChildComponent (const int index) const throw();

    /** Returns the index of this component in the list of child components.

        A value of 0 means it is first in the list (i.e. behind all other components). Higher
        values are further towards the front.

        Returns -1 if the component passed-in is not a child of this component.

        @see getNumChildComponents, getChildComponent, addChildComponent, toFront, toBack, toBehind
    */
    int getIndexOfChildComponent (const Component* const child) const throw();

    /** Adds a child component to this one.

        @param child    the new component to add. If the component passed-in is already
                        the child of another component, it'll first be removed from that.

        @param zOrder   The index in the child-list at which this component should be inserted.
                        A value of -1 will insert it in front of the others, 0 is the back.
        @see removeChildComponent, addAndMakeVisible, getChild,
             ComponentListener::componentChildrenChanged
    */
    void addChildComponent (Component* const child,
                            int zOrder = -1);

    /** Adds a child component to this one, and also makes the child visible if it isn't.

        Quite a useful function, this is just the same as calling addChildComponent()
        followed by setVisible (true) on the child.
    */
    void addAndMakeVisible (Component* const child,
                            int zOrder = -1);

    /** Removes one of this component's child-components.

        If the child passed-in isn't actually a child of this component (either because
        it's invalid or is the child of a different parent), then nothing is done.

        Note that removing a child will not delete it!

        @see addChildComponent, ComponentListener::componentChildrenChanged
    */
    void removeChildComponent (Component* const childToRemove);

    /** Removes one of this component's child-components by index.

        This will return a pointer to the component that was removed, or null if
        the index was out-of-range.

        Note that removing a child will not delete it!

        @see addChildComponent, ComponentListener::componentChildrenChanged
    */
    Component* removeChildComponent (const int childIndexToRemove);

    /** Removes all this component's children.

        Note that this won't delete them! To do that, use deleteAllChildren() instead.
    */
    void removeAllChildren();

    /** Removes all this component's children, and deletes them.

        @see removeAllChildren
    */
    void deleteAllChildren();

    /** Returns the component which this component is inside.

        If this is the highest-level component or hasn't yet been added to
        a parent, this will return null.
    */
    Component* getParentComponent() const throw()                   { return parentComponent_; }

    /** Searches the parent components for a component of a specified class.

        For example findParentComponentOfClass \<MyComp\>() would return the first parent
        component that can be dynamically cast to a MyComp, or will return 0 if none
        of the parents are suitable.

        N.B. The dummy parameter is needed to work around a VC6 compiler bug.
    */
    template <class TargetClass>
    TargetClass* findParentComponentOfClass (TargetClass* const dummyParameter = 0) const
    {
        (void) dummyParameter;
        Component* p = parentComponent_;
        while (p != 0)
        {
            TargetClass* target = dynamic_cast <TargetClass*> (p);
            if (target != 0)
                return target;

            p = p->parentComponent_;
        }

        return 0;
    }

    /** Returns the highest-level component which contains this one or its parents.

        This will search upwards in the parent-hierarchy from this component, until it
        finds the highest one that doesn't have a parent (i.e. is on the desktop or
        not yet added to a parent), and will return that.
    */
    Component* getTopLevelComponent() const throw();

    /** Checks whether a component is anywhere inside this component or its children.

        This will recursively check through this components children to see if the
        given component is anywhere inside.
    */
    bool isParentOf (const Component* possibleChild) const throw();

    /** Called to indicate that the component's parents have changed.

        When a component is added or removed from its parent, this method will
        be called on all of its children (recursively - so all children of its
        children will also be called as well).

        Subclasses can override this if they need to react to this in some way.

        @see getParentComponent, isShowing, ComponentListener::componentParentHierarchyChanged
    */
    virtual void parentHierarchyChanged();

    /** Subclasses can use this callback to be told when children are added or removed.

        @see parentHierarchyChanged
    */
    virtual void childrenChanged();

    /** Tests whether a given point inside the component.

        Overriding this method allows you to create components which only intercept
        mouse-clicks within a user-defined area.

        This is called to find out whether a particular x, y co-ordinate is
        considered to be inside the component or not, and is used by methods such
        as contains() and getComponentAt() to work out which component
        the mouse is clicked on.

        Components with custom shapes will probably want to override it to perform
        some more complex hit-testing.

        The default implementation of this method returns either true or false,
        depending on the value that was set by calling setInterceptsMouseClicks() (true
        is the default return value).

        Note that the hit-test region is not related to the opacity with which
        areas of a component are painted.

        Applications should never call hitTest() directly - instead use the
        contains() method, because this will also test for occlusion by the
        component's parent.

        Note that for components on the desktop, this method will be ignored, because it's
        not always possible to implement this behaviour on all platforms.

        @param x    the x co-ordinate to test, relative to the left hand edge of this
                    component. This value is guaranteed to be greater than or equal to
                    zero, and less than the component's width
        @param y    the y co-ordinate to test, relative to the top edge of this
                    component. This value is guaranteed to be greater than or equal to
                    zero, and less than the component's height
        @returns    true if the click is considered to be inside the component
        @see setInterceptsMouseClicks, contains
    */
    virtual bool hitTest (int x, int y);

    /** Changes the default return value for the hitTest() method.

        Setting this to false is an easy way to make a component pass its mouse-clicks
        through to the components behind it.

        When a component is created, the default setting for this is true.

        @param allowClicksOnThisComponent   if true, hitTest() will always return true; if false, it will
                                            return false (or true for child components if allowClicksOnChildComponents
                                            is true)
        @param allowClicksOnChildComponents if this is true and allowClicksOnThisComponent is false, then child
                                            components can be clicked on as normal but clicks on this component pass
                                            straight through; if this is false and allowClicksOnThisComponent
                                            is false, then neither this component nor any child components can
                                            be clicked on
        @see hitTest, getInterceptsMouseClicks
    */
    void setInterceptsMouseClicks (const bool allowClicksOnThisComponent,
                                   const bool allowClicksOnChildComponents) throw();

    /** Retrieves the current state of the mouse-click interception flags.

        On return, the two parameters are set to the state used in the last call to
        setInterceptsMouseClicks().

        @see setInterceptsMouseClicks
    */
    void getInterceptsMouseClicks (bool& allowsClicksOnThisComponent,
                                   bool& allowsClicksOnChildComponents) const throw();

    /** Returns true if a given point lies within this component or one of its children.

        Never override this method! Use hitTest to create custom hit regions.

        @param x    the x co-ordinate to test, relative to this component's left hand edge.
        @param y    the y co-ordinate to test, relative to this component's top edge.
        @returns    true if the point is within the component's hit-test area, but only if
                    that part of the component isn't clipped by its parent component. Note
                    that this won't take into account any overlapping sibling components
                    which might be in the way - for that, see reallyContains()
        @see hitTest, reallyContains, getComponentAt
    */
    virtual bool contains (int x, int y);

    /** Returns true if a given point lies in this component, taking any overlapping
        siblings into account.

        @param x    the x co-ordinate to test, relative to this component's left hand edge.
        @param y    the y co-ordinate to test, relative to this component's top edge.
        @param returnTrueIfWithinAChild     if the point actually lies within a child of this
                                            component, this determines the value that will
                                            be returned.

        @see contains, getComponentAt
    */
    bool reallyContains (int x, int y,
                         const bool returnTrueIfWithinAChild);

    /** Returns the component at a certain point within this one.

        @param x    the x co-ordinate to test, relative to this component's left hand edge.
        @param y    the y co-ordinate to test, relative to this component's top edge.
        @returns    the component that is at this position - which may be 0, this component,
                    or one of its children. Note that overlapping siblings that might actually
                    be in the way are not taken into account by this method - to account for these,
                    instead call getComponentAt on the top-level parent of this component.
        @see hitTest, contains, reallyContains
    */
    Component* getComponentAt (const int x, const int y);

    /** Marks the whole component as needing to be redrawn.

        Calling this will not do any repainting immediately, but will mark the component
        as 'dirty'. At some point in the near future the operating system will send a paint
        message, which will redraw all the dirty regions of all components.
        There's no guarantee about how soon after calling repaint() the redraw will actually
        happen, and other queued events may be delivered before a redraw is done.

        If the setBufferedToImage() method has been used to cause this component
        to use a buffer, the repaint() call will invalidate the component's buffer.

        To redraw just a subsection of the component rather than the whole thing,
        use the repaint (int, int, int, int) method.

        @see paint
    */
    void repaint() throw();

    /** Marks a subsection of this component as needing to be redrawn.

        Calling this will not do any repainting immediately, but will mark the given region
        of the component as 'dirty'. At some point in the near future the operating system
        will send a paint message, which will redraw all the dirty regions of all components.
        There's no guarantee about how soon after calling repaint() the redraw will actually
        happen, and other queued events may be delivered before a redraw is done.

        The region that is passed in will be clipped to keep it within the bounds of this
        component.

        @see repaint()
    */
    void repaint (const int x, const int y,
                  const int width, const int height) throw();

    /** Makes the component use an internal buffer to optimise its redrawing.

        Setting this flag to true will cause the component to allocate an
        internal buffer into which it paints itself, so that when asked to
        redraw itself, it can use this buffer rather than actually calling the
        paint() method.

        The buffer is kept until the repaint() method is called directly on
        this component (or until it is resized), when the image is invalidated
        and then redrawn the next time the component is painted.

        Note that only the drawing that happens within the component's paint()
        method is drawn into the buffer, it's child components are not buffered, and
        nor is the paintOverChildren() method.

        @see repaint, paint, createComponentSnapshot
    */
    void setBufferedToImage (const bool shouldBeBuffered) throw();

    /** Generates a snapshot of part of this component.

        This will return a new Image, the size of the rectangle specified,
        containing a snapshot of the specified area of the component and all
        its children.

        The image may or may not have an alpha-channel, depending on whether the
        image is opaque or not.

        If the clipImageToComponentBounds parameter is true and the area is greater than
        the size of the component, it'll be clipped. If clipImageToComponentBounds is false
        then parts of the component beyond its bounds can be drawn.

        The caller is responsible for deleting the image that is returned.

        @see paintEntireComponent
    */
    Image* createComponentSnapshot (const Rectangle& areaToGrab,
                                    const bool clipImageToComponentBounds = true);

    /** Draws this component and all its subcomponents onto the specified graphics
        context.

        You should very rarely have to use this method, it's simply there in case you need
        to draw a component with a custom graphics context for some reason, e.g. for
        creating a snapshot of the component.

        It calls paint(), paintOverChildren() and recursively calls paintEntireComponent()
        on its children in order to render the entire tree.

        The graphics context may be left in an undefined state after this method returns,
        so you may need to reset it if you're going to use it again.
    */
    void paintEntireComponent (Graphics& context);

    /** Adds an effect filter to alter the component's appearance.

        When a component has an effect filter set, then this is applied to the
        results of its paint() method. There are a few preset effects, such as
        a drop-shadow or glow, but they can be user-defined as well.

        The effect that is passed in will not be deleted by the component - the
        caller must take care of deleting it.

        To remove an effect from a component, pass a null pointer in as the parameter.

        @see ImageEffectFilter, DropShadowEffect, GlowEffect
    */
    void setComponentEffect (ImageEffectFilter* const newEffect);

    /** Returns the current component effect.

        @see setComponentEffect
    */
    ImageEffectFilter* getComponentEffect() const throw()               { return effect_; }

    /** Finds the appropriate look-and-feel to use for this component.

        If the component hasn't had a look-and-feel explicitly set, this will
        return the parent's look-and-feel, or just the default one if there's no
        parent.

        @see setLookAndFeel, lookAndFeelChanged
    */
    LookAndFeel& getLookAndFeel() const throw();

    /** Sets the look and feel to use for this component.

        This will also change the look and feel for any child components that haven't
        had their look set explicitly.

        The object passed in will not be deleted by the component, so it's the caller's
        responsibility to manage it. It may be used at any time until this component
        has been deleted.

        Calling this method will also invoke the sendLookAndFeelChange() method.

        @see getLookAndFeel, lookAndFeelChanged
    */
    void setLookAndFeel (LookAndFeel* const newLookAndFeel);

    /** Called to let the component react to a change in the look-and-feel setting.

        When the look-and-feel is changed for a component, this will be called in
        all its child components, recursively.

        It can also be triggered manually by the sendLookAndFeelChange() method, in case
        an application uses a LookAndFeel class that might have changed internally.

        @see sendLookAndFeelChange, getLookAndFeel
    */
    virtual void lookAndFeelChanged();

    /** Calls the lookAndFeelChanged() method in this component and all its children.

        This will recurse through the children and their children, calling lookAndFeelChanged()
        on them all.

        @see lookAndFeelChanged
    */
    void sendLookAndFeelChange();

    /** Indicates whether any parts of the component might be transparent.

        Components that always paint all of their contents with solid colour and
        thus completely cover any components behind them should use this method
        to tell the repaint system that they are opaque.

        This information is used to optimise drawing, because it means that
        objects underneath opaque windows don't need to be painted.

        By default, components are considered transparent, unless this is used to
        make it otherwise.

        @see isOpaque, getVisibleArea
    */
    void setOpaque (const bool shouldBeOpaque) throw();

    /** Returns true if no parts of this component are transparent.

        @returns the value that was set by setOpaque, (the default being false)
        @see setOpaque
    */
    bool isOpaque() const throw();

    /** Indicates whether the component should be brought to the front when clicked.

        Setting this flag to true will cause the component to be brought to the front
        when the mouse is clicked somewhere inside it or its child components.

        Note that a top-level desktop window might still be brought to the front by the
        operating system when it's clicked, depending on how the OS works.

        By default this is set to false.

        @see setMouseClickGrabsKeyboardFocus
    */
    void setBroughtToFrontOnMouseClick (const bool shouldBeBroughtToFront) throw();

    /** Indicates whether the component should be brought to the front when clicked-on.

        @see setBroughtToFrontOnMouseClick
    */
    bool isBroughtToFrontOnMouseClick() const throw();

    // Keyboard focus methods

    /** Sets a flag to indicate whether this component needs keyboard focus or not.

        By default components aren't actually interested in gaining the
        focus, but this method can be used to turn this on.

        See the grabKeyboardFocus() method for details about the way a component
        is chosen to receive the focus.

        @see grabKeyboardFocus, getWantsKeyboardFocus
    */
    void setWantsKeyboardFocus (const bool wantsFocus) throw();

    /** Returns true if the component is interested in getting keyboard focus.

        This returns the flag set by setWantsKeyboardFocus(). The default
        setting is false.

        @see setWantsKeyboardFocus
    */
    bool getWantsKeyboardFocus() const throw();

    /** Chooses whether a click on this component automatically grabs the focus.

        By default this is set to true, but you might want a component which can
        be focused, but where you don't want the user to be able to affect it directly
        by clicking.
    */
    void setMouseClickGrabsKeyboardFocus (const bool shouldGrabFocus);

    /** Returns the last value set with setMouseClickGrabsKeyboardFocus().

        See setMouseClickGrabsKeyboardFocus() for more info.
    */
    bool getMouseClickGrabsKeyboardFocus() const throw();

    /** Tries to give keyboard focus to this component.

        When the user clicks on a component or its grabKeyboardFocus()
        method is called, the following procedure is used to work out which
        component should get it:

        - if the component that was clicked on actually wants focus (as indicated
          by calling getWantsKeyboardFocus), it gets it.
        - if the component itself doesn't want focus, it will try to pass it
          on to whichever of its children is the default component, as determined by
          KeyboardFocusTraverser::getDefaultComponent()
        - if none of its children want focus at all, it will pass it up to its
          parent instead, unless it's a top-level component without a parent,
          in which case it just takes the focus itself.

        @see setWantsKeyboardFocus, getWantsKeyboardFocus, hasKeyboardFocus,
             getCurrentlyFocusedComponent, focusGained, focusLost,
             keyPressed, keyStateChanged
    */
    void grabKeyboardFocus();

    /** Returns true if this component currently has the keyboard focus.

        @param trueIfChildIsFocused     if this is true, then the method returns true if
                                        either this component or any of its children (recursively)
                                        have the focus. If false, the method only returns true if
                                        this component has the focus.

        @see grabKeyboardFocus, setWantsKeyboardFocus, getCurrentlyFocusedComponent,
             focusGained, focusLost
    */
    bool hasKeyboardFocus (const bool trueIfChildIsFocused) const throw();

    /** Returns the component that currently has the keyboard focus.

        @returns the focused component, or null if nothing is focused.
    */
    static Component* JUCE_CALLTYPE getCurrentlyFocusedComponent() throw();

    /** Tries to move the keyboard focus to one of this component's siblings.

        This will try to move focus to either the next or previous component. (This
        is the method that is used when shifting focus by pressing the tab key).

        Components for which getWantsKeyboardFocus() returns false are not looked at.

        @param moveToNext   if true, the focus will move forwards; if false, it will
                            move backwards
        @see grabKeyboardFocus, setFocusContainer, setWantsKeyboardFocus
    */
    void moveKeyboardFocusToSibling (const bool moveToNext);

    /** Creates a KeyboardFocusTraverser object to use to determine the logic by
        which focus should be passed from this component.

        The default implementation of this method will return a default
        KeyboardFocusTraverser if this component is a focus container (as determined
        by the setFocusContainer() method). If the component isn't a focus
        container, then it will recursively ask its parents for a KeyboardFocusTraverser.

        If you overrride this to return a custom KeyboardFocusTraverser, then
        this component and all its sub-components will use the new object to
        make their focusing decisions.

        The method should return a new object, which the caller is required to
        delete when no longer needed.
    */
    virtual KeyboardFocusTraverser* createFocusTraverser();

    /** Returns the focus order of this component, if one has been specified.

        By default components don't have a focus order - in that case, this
        will return 0. Lower numbers indicate that the component will be
        earlier in the focus traversal order.

        To change the order, call setExplicitFocusOrder().

        The focus order may be used by the KeyboardFocusTraverser class as part of
        its algorithm for deciding the order in which components should be traversed.
        See the KeyboardFocusTraverser class for more details on this.

        @see moveKeyboardFocusToSibling, createFocusTraverser, KeyboardFocusTraverser
    */
    int getExplicitFocusOrder() const throw();

    /** Sets the index used in determining the order in which focusable components
        should be traversed.

        A value of 0 or less is taken to mean that no explicit order is wanted, and
        that traversal should use other factors, like the component's position.

        @see getExplicitFocusOrder, moveKeyboardFocusToSibling
    */
    void setExplicitFocusOrder (const int newFocusOrderIndex) throw();

    /** Indicates whether this component is a parent for components that can have
        their focus traversed.

        This flag is used by the default implementation of the createFocusTraverser()
        method, which uses the flag to find the first parent component (of the currently
        focused one) which wants to be a focus container.

        So using this method to set the flag to 'true' causes this component to
        act as the top level within which focus is passed around.

        @see isFocusContainer, createFocusTraverser, moveKeyboardFocusToSibling
    */
    void setFocusContainer (const bool isFocusContainer) throw();

    /** Returns true if this component has been marked as a focus container.

        See setFocusContainer() for more details.

        @see setFocusContainer, moveKeyboardFocusToSibling, createFocusTraverser
    */
    bool isFocusContainer() const throw();

    /** Returns true if the component (and all its parents) are enabled.

        Components are enabled by default, and can be disabled with setEnabled(). Exactly
        what difference this makes to the component depends on the type. E.g. buttons
        and sliders will choose to draw themselves differently, etc.

        Note that if one of this component's parents is disabled, this will always
        return false, even if this component itself is enabled.

        @see setEnabled, enablementChanged
    */
    bool isEnabled() const throw();

    /** Enables or disables this component.

        Disabling a component will also cause all of its child components to become
        disabled.

        Similarly, enabling a component which is inside a disabled parent
        component won't make any difference until the parent is re-enabled.

        @see isEnabled, enablementChanged
    */
    void setEnabled (const bool shouldBeEnabled);

    /** Callback to indicate that this component has been enabled or disabled.

        This can be triggered by one of the component's parent components
        being enabled or disabled, as well as changes to the component itself.

        The default implementation of this method does nothing; your class may
        wish to repaint itself or something when this happens.

        @see setEnabled, isEnabled
    */
    virtual void enablementChanged();

    /** Changes the mouse cursor shape to use when the mouse is over this component.

        Note that the cursor set by this method can be overridden by the getMouseCursor
        method.

        @see MouseCursor
    */
    void setMouseCursor (const MouseCursor& cursorType) throw();

    /** Returns the mouse cursor shape to use when the mouse is over this component.

        The default implementation will return the cursor that was set by setCursor()
        but can be overridden for more specialised purposes, e.g. returning different
        cursors depending on the mouse position.

        @see MouseCursor
    */
    virtual const MouseCursor getMouseCursor();

    /** Forces the current mouse cursor to be updated.

        If you're overriding the getMouseCursor() method to control which cursor is
        displayed, then this will only be checked each time the user moves the mouse. So
        if you want to force the system to check that the cursor being displayed is
        up-to-date (even if the mouse is just sitting there), call this method.

        This isn't needed if you're only using setMouseCursor().
    */
    void updateMouseCursor() const throw();

    /** Components can override this method to draw their content.

        The paint() method gets called when a region of a component needs redrawing,
        either because the component's repaint() method has been called, or because
        something has happened on the screen that means a section of a window needs
        to be redrawn.

        Any child components will draw themselves over whatever this method draws. If
        you need to paint over the top of your child components, you can also implement
        the paintOverChildren() method to do this.

        If you want to cause a component to redraw itself, this is done asynchronously -
        calling the repaint() method marks a region of the component as "dirty", and the
        paint() method will automatically be called sometime later, by the message thread,
        to paint any bits that need refreshing. In Juce (and almost all modern UI frameworks),
        you never redraw something synchronously.

        You should never need to call this method directly - to take a snapshot of the
        component you could use createComponentSnapshot() or paintEntireComponent().

        @param g    the graphics context that must be used to do the drawing operations.
        @see repaint, paintOverChildren, Graphics
    */
    virtual void paint (Graphics& g);

    /** Components can override this method to draw over the top of their children.

        For most drawing operations, it's better to use the normal paint() method,
        but if you need to overlay something on top of the children, this can be
        used.

        @see paint, Graphics
    */
    virtual void paintOverChildren (Graphics& g);

    /** Called when the mouse moves inside this component.

        If the mouse button isn't pressed and the mouse moves over a component,
        this will be called to let the component react to this.

        A component will always get a mouseEnter callback before a mouseMove.

        @param e    details about the position and status of the mouse event
        @see mouseEnter, mouseExit, mouseDrag, contains
    */
    virtual void mouseMove         (const MouseEvent& e);

    /** Called when the mouse first enters this component.

        If the mouse button isn't pressed and the mouse moves into a component,
        this will be called to let the component react to this.

        When the mouse button is pressed and held down while being moved in
        or out of a component, no mouseEnter or mouseExit callbacks are made - only
        mouseDrag messages are sent to the component that the mouse was originally
        clicked on, until the button is released.

        If you're writing a component that needs to repaint itself when the mouse
        enters and exits, it might be quicker to use the setRepaintsOnMouseActivity()
        method.

        @param e    details about the position and status of the mouse event
        @see mouseExit, mouseDrag, mouseMove, contains
    */
    virtual void mouseEnter        (const MouseEvent& e);

    /** Called when the mouse moves out of this component.

        This will be called when the mouse moves off the edge of this
        component.

        If the mouse button was pressed, and it was then dragged off the
        edge of the component and released, then this callback will happen
        when the button is released, after the mouseUp callback.

        If you're writing a component that needs to repaint itself when the mouse
        enters and exits, it might be quicker to use the setRepaintsOnMouseActivity()
        method.

        @param e    details about the position and status of the mouse event
        @see mouseEnter, mouseDrag, mouseMove, contains
    */
    virtual void mouseExit         (const MouseEvent& e);

    /** Called when a mouse button is pressed while it's over this component.

        The MouseEvent object passed in contains lots of methods for finding out
        which button was pressed, as well as which modifier keys (e.g. shift, ctrl)
        were held down at the time.

        Once a button is held down, the mouseDrag method will be called when the
        mouse moves, until the button is released.

        @param e    details about the position and status of the mouse event
        @see mouseUp, mouseDrag, mouseDoubleClick, contains
    */
    virtual void mouseDown         (const MouseEvent& e);

    /** Called when the mouse is moved while a button is held down.

        When a mouse button is pressed inside a component, that component
        receives mouseDrag callbacks each time the mouse moves, even if the
        mouse strays outside the component's bounds.

        If you want to be able to drag things off the edge of a component
        and have the component scroll when you get to the edges, the
        beginDragAutoRepeat() method might be useful.

        @param e    details about the position and status of the mouse event
        @see mouseDown, mouseUp, mouseMove, contains, beginDragAutoRepeat
    */
    virtual void mouseDrag         (const MouseEvent& e);

    /** Called when a mouse button is released.

        A mouseUp callback is sent to the component in which a button was pressed
        even if the mouse is actually over a different component when the
        button is released.

        The MouseEvent object passed in contains lots of methods for finding out
        which buttons were down just before they were released.

        @param e    details about the position and status of the mouse event
        @see mouseDown, mouseDrag, mouseDoubleClick, contains
    */
    virtual void mouseUp           (const MouseEvent& e);

    /** Called when a mouse button has been double-clicked in this component.

        The MouseEvent object passed in contains lots of methods for finding out
        which button was pressed, as well as which modifier keys (e.g. shift, ctrl)
        were held down at the time.

        For altering the time limit used to detect double-clicks,
        see MouseEvent::setDoubleClickTimeout.

        @param e    details about the position and status of the mouse event
        @see mouseDown, mouseUp, MouseEvent::setDoubleClickTimeout,
             MouseEvent::getDoubleClickTimeout
    */
    virtual void mouseDoubleClick  (const MouseEvent& e);

    /** Called when the mouse-wheel is moved.

        This callback is sent to the component that the mouse is over when the
        wheel is moved.

        If not overridden, the component will forward this message to its parent, so
        that parent components can collect mouse-wheel messages that happen to
        child components which aren't interested in them.

        @param e                details about the position and status of the mouse event
        @param wheelIncrementX   the speed and direction of the horizontal scroll-wheel - a positive
                                 value means the wheel has been pushed to the right, negative means it
                                 was pushed to the left
        @param wheelIncrementY   the speed and direction of the vertical scroll-wheel - a positive
                                 value means the wheel has been pushed upwards, negative means it
                                 was pushed downwards
    */
    virtual void mouseWheelMove    (const MouseEvent& e,
                                    float wheelIncrementX,
                                    float wheelIncrementY);

    /** Ensures that a non-stop stream of mouse-drag events will be sent during the
        next mouse-drag operation.

        This allows you to make sure that mouseDrag() events sent continuously, even
        when the mouse isn't moving. This can be useful for things like auto-scrolling
        components when the mouse is near an edge.

        Call this method during a mouseDown() or mouseDrag() callback, specifying the
        minimum interval between consecutive mouse drag callbacks. The callbacks
        will continue until the mouse is released, and then the interval will be reset,
        so you need to make sure it's called every time you begin a drag event. If it
        is called when the mouse isn't actually being pressed, it will apply to the next
        mouse-drag operation that happens.

        Passing an interval of 0 or less will cancel the auto-repeat.

        @see mouseDrag
    */
    static void beginDragAutoRepeat (const int millisecondIntervalBetweenCallbacks);

    /** Causes automatic repaints when the mouse enters or exits this component.

        If turned on, then when the mouse enters/exits, or when the button is pressed/released
        on the component, it will trigger a repaint.

        This is handy for things like buttons that need to draw themselves differently when
        the mouse moves over them, and it avoids having to override all the different mouse
        callbacks and call repaint().

        @see mouseEnter, mouseExit, mouseDown, mouseUp
    */
    void setRepaintsOnMouseActivity (const bool shouldRepaint) throw();

    /** Registers a listener to be told when mouse events occur in this component.

        If you need to get informed about mouse events in a component but can't or
        don't want to override its methods, you can attach any number of listeners
        to the component, and these will get told about the events in addition to
        the component's own callbacks being called.

        Note that a MouseListener can also be attached to more than one component.

        @param newListener                              the listener to register
        @param wantsEventsForAllNestedChildComponents   if true, the listener will receive callbacks
                                                        for events that happen to any child component
                                                        within this component, including deeply-nested
                                                        child components. If false, it will only be
                                                        told about events that this component handles.
        @see MouseListener, removeMouseListener
    */
    void addMouseListener (MouseListener* const newListener,
                           const bool wantsEventsForAllNestedChildComponents) throw();

    /** Deregisters a mouse listener.

        @see addMouseListener, MouseListener
    */
    void removeMouseListener (MouseListener* const listenerToRemove) throw();

    /** Adds a listener that wants to hear about keypresses that this component receives.

        The listeners that are registered with a component are called by its keyPressed() or
        keyStateChanged() methods (assuming these haven't been overridden to do something else).

        If you add an object as a key listener, be careful to remove it when the object
        is deleted, or the component will be left with a dangling pointer.

        @see keyPressed, keyStateChanged, removeKeyListener
    */
    void addKeyListener (KeyListener* const newListener) throw();

    /** Removes a previously-registered key listener.

        @see addKeyListener
    */
    void removeKeyListener (KeyListener* const listenerToRemove) throw();

    /** Called when a key is pressed.

        When a key is pressed, the component that has the keyboard focus will have this
        method called. Remember that a component will only be given the focus if its
        setWantsKeyboardFocus() method has been used to enable this.

        If your implementation returns true, the event will be consumed and not passed
        on to any other listeners. If it returns false, the key will be passed to any
        KeyListeners that have been registered with this component. As soon as one of these
        returns true, the process will stop, but if they all return false, the event will
        be passed upwards to this component's parent, and so on.

        The default implementation of this method does nothing and returns false.

        @see keyStateChanged, getCurrentlyFocusedComponent, addKeyListener
    */
    virtual bool keyPressed (const KeyPress& key);

    /** Called when a key is pressed or released.

        Whenever a key on the keyboard is pressed or released (including modifier keys
        like shift and ctrl), this method will be called on the component that currently
        has the keyboard focus. Remember that a component will only be given the focus if
        its setWantsKeyboardFocus() method has been used to enable this.

        If your implementation returns true, the event will be consumed and not passed
        on to any other listeners. If it returns false, then any KeyListeners that have
        been registered with this component will have their keyStateChanged methods called.
        As soon as one of these returns true, the process will stop, but if they all return
        false, the event will be passed upwards to this component's parent, and so on.

        The default implementation of this method does nothing and returns false.

        To find out which keys are up or down at any time, see the KeyPress::isKeyCurrentlyDown()
        method.

        @param isKeyDown    true if a key has been pressed; false if it has been released

        @see keyPressed, KeyPress, getCurrentlyFocusedComponent, addKeyListener
    */
    virtual bool keyStateChanged (const bool isKeyDown);

    /** Called when a modifier key is pressed or released.

        Whenever the shift, control, alt or command keys are pressed or released,
        this method will be called on the component that currently has the keyboard focus.
        Remember that a component will only be given the focus if its setWantsKeyboardFocus()
        method has been used to enable this.

        The default implementation of this method actually calls its parent's modifierKeysChanged
        method, so that focused components which aren't interested in this will give their
        parents a chance to act on the event instead.

        @see keyStateChanged, ModifierKeys
    */
    virtual void modifierKeysChanged (const ModifierKeys& modifiers);

    /** Enumeration used by the focusChanged() and focusLost() methods. */
    enum FocusChangeType
    {
        focusChangedByMouseClick,   /**< Means that the user clicked the mouse to change focus. */
        focusChangedByTabKey,       /**< Means that the user pressed the tab key to move the focus. */
        focusChangedDirectly        /**< Means that the focus was changed by a call to grabKeyboardFocus(). */
    };

    /** Called to indicate that this component has just acquired the keyboard focus.

        @see focusLost, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus
    */
    virtual void focusGained (FocusChangeType cause);

    /** Called to indicate that this component has just lost the keyboard focus.

        @see focusGained, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus
    */
    virtual void focusLost (FocusChangeType cause);

    /** Called to indicate that one of this component's children has been focused or unfocused.

        Essentially this means that the return value of a call to hasKeyboardFocus (true) has
        changed. It happens when focus moves from one of this component's children (at any depth)
        to a component that isn't contained in this one, (or vice-versa).

        @see focusGained, setWantsKeyboardFocus, getCurrentlyFocusedComponent, hasKeyboardFocus
    */
    virtual void focusOfChildComponentChanged (FocusChangeType cause);

    /** Returns true if the mouse is currently over this component.

        If the mouse isn't over the component, this will return false, even if the
        mouse is currently being dragged - so you can use this in your mouseDrag
        method to find out whether it's really over the component or not.

        Note that when the mouse button is being held down, then the only component
        for which this method will return true is the one that was originally
        clicked on.

        @see isMouseButtonDown. isMouseOverOrDragging, mouseDrag
    */
    bool isMouseOver() const throw();

    /** Returns true if the mouse button is currently held down in this component.

        Note that this is a test to see whether the mouse is being pressed in this
        component, so it'll return false if called on component A when the mouse
        is actually being dragged in component B.

        @see isMouseButtonDownAnywhere, isMouseOver, isMouseOverOrDragging
    */
    bool isMouseButtonDown() const throw();

    /** True if the mouse is over this component, or if it's being dragged in this component.

        This is a handy equivalent to (isMouseOver() || isMouseButtonDown()).

        @see isMouseOver, isMouseButtonDown, isMouseButtonDownAnywhere
    */
    bool isMouseOverOrDragging() const throw();

    /** Returns true if a mouse button is currently down.

        Unlike isMouseButtonDown, this will test the current state of the
        buttons without regard to which component (if any) it has been
        pressed in.

        @see isMouseButtonDown, ModifierKeys
    */
    static bool JUCE_CALLTYPE isMouseButtonDownAnywhere() throw();

    /** Returns the mouse's current position, relative to this component.

        The co-ordinates are relative to the component's top-left corner.
    */
    void getMouseXYRelative (int& x, int& y) const throw();

    /** Returns the component that's currently underneath the mouse.

        @returns the component or 0 if there isn't one.
        @see contains, getComponentAt
    */
    static Component* JUCE_CALLTYPE getComponentUnderMouse() throw();

    /** Allows the mouse to move beyond the edges of the screen.

        Calling this method when the mouse button is currently pressed inside this component
        will remove the cursor from the screen and allow the mouse to (seem to) move beyond
        the edges of the screen.

        This means that the co-ordinates returned to mouseDrag() will be unbounded, and this
        can be used for things like custom slider controls or dragging objects around, where
        movement would be otherwise be limited by the mouse hitting the edges of the screen.

        The unbounded mode is automatically turned off when the mouse button is released, or
        it can be turned off explicitly by calling this method again.

        @param shouldUnboundedMovementBeEnabled     whether to turn this mode on or off
        @param keepCursorVisibleUntilOffscreen      if set to false, the cursor will immediately be
                                                    hidden; if true, it will only be hidden when it
                                                    is moved beyond the edge of the screen
    */
    void enableUnboundedMouseMovement (bool shouldUnboundedMovementBeEnabled,
                                       bool keepCursorVisibleUntilOffscreen = false) throw();

    /** Called when this component's size has been changed.

        A component can implement this method to do things such as laying out its
        child components when its width or height changes.

        The method is called synchronously as a result of the setBounds or setSize
        methods, so repeatedly changing a components size will repeatedly call its
        resized method (unlike things like repainting, where multiple calls to repaint
        are coalesced together).

        If the component is a top-level window on the desktop, its size could also
        be changed by operating-system factors beyond the application's control.

        @see moved, setSize
    */
    virtual void resized();

    /** Called when this component's position has been changed.

        This is called when the position relative to its parent changes, not when
        its absolute position on the screen changes (so it won't be called for
        all child components when a parent component is moved).

        The method is called synchronously as a result of the setBounds, setTopLeftPosition
        or any of the other repositioning methods, and like resized(), it will be
        called each time those methods are called.

        If the component is a top-level window on the desktop, its position could also
        be changed by operating-system factors beyond the application's control.

        @see resized, setBounds
    */
    virtual void moved();

    /** Called when one of this component's children is moved or resized.

        If the parent wants to know about changes to its immediate children (not
        to children of its children), this is the method to override.

        @see moved, resized, parentSizeChanged
    */
    virtual void childBoundsChanged (Component* child);

    /** Called when this component's immediate parent has been resized.

        If the component is a top-level window, this indicates that the screen size
        has changed.

        @see childBoundsChanged, moved, resized
    */
    virtual void parentSizeChanged();

    /** Called when this component has been moved to the front of its siblings.

        The component may have been brought to the front by the toFront() method, or
        by the operating system if it's a top-level window.

        @see toFront
    */
    virtual void broughtToFront();

    /** Adds a listener to be told about changes to the component hierarchy or position.

        Component listeners get called when this component's size, position or children
        change - see the ComponentListener class for more details.

        @param newListener  the listener to register - if this is already registered, it
                            will be ignored.
        @see ComponentListener, removeComponentListener
    */
    void addComponentListener (ComponentListener* const newListener) throw();

    /** Removes a component listener.

        @see addComponentListener
    */
    void removeComponentListener (ComponentListener* const listenerToRemove) throw();

    /** Dispatches a numbered message to this component.

        This is a quick and cheap way of allowing simple asynchronous messages to
        be sent to components. It's also safe, because if the component that you
        send the message to is a null or dangling pointer, this won't cause an error.

        The command ID is later delivered to the component's handleCommandMessage() method by
        the application's message queue.

        @see handleCommandMessage
    */
    void postCommandMessage (const int commandId) throw();

    /** Called to handle a command that was sent by postCommandMessage().

        This is called by the message thread when a command message arrives, and
        the component can override this method to process it in any way it needs to.

        @see postCommandMessage
    */
    virtual void handleCommandMessage (int commandId);

    /** Runs a component modally, waiting until the loop terminates.

        This method first makes the component visible, brings it to the front and
        gives it the keyboard focus.

        It then runs a loop, dispatching messages from the system message queue, but
        blocking all mouse or keyboard messages from reaching any components other
        than this one and its children.

        This loop continues until the component's exitModalState() method is called (or
        the component is deleted), and then this method returns, returning the value
        passed into exitModalState().

        @see enterModalState, exitModalState, isCurrentlyModal, getCurrentlyModalComponent,
             isCurrentlyBlockedByAnotherModalComponent, MessageManager::dispatchNextMessage
    */
    int runModalLoop();

    /** Puts the component into a modal state.

        This makes the component modal, so that messages are blocked from reaching
        any components other than this one and its children, but unlike runModalLoop(),
        this method returns immediately.

        If takeKeyboardFocus is true, the component will use grabKeyboardFocus() to
        get the focus, which is usually what you'll want it to do. If not, it will leave
        the focus unchanged.

        @see exitModalState, runModalLoop
    */
    void enterModalState (const bool takeKeyboardFocus = true);

    /** Ends a component's modal state.

        If this component is currently modal, this will turn of its modalness, and return
        a value to the runModalLoop() method that might have be running its modal loop.

        @see runModalLoop, enterModalState, isCurrentlyModal
    */
    void exitModalState (const int returnValue);

    /** Returns true if this component is the modal one.

        It's possible to have nested modal components, e.g. a pop-up dialog box
        that launches another pop-up, but this will only return true for
        the one at the top of the stack.

        @see getCurrentlyModalComponent
    */
    bool isCurrentlyModal() const throw();

    /** Returns the number of components that are currently in a modal state.
        @see getCurrentlyModalComponent
     */
    static int JUCE_CALLTYPE getNumCurrentlyModalComponents() throw();

    /** Returns one of the components that are currently modal.

        The index specifies which of the possible modal components to return. The order
        of the components in this list is the reverse of the order in which they became
        modal - so the component at index 0 is always the active component, and the others
        are progressively earlier ones that are themselves now blocked by later ones.

        @returns the modal component, or null if no components are modal (or if the
                index is out of range)
        @see getNumCurrentlyModalComponents, runModalLoop, isCurrentlyModal
    */
    static Component* JUCE_CALLTYPE getCurrentlyModalComponent (int index = 0) throw();

    /** Checks whether there's a modal component somewhere that's stopping this one
        from receiving messages.

        If there is a modal component, its canModalEventBeSentToComponent() method
        will be called to see if it will still allow this component to receive events.

        @see runModalLoop, getCurrentlyModalComponent
    */
    bool isCurrentlyBlockedByAnotherModalComponent() const throw();

    /** When a component is modal, this callback allows it to choose which other
        components can still receive events.

        When a modal component is active and the user clicks on a non-modal component,
        this method is called on the modal component, and if it returns true, the
        event is allowed to reach its target. If it returns false, the event is blocked
        and the inputAttemptWhenModal() callback is made.

        It called by the isCurrentlyBlockedByAnotherModalComponent() method. The default
        implementation just returns false in all cases.
    */
    virtual bool canModalEventBeSentToComponent (const Component* targetComponent);

    /** Called when the user tries to click on a component that is blocked by another
        modal component.

        When a component is modal and the user clicks on one of the other components,
        the modal component will receive this callback.

        The default implementation of this method will play a beep, and bring the currently
        modal component to the front, but it can be overridden to do other tasks.

        @see isCurrentlyBlockedByAnotherModalComponent, canModalEventBeSentToComponent
    */
    virtual void inputAttemptWhenModal();

    /** Returns one of the component's properties as a string.

        @param keyName                          the name of the property to retrieve
        @param useParentComponentIfNotFound     if this is true and the key isn't present in this component's
                                                properties, then it will check whether the parent component has
                                                the key.
        @param defaultReturnValue               a value to return if the named property doesn't actually exist
    */
    const String getComponentProperty (const String& keyName,
                                       const bool useParentComponentIfNotFound,
                                       const String& defaultReturnValue = String::empty) const throw();

    /** Returns one of the properties as an integer.

        @param keyName                          the name of the property to retrieve
        @param useParentComponentIfNotFound     if this is true and the key isn't present in this component's
                                                properties, then it will check whether the parent component has
                                                the key.
        @param defaultReturnValue               a value to return if the named property doesn't actually exist
    */
    int getComponentPropertyInt (const String& keyName,
                                 const bool useParentComponentIfNotFound,
                                 const int defaultReturnValue = 0) const throw();

    /** Returns one of the properties as an double.

        @param keyName                          the name of the property to retrieve
        @param useParentComponentIfNotFound     if this is true and the key isn't present in this component's
                                                properties, then it will check whether the parent component has
                                                the key.
        @param defaultReturnValue               a value to return if the named property doesn't actually exist
    */
    double getComponentPropertyDouble (const String& keyName,
                                       const bool useParentComponentIfNotFound,
                                       const double defaultReturnValue = 0.0) const throw();

    /** Returns one of the properties as an boolean.

        The result will be true if the string found for this key name can be parsed as a non-zero
        integer.

        @param keyName                          the name of the property to retrieve
        @param useParentComponentIfNotFound     if this is true and the key isn't present in this component's
                                                properties, then it will check whether the parent component has
                                                the key.
        @param defaultReturnValue               a value to return if the named property doesn't actually exist
    */
    bool getComponentPropertyBool (const String& keyName,
                                   const bool useParentComponentIfNotFound,
                                   const bool defaultReturnValue = false) const throw();

    /** Returns one of the properties as an colour.

        @param keyName                          the name of the property to retrieve
        @param useParentComponentIfNotFound     if this is true and the key isn't present in this component's
                                                properties, then it will check whether the parent component has
                                                the key.
        @param defaultReturnValue               a colour to return if the named property doesn't actually exist
    */
    const Colour getComponentPropertyColour (const String& keyName,
                                             const bool useParentComponentIfNotFound,
                                             const Colour& defaultReturnValue = Colours::black) const throw();

    /** Sets a named property as a string.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param value        the new value to set it to
        @see removeComponentProperty
    */
    void setComponentProperty (const String& keyName, const String& value) throw();

    /** Sets a named property to an integer.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param value        the new value to set it to
        @see removeComponentProperty
    */
    void setComponentProperty (const String& keyName, const int value) throw();

    /** Sets a named property to a double.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param value        the new value to set it to
        @see removeComponentProperty
    */
    void setComponentProperty (const String& keyName, const double value) throw();

    /** Sets a named property to a boolean.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param value        the new value to set it to
        @see removeComponentProperty
    */
    void setComponentProperty (const String& keyName, const bool value) throw();

    /** Sets a named property to a colour.

        @param keyName      the name of the property to set. (This mustn't be an empty string)
        @param newColour    the new colour to set it to
        @see removeComponentProperty
    */
    void setComponentProperty (const String& keyName, const Colour& newColour) throw();

    /** Deletes a named component property.

        @param keyName      the name of the property to delete. (This mustn't be an empty string)
        @see setComponentProperty, getComponentProperty
    */
    void removeComponentProperty (const String& keyName) throw();

    /** Returns the complete set of properties that have been set for this component.

        If no properties have been set, this will return a null pointer.

        @see getComponentProperty, setComponentProperty
    */
    PropertySet* getComponentProperties() const throw()           { return propertySet_; }

    /** Looks for a colour that has been registered with the given colour ID number.

        If a colour has been set for this ID number using setColour(), then it is
        returned. If none has been set, the method will try calling the component's
        LookAndFeel class's findColour() method. If none has been registered with the
        look-and-feel either, it will just return black.

        The colour IDs for various purposes are stored as enums in the components that
        they are relevent to - for an example, see Slider::ColourIds,
        Label::ColourIds, TextEditor::ColourIds, TreeView::ColourIds, etc.

        @see setColour, isColourSpecified, colourChanged, LookAndFeel::findColour, LookAndFeel::setColour
    */
    const Colour findColour (const int colourId, const bool inheritFromParent = false) const throw();

    /** Registers a colour to be used for a particular purpose.

        Changing a colour will cause a synchronous callback to the colourChanged()
        method, which your component can override if it needs to do something when
        colours are altered.

        For more details about colour IDs, see the comments for findColour().

        @see findColour, isColourSpecified, colourChanged, LookAndFeel::findColour, LookAndFeel::setColour
    */
    void setColour (const int colourId, const Colour& colour);

    /** If a colour has been set with setColour(), this will remove it.

        This allows you to make a colour revert to its default state.
    */
    void removeColour (const int colourId);

    /** Returns true if the specified colour ID has been explicitly set for this
        component using the setColour() method.
    */
    bool isColourSpecified (const int colourId) const throw();

    /** This looks for any colours that have been specified for this component,
        and copies them to the specified target component.
    */
    void copyAllExplicitColoursTo (Component& target) const throw();

    /** This method is called when a colour is changed by the setColour() method.

        @see setColour, findColour
    */
    virtual void colourChanged();

    /** Returns the underlying native window handle for this component.

        This is platform-dependent and strictly for power-users only!
    */
    void* getWindowHandle() const throw();

    /** When created, each component is given a number to uniquely identify it.

        The number is incremented each time a new component is created, so it's a more
        unique way of identifying a component than using its memory location (which
        may be reused after the component is deleted, of course).
    */
    uint32 getComponentUID() const throw()                { return componentUID; }

    juce_UseDebuggingNewOperator

private:

    friend class ComponentPeer;
    friend class InternalDragRepeater;

    static Component* currentlyFocusedComponent;
    static Component* componentUnderMouse;

    String componentName_;
    Component* parentComponent_;
    uint32 componentUID;
    Rectangle bounds_;
    unsigned short numDeepMouseListeners;
    Array <Component*> childComponentList_;
    LookAndFeel* lookAndFeel_;
    MouseCursor cursor_;
    ImageEffectFilter* effect_;
    Image* bufferedImage_;
    VoidArray* mouseListeners_;
    VoidArray* keyListeners_;
    VoidArray* componentListeners_;
    PropertySet* propertySet_;

    struct ComponentFlags
    {
        bool hasHeavyweightPeerFlag     : 1;
        bool visibleFlag                : 1;
        bool opaqueFlag                 : 1;
        bool ignoresMouseClicksFlag     : 1;
        bool allowChildMouseClicksFlag  : 1;
        bool wantsFocusFlag             : 1;
        bool isFocusContainerFlag       : 1;
        bool dontFocusOnMouseClickFlag  : 1;
        bool alwaysOnTopFlag            : 1;
        bool bufferToImageFlag          : 1;
        bool bringToFrontOnClickFlag    : 1;
        bool repaintOnMouseActivityFlag : 1;
        bool draggingFlag               : 1;
        bool mouseOverFlag              : 1;
        bool mouseInsideFlag            : 1;
        bool currentlyModalFlag         : 1;
        bool isDisabledFlag             : 1;
        bool childCompFocusedFlag       : 1;
#ifdef JUCE_DEBUG
        bool isInsidePaintCall          : 1;
#endif
    };

    union
    {
        uint32 componentFlags_;
        ComponentFlags flags;
    };

    void internalMouseEnter (int x, int y, const int64 time);
    void internalMouseExit  (int x, int y, const int64 time);
    void internalMouseDown  (int x, int y);
    void internalMouseUp    (const int oldModifiers, int x, int y, const int64 time);
    void internalMouseDrag  (int x, int y, const int64 time);
    void internalMouseMove  (int x, int y, const int64 time);
    void internalMouseWheel (const int intAmountX, const int intAmountY, const int64 time);
    void internalBroughtToFront();
    void internalFocusGain (const FocusChangeType cause);
    void internalFocusLoss (const FocusChangeType cause);
    void internalChildFocusChange (FocusChangeType cause);
    void internalModalInputAttempt();
    void internalModifierKeysChanged();
    void internalChildrenChanged();
    void internalHierarchyChanged();
    void internalUpdateMouseCursor (const bool forcedUpdate) throw();
    void sendMovedResizedMessages (const bool wasMoved, const bool wasResized);
    void repaintParent() throw();
    void sendFakeMouseMove() const;
    void takeKeyboardFocus (const FocusChangeType cause);
    void grabFocusInternal (const FocusChangeType cause, const bool canTryParent = true);
    static void giveAwayFocus();
    void sendEnablementChangeMessage();
    static void* runModalLoopCallback (void*);
    static void bringModalComponentToFront();
    void subtractObscuredRegions (RectangleList& result,
                                  const int deltaX, const int deltaY,
                                  const Rectangle& clipRect,
                                  const Component* const compToAvoid) const throw();
    void clipObscuredRegions (Graphics& g, const Rectangle& clipRect,
                              const int deltaX, const int deltaY) const throw();

    // how much of the component is not off the edges of its parents
    const Rectangle getUnclippedArea() const;
    void sendVisibilityChangeMessage();

    // This is included here just to cause a compile error if your code is still handling
    // drag-and-drop with this method. If so, just update it to use the new FileDragAndDropTarget
    // class, which is easy (just make your class inherit from FileDragAndDropTarget, and
    // implement its methods instead of this Component method).
    virtual void filesDropped (const StringArray&, int, int) {}

    // components aren't allowed to have copy constructors, as this would mess up parent
    // hierarchies. You might need to give your subclasses a private dummy constructor like
    // this one to avoid compiler warnings.
    Component (const Component&);

    const Component& operator= (const Component&);

    // (dummy method to cause a deliberate compile error - if you hit this, you need to update your
    // subclass to use the new parameters to keyStateChanged)
    virtual void keyStateChanged() {};

protected:
    /** @internal */
    virtual void internalRepaint (int x, int y, int w, int h);

    virtual ComponentPeer* createNewPeer (int styleFlags, void* nativeWindowToAttachTo);

    /** Overridden from the MessageListener parent class.

        You can override this if you really need to, but be sure to pass your unwanted messages up
        to this base class implementation, as the Component class needs to send itself messages
        to work properly.
    */
    void handleMessage (const Message&);
};

#endif   // __JUCE_COMPONENT_JUCEHEADER__
/********* End of inlined file: juce_Component.h *********/

/********* Start of inlined file: juce_ApplicationCommandInfo.h *********/
#ifndef __JUCE_APPLICATIONCOMMANDINFO_JUCEHEADER__
#define __JUCE_APPLICATIONCOMMANDINFO_JUCEHEADER__

/********* Start of inlined file: juce_ApplicationCommandID.h *********/
#ifndef __JUCE_APPLICATIONCOMMANDID_JUCEHEADER__
#define __JUCE_APPLICATIONCOMMANDID_JUCEHEADER__

/** A type used to hold the unique ID for an application command.

    This is a numeric type, so it can be stored as an integer.

    @see ApplicationCommandInfo, ApplicationCommandManager,
         ApplicationCommandTarget, KeyPressMappingSet
*/
typedef int CommandID;

/** A set of general-purpose application command IDs.

    Because these commands are likely to be used in most apps, they're defined
    here to help different apps to use the same numeric values for them.

    Of course you don't have to use these, but some of them are used internally by
    Juce - e.g. the quit ID is recognised as a command by the JUCEApplication class.

    @see ApplicationCommandInfo, ApplicationCommandManager,
         ApplicationCommandTarget, KeyPressMappingSet
*/
namespace StandardApplicationCommandIDs
{
    /** This command ID should be used to send a "Quit the App" command.

        This command is recognised by the JUCEApplication class, so if it is invoked
        and no other ApplicationCommandTarget handles the event first, the JUCEApplication
        object will catch it and call JUCEApplication::systemRequestedQuit().
    */
    static const CommandID  quit           = 0x1001;

    /** The command ID that should be used to send a "Delete" command. */
    static const CommandID  del            = 0x1002;

    /** The command ID that should be used to send a "Cut" command. */
    static const CommandID  cut            = 0x1003;

    /** The command ID that should be used to send a "Copy to clipboard" command. */
    static const CommandID  copy           = 0x1004;

    /** The command ID that should be used to send a "Paste from clipboard" command. */
    static const CommandID  paste          = 0x1005;

    /** The command ID that should be used to send a "Select all" command. */
    static const CommandID  selectAll      = 0x1006;

    /** The command ID that should be used to send a "Deselect all" command. */
    static const CommandID  deselectAll    = 0x1007;
}

#endif   // __JUCE_APPLICATIONCOMMANDID_JUCEHEADER__
/********* End of inlined file: juce_ApplicationCommandID.h *********/

/**
    Holds information describing an application command.

    This object is used to pass information about a particular command, such as its
    name, description and other usage flags.

    When an ApplicationCommandTarget is asked to provide information about the commands
    it can perform, this is the structure gets filled-in to describe each one.

    @see ApplicationCommandTarget, ApplicationCommandTarget::getCommandInfo(),
         ApplicationCommandManager
*/
struct JUCE_API  ApplicationCommandInfo
{

    ApplicationCommandInfo (const CommandID commandID) throw();

    /** Sets a number of the structures values at once.

        The meanings of each of the parameters is described below, in the appropriate
        member variable's description.
    */
    void setInfo (const String& shortName,
                  const String& description,
                  const String& categoryName,
                  const int flags) throw();

    /** An easy way to set or remove the isDisabled bit in the structure's flags field.

        If isActive is true, the flags member has the isDisabled bit cleared; if isActive
        is false, the bit is set.
    */
    void setActive (const bool isActive) throw();

    /** An easy way to set or remove the isTicked bit in the structure's flags field.
    */
    void setTicked (const bool isTicked) throw();

    /** Handy method for adding a keypress to the defaultKeypresses array.

        This is just so you can write things like:
        @code
        myinfo.addDefaultKeypress (T('s'), ModifierKeys::commandModifier);
        @endcode
        instead of
        @code
        myinfo.defaultKeypresses.add (KeyPress (T('s'), ModifierKeys::commandModifier));
        @endcode
    */
    void addDefaultKeypress (const int keyCode,
                             const ModifierKeys& modifiers) throw();

    /** The command's unique ID number.
    */
    CommandID commandID;

    /** A short name to describe the command.

        This should be suitable for use in menus, on buttons that trigger the command, etc.

        You can use the setInfo() method to quickly set this and some of the command's
        other properties.
    */
    String shortName;

    /** A longer description of the command.

        This should be suitable for use in contexts such as a KeyMappingEditorComponent or
        pop-up tooltip describing what the command does.

        You can use the setInfo() method to quickly set this and some of the command's
        other properties.
    */
    String description;

    /** A named category that the command fits into.

        You can give your commands any category you like, and these will be displayed in
        contexts such as the KeyMappingEditorComponent, where the category is used to group
        commands together.

        You can use the setInfo() method to quickly set this and some of the command's
        other properties.
    */
    String categoryName;

    /** A list of zero or more keypresses that should be used as the default keys for
        this command.

        Methods such as KeyPressMappingSet::resetToDefaultMappings() will use the keypresses in
        this list to initialise the default set of key-to-command mappings.

        @see addDefaultKeypress
    */
    Array <KeyPress> defaultKeypresses;

    /** Flags describing the ways in which this command should be used.

        A bitwise-OR of these values is stored in the ApplicationCommandInfo::flags
        variable.
    */
    enum CommandFlags
    {
        /** Indicates that the command can't currently be performed.

            The ApplicationCommandTarget::getCommandInfo() method must set this flag if it's
            not currently permissable to perform the command. If the flag is set, then
            components that trigger the command, e.g. PopupMenu, may choose to grey-out the
            command or show themselves as not being enabled.

            @see ApplicationCommandInfo::setActive
        */
        isDisabled                  = 1 << 0,

        /** Indicates that the command should have a tick next to it on a menu.

            If your command is shown on a menu and this is set, it'll show a tick next to
            it. Other components such as buttons may also use this flag to indicate that it
            is a value that can be toggled, and is currently in the 'on' state.

            @see ApplicationCommandInfo::setTicked
        */
        isTicked                    = 1 << 1,

        /** If this flag is present, then when a KeyPressMappingSet invokes the command,
            it will call the command twice, once on key-down and again on key-up.

            @see ApplicationCommandTarget::InvocationInfo
        */
        wantsKeyUpDownCallbacks     = 1 << 2,

        /** If this flag is present, then a KeyMappingEditorComponent will not display the
            command in its list.
        */
        hiddenFromKeyEditor         = 1 << 3,

        /** If this flag is present, then a KeyMappingEditorComponent will display the
            command in its list, but won't allow the assigned keypress to be changed.
        */
        readOnlyInKeyEditor         = 1 << 4,

        /** If this flag is present and the command is invoked from a keypress, then any
            buttons or menus that are also connected to the command will not flash to
            indicate that they've been triggered.
        */
        dontTriggerVisualFeedback   = 1 << 5
    };

    /** A bitwise-OR of the values specified in the CommandFlags enum.

        You can use the setInfo() method to quickly set this and some of the command's
        other properties.
    */
    int flags;
};

#endif   // __JUCE_APPLICATIONCOMMANDINFO_JUCEHEADER__
/********* End of inlined file: juce_ApplicationCommandInfo.h *********/

/**
    A command target publishes a list of command IDs that it can perform.

    An ApplicationCommandManager despatches commands to targets, which must be
    able to provide information about what commands they can handle.

    To create a target, you'll need to inherit from this class, implementing all of
    its pure virtual methods.

    For info about how a target is chosen to receive a command, see
    ApplicationCommandManager::getFirstCommandTarget().

    @see ApplicationCommandManager, ApplicationCommandInfo
*/
class JUCE_API  ApplicationCommandTarget
{
public:

    /** Creates a command target. */
    ApplicationCommandTarget();

    /** Destructor. */
    virtual ~ApplicationCommandTarget();

    /**
    */
    struct JUCE_API  InvocationInfo
    {

        InvocationInfo (const CommandID commandID) throw();

        /** The UID of the command that should be performed. */
        CommandID commandID;

        /** The command's flags.

            See ApplicationCommandInfo for a description of these flag values.
        */
        int commandFlags;

        /** The types of context in which the command might be called. */
        enum InvocationMethod
        {
            direct = 0,     /**< The command is being invoked directly by a piece of code. */
            fromKeyPress,   /**< The command is being invoked by a key-press. */
            fromMenu,       /**< The command is being invoked by a menu selection. */
            fromButton      /**< The command is being invoked by a button click. */
        };

        /** The type of event that triggered this command. */
        InvocationMethod invocationMethod;

        /** If triggered by a keypress or menu, this will be the component that had the
            keyboard focus at the time.

            If triggered by a button, it may be set to that component, or it may be null.
        */
        Component* originatingComponent;

        /** The keypress that was used to invoke it.

            Note that this will be an invalid keypress if the command was invoked
            by some other means than a keyboard shortcut.
        */
        KeyPress keyPress;

        /** True if the callback is being invoked when the key is pressed,
            false if the key is being released.

            @see KeyPressMappingSet::addCommand()
        */
        bool isKeyDown;

        /** If the key is being released, this indicates how long it had been held
            down for.

            (Only relevant if isKeyDown is false.)
        */
        int millisecsSinceKeyPressed;
    };

    /** This must return the next target to try after this one.

        When a command is being sent, and the first target can't handle
        that command, this method is used to determine the next target that should
        be tried.

        It may return 0 if it doesn't know of another target.

        If your target is a Component, you would usually use the findFirstTargetParentComponent()
        method to return a parent component that might want to handle it.

        @see invoke
    */
    virtual ApplicationCommandTarget* getNextCommandTarget() = 0;

    /** This must return a complete list of commands that this target can handle.

        Your target should add all the command IDs that it handles to the array that is
        passed-in.
    */
    virtual void getAllCommands (Array <CommandID>& commands) = 0;

    /** This must provide details about one of the commands that this target can perform.

        This will be called with one of the command IDs that the target provided in its
        getAllCommands() methods.

        It should fill-in all appropriate fields of the ApplicationCommandInfo structure with
        suitable information about the command. (The commandID field will already have been filled-in
        by the caller).

        The easiest way to set the info is using the ApplicationCommandInfo::setInfo() method to
        set all the fields at once.

        If the command is currently inactive for some reason, this method must use
        ApplicationCommandInfo::setActive() to make that clear, (or it should set the isDisabled
        bit of the ApplicationCommandInfo::flags field).

        Any default key-presses for the command should be appended to the
        ApplicationCommandInfo::defaultKeypresses field.

        Note that if you change something that affects the status of the commands
        that would be returned by this method (e.g. something that makes some commands
        active or inactive), you should call ApplicationCommandManager::commandStatusChanged()
        to cause the manager to refresh its status.
    */
    virtual void getCommandInfo (const CommandID commandID,
                                 ApplicationCommandInfo& result) = 0;

    /** This must actually perform the specified command.

        If this target is able to perform the command specified by the commandID field of the
        InvocationInfo structure, then it should do so, and must return true.

        If it can't handle this command, it should return false, which tells the caller to pass
        the command on to the next target in line.

        @see invoke, ApplicationCommandManager::invoke
    */
    virtual bool perform (const InvocationInfo& info) = 0;

    /** Makes this target invoke a command.

        Your code can call this method to invoke a command on this target, but normally
        you'd call it indirectly via ApplicationCommandManager::invoke() or
        ApplicationCommandManager::invokeDirectly().

        If this target can perform the given command, it will call its perform() method to
        do so. If not, then getNextCommandTarget() will be used to determine the next target
        to try, and the command will be passed along to it.

        @param invocationInfo       this must be correctly filled-in, describing the context for
                                    the invocation.
        @param asynchronously       if false, the command will be performed before this method returns.
                                    If true, a message will be posted so that the command will be performed
                                    later on the message thread, and this method will return immediately.
        @see perform, ApplicationCommandManager::invoke
    */
    bool invoke (const InvocationInfo& invocationInfo,
                 const bool asynchronously);

    /** Invokes a given command directly on this target.

        This is just an easy way to call invoke() without having to fill out the InvocationInfo
        structure.
    */
    bool invokeDirectly (const CommandID commandID,
                         const bool asynchronously);

    /** Searches this target and all subsequent ones for the first one that can handle
        the specified command.

        This will use getNextCommandTarget() to determine the chain of targets to try
        after this one.
    */
    ApplicationCommandTarget* getTargetForCommand (const CommandID commandID);

    /** Checks whether this command can currently be performed by this target.

        This will return true only if a call to getCommandInfo() doesn't set the
        isDisabled flag to indicate that the command is inactive.
    */
    bool isCommandActive (const CommandID commandID);

    /** If this object is a Component, this method will seach upwards in its current
        UI hierarchy for the next parent component that implements the
        ApplicationCommandTarget class.

        If your target is a Component, this is a very handy method to use in your
        getNextCommandTarget() implementation.
    */
    ApplicationCommandTarget* findFirstTargetParentComponent();

    juce_UseDebuggingNewOperator

private:
    // (for async invocation of commands)
    class CommandTargetMessageInvoker  : public MessageListener
    {
    public:
        CommandTargetMessageInvoker (ApplicationCommandTarget* const owner);
        ~CommandTargetMessageInvoker();

        void handleMessage (const Message& message);

    private:
        ApplicationCommandTarget* const owner;

        CommandTargetMessageInvoker (const CommandTargetMessageInvoker&);
        const CommandTargetMessageInvoker& operator= (const CommandTargetMessageInvoker&);
    };

    CommandTargetMessageInvoker* messageInvoker;

    friend class CommandTargetMessageInvoker;
    bool tryToInvoke (const InvocationInfo& info, const bool async);
};

#endif   // __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__
/********* End of inlined file: juce_ApplicationCommandTarget.h *********/

/********* Start of inlined file: juce_ActionListener.h *********/
#ifndef __JUCE_ACTIONLISTENER_JUCEHEADER__
#define __JUCE_ACTIONLISTENER_JUCEHEADER__

/**
    Receives callbacks to indicate that some kind of event has occurred.

    Used by various classes, e.g. buttons when they are pressed, to tell listeners
    about something that's happened.

    @see ActionListenerList, ActionBroadcaster, ChangeListener
*/
class JUCE_API  ActionListener
{
public:
    /** Destructor. */
    virtual ~ActionListener()  {}

    /** Overridden by your subclass to receive the callback.

        @param message  the string that was specified when the event was triggered
                        by a call to ActionListenerList::sendActionMessage()
    */
    virtual void actionListenerCallback (const String& message) = 0;
};

#endif   // __JUCE_ACTIONLISTENER_JUCEHEADER__
/********* End of inlined file: juce_ActionListener.h *********/

/**
    An instance of this class is used to specify initialisation and shutdown
    code for the application.

    An application that wants to run in the JUCE framework needs to declare a
    subclass of JUCEApplication and implement its various pure virtual methods.

    It then needs to use the START_JUCE_APPLICATION macro somewhere in a cpp file
    to declare an instance of this class and generate a suitable platform-specific
    main() function.

    e.g. @code
        class MyJUCEApp  : public JUCEApplication
        {
            // NEVER put objects inside a JUCEApplication class - only use pointers to
            // objects, which you must create in the initialise() method.
            MyApplicationWindow* myMainWindow;

        public:
            MyJUCEApp()
                : myMainWindow (0)
            {
                // never create any Juce objects in the constructor - do all your initialisation
                // in the initialise() method.
            }

            ~MyJUCEApp()
            {
                // all your shutdown code must have already been done in the shutdown() method -
                // nothing should happen in this destructor.
            }

            void initialise (const String& commandLine)
            {
                myMainWindow = new MyApplicationWindow();
                myMainWindow->setBounds (100, 100, 400, 500);
                myMainWindow->setVisible (true);
            }

            void shutdown()
            {
                delete myMainWindow;
            }

            const String getApplicationName()
            {
                return T("Super JUCE-o-matic");
            }

            const String getApplicationVersion()
            {
                return T("1.0");
            }
        };

        // this creates wrapper code to actually launch the app properly.
        START_JUCE_APPLICATION (MyJUCEApp)
    @endcode

    Because this object will be created before Juce has properly initialised, you must
    NEVER add any member variable objects that will be automatically constructed. Likewise
    don't put ANY code in the constructor that could call Juce functions. Any objects that
    you want to add to the class must be pointers, which you should instantiate during the
    initialise() method, and delete in the shutdown() method.

    @see MessageManager, DeletedAtShutdown
*/
class JUCE_API  JUCEApplication  : public ApplicationCommandTarget,
                                   private ActionListener
{
protected:

    /** Constructs a JUCE app object.

        If subclasses implement a constructor or destructor, they shouldn't call any
        JUCE code in there - put your startup/shutdown code in initialise() and
        shutdown() instead.
    */
    JUCEApplication();

public:
    /** Destructor.

        If subclasses implement a constructor or destructor, they shouldn't call any
        JUCE code in there - put your startup/shutdown code in initialise() and
        shutdown() instead.
    */
    virtual ~JUCEApplication();

    /** Returns the global instance of the application object being run. */
    static JUCEApplication* getInstance() throw();

    /** Called when the application starts.

        This will be called once to let the application do whatever initialisation
        it needs, create its windows, etc.

        After the method returns, the normal event-dispatch loop will be run,
        until the quit() method is called, at which point the shutdown()
        method will be called to let the application clear up anything it needs
        to delete.

        If during the initialise() method, the application decides not to start-up
        after all, it can just call the quit() method and the event loop won't be run.

        @param commandLineParameters    the line passed in does not include the
                                        name of the executable, just the parameter list.
        @see shutdown, quit
    */
    virtual void initialise (const String& commandLineParameters) = 0;

    /** Returns true if the application hasn't yet completed its initialise() method
        and entered the main event loop.

        This is handy for things like splash screens to know when the app's up-and-running
        properly.
    */
    bool isInitialising() const throw();

    /* Called to allow the application to clear up before exiting.

       After JUCEApplication::quit() has been called, the event-dispatch loop will
       terminate, and this method will get called to allow the app to sort itself
       out.

       Be careful that nothing happens in this method that might rely on messages
       being sent, or any kind of window activity, because the message loop is no
       longer running at this point.

        @see DeletedAtShutdown
    */
    virtual void shutdown() = 0;

    /** Returns the application's name.

        An application must implement this to name itself.
    */
    virtual const String getApplicationName() = 0;

    /** Returns the application's version number.

        An application can implement this to give itself a version.
        (The default implementation of this just returns an empty string).
    */
    virtual const String getApplicationVersion();

    /** Checks whether multiple instances of the app are allowed.

        If you application class returns true for this, more than one instance is
        permitted to run (except on the Mac where this isn't possible).

        If it's false, the second instance won't start, but it you will still get a
        callback to anotherInstanceStarted() to tell you about this - which
        gives you a chance to react to what the user was trying to do.
    */
    virtual bool moreThanOneInstanceAllowed();

    /** Indicates that the user has tried to start up another instance of the app.

        This will get called even if moreThanOneInstanceAllowed() is false.
    */
    virtual void anotherInstanceStarted (const String& commandLine);

    /** Called when the operating system is trying to close the application.

        The default implementation of this method is to call quit(), but it may
        be overloaded to ignore the request or do some other special behaviour
        instead. For example, you might want to offer the user the chance to save
        their changes before quitting, and give them the chance to cancel.

        If you want to send a quit signal to your app, this is the correct method
        to call, because it means that requests that come from the system get handled
        in the same way as those from your own application code. So e.g. you'd
        call this method from a "quit" item on a menu bar.
    */
    virtual void systemRequestedQuit();

    /** If any unhandled exceptions make it through to the message dispatch loop, this
        callback will be triggered, in case you want to log them or do some other
        type of error-handling.

        If the type of exception is derived from the std::exception class, the pointer
        passed-in will be valid. If the exception is of unknown type, this pointer
        will be null.
    */
    virtual void unhandledException (const std::exception* e,
                                     const String& sourceFilename,
                                     const int lineNumber);

    /** Signals that the main message loop should stop and the application should terminate.

        This isn't synchronous, it just posts a quit message to the main queue, and
        when this message arrives, the message loop will stop, the shutdown() method
        will be called, and the app will exit.

        Note that this will cause an unconditional quit to happen, so if you need an
        extra level before this, e.g. to give the user the chance to save their work
        and maybe cancel the quit, you'll need to handle this in the systemRequestedQuit()
        method - see that method's help for more info.

        @see MessageManager, DeletedAtShutdown
    */
    static void quit();

    /** Sets the value that should be returned as the application's exit code when the
        app quits.

        This is the value that's returned by the main() function. Normally you'd leave this
        as 0 unless you want to indicate an error code.

        @see getApplicationReturnValue
    */
    void setApplicationReturnValue (const int newReturnValue) throw();

    /** Returns the value that has been set as the application's exit code.
        @see setApplicationReturnValue
    */
    int getApplicationReturnValue() const throw()                   { return appReturnValue; }

    /** Returns the application's command line params.
    */
    const String getCommandLineParameters() const throw()           { return commandLineParameters; }

    // These are used by the START_JUCE_APPLICATION() macro and aren't for public use.

    /** @internal */
    static int main (String& commandLine, JUCEApplication* const newApp);
    /** @internal */
    static int main (int argc, char* argv[], JUCEApplication* const newApp);

    /** @internal */
    static void sendUnhandledException (const std::exception* const e,
                                        const char* const sourceFile,
                                        const int lineNumber);

    /** @internal */
    ApplicationCommandTarget* getNextCommandTarget();
    /** @internal */
    void getCommandInfo (const CommandID commandID, ApplicationCommandInfo& result);
    /** @internal */
    void getAllCommands (Array <CommandID>& commands);
    /** @internal */
    bool perform (const InvocationInfo& info);
    /** @internal */
    void actionListenerCallback (const String& message);

private:

    String commandLineParameters;
    int appReturnValue;
    bool stillInitialising;

    static int shutdownAppAndClearUp();
};

#endif   // __JUCE_APPLICATION_JUCEHEADER__
/********* End of inlined file: juce_Application.h *********/

#endif
#ifndef __JUCE_APPLICATIONCOMMANDID_JUCEHEADER__

#endif
#ifndef __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__

/********* Start of inlined file: juce_DeletedAtShutdown.h *********/
#ifndef __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__
#define __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__

/**
    Classes derived from this will be automatically deleted when the application exits.

    After JUCEApplication::shutdown() has been called, any objects derived from
    DeletedAtShutdown which are still in existence will be deleted in the reverse
    order to that in which they were created.

    So if you've got a singleton and don't want to have to explicitly delete it, just
    inherit from this and it'll be taken care of.
*/
class JUCE_API  DeletedAtShutdown
{
protected:
    /** Creates a DeletedAtShutdown object. */
    DeletedAtShutdown() throw();

    /** Destructor.

        It's ok to delete these objects explicitly - it's only the ones left
        dangling at the end that will be deleted automatically.
    */
    virtual ~DeletedAtShutdown();

public:
    /** Deletes all extant objects.

        This shouldn't be used by applications, as it's called automatically
        in the shutdown code of the JUCEApplication class.
    */
    static void deleteAll();

private:
    DeletedAtShutdown (const DeletedAtShutdown&);
    const DeletedAtShutdown& operator= (const DeletedAtShutdown&);
};

#endif   // __JUCE_DELETEDATSHUTDOWN_JUCEHEADER__
/********* End of inlined file: juce_DeletedAtShutdown.h *********/

#endif
#ifndef __JUCE_APPLICATIONCOMMANDINFO_JUCEHEADER__

#endif
#ifndef __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__

/********* Start of inlined file: juce_ApplicationCommandManager.h *********/
#ifndef __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__
#define __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__

/********* Start of inlined file: juce_AsyncUpdater.h *********/
#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__
#define __JUCE_ASYNCUPDATER_JUCEHEADER__

/**
    Has a callback method that is triggered asynchronously.

    This object allows an asynchronous callback function to be triggered, for
    tasks such as coalescing multiple updates into a single callback later on.

    Basically, one or more calls to the triggerAsyncUpdate() will result in the
    message thread calling handleAsyncUpdate() as soon as it can.
*/
class JUCE_API  AsyncUpdater
{
public:

    /** Creates an AsyncUpdater object. */
    AsyncUpdater() throw();

    /** Destructor.

        If there are any pending callbacks when the object is deleted, these are lost.
    */
    virtual ~AsyncUpdater();

    /** Causes the callback to be triggered at a later time.

        This method returns immediately, having made sure that a callback
        to the handleAsyncUpdate() method will occur as soon as possible.

        If an update callback is already pending but hasn't happened yet, calls
        to this method will be ignored.

        It's thread-safe to call this method from any number of threads without
        needing to worry about locking.
    */
    void triggerAsyncUpdate() throw();

    /** This will stop any pending updates from happening.

        If called after triggerAsyncUpdate() and before the handleAsyncUpdate()
        callback happens, this will cancel the handleAsyncUpdate() callback.
    */
    void cancelPendingUpdate() throw();

    /** If an update has been triggered and is pending, this will invoke it
        synchronously.

        Use this as a kind of "flush" operation - if an update is pending, the
        handleAsyncUpdate() method will be called immediately; if no update is
        pending, then nothing will be done.
    */
    void handleUpdateNowIfNeeded();

    /** Called back to do whatever your class needs to do.

        This method is called by the message thread at the next convenient time
        after the triggerAsyncUpdate() method has been called.
    */
    virtual void handleAsyncUpdate() = 0;

private:

    class AsyncUpdaterInternal  : public MessageListener
    {
    public:
        AsyncUpdaterInternal() throw() {}
        ~AsyncUpdaterInternal() {}

        void handleMessage (const Message&);

        AsyncUpdater* owner;

    private:
        AsyncUpdaterInternal (const AsyncUpdaterInternal&);
        const AsyncUpdaterInternal& operator= (const AsyncUpdaterInternal&);
    };

    AsyncUpdaterInternal internalAsyncHandler;
    bool asyncMessagePending;
};

#endif   // __JUCE_ASYNCUPDATER_JUCEHEADER__
/********* End of inlined file: juce_AsyncUpdater.h *********/

/********* Start of inlined file: juce_Desktop.h *********/
#ifndef __JUCE_DESKTOP_JUCEHEADER__
#define __JUCE_DESKTOP_JUCEHEADER__

/********* Start of inlined file: juce_Timer.h *********/
#ifndef __JUCE_TIMER_JUCEHEADER__
#define __JUCE_TIMER_JUCEHEADER__

class InternalTimerThread;

/**
    Repeatedly calls a user-defined method at a specified time interval.

    A Timer's timerCallback() method will be repeatedly called at a given
    interval. Initially when a Timer object is created, they will do nothing
    until the startTimer() method is called, then the message thread will
    start calling it back until stopTimer() is called.

    The time interval isn't guaranteed to be precise to any more than maybe
    10-20ms, and the intervals may end up being much longer than requested if the
    system is busy. Because it's the message thread that is doing the callbacks,
    any messages that take a significant amount of time to process will block
    all the timers for that period.

    If you need to have a single callback that is shared by multiple timers with
    different frequencies, then the MultiTimer class allows you to do that - its
    structure is very similar to the Timer class, but contains multiple timers
    internally, each one identified by an ID number.

    @see MultiTimer
*/
class JUCE_API  Timer
{
protected:

    /** Creates a Timer.

        When created, the timer is stopped, so use startTimer() to get it going.
    */
    Timer() throw();

    /** Creates a copy of another timer.

        Note that this timer won't be started, even if the one you're copying
        is running.
    */
    Timer (const Timer& other) throw();

public:

    /** Destructor. */
    virtual ~Timer();

    /** The user-defined callback routine that actually gets called periodically.

        It's perfectly ok to call startTimer() or stopTimer() from within this
        callback to change the subsequent intervals.
    */
    virtual void timerCallback() = 0;

    /** Starts the timer and sets the length of interval required.

        If the timer is already started, this will reset it, so the
        time between calling this method and the next timer callback
        will not be less than the interval length passed in.

        @param  intervalInMilliseconds  the interval to use (any values less than 1 will be
                                        rounded up to 1)
    */
    void startTimer (const int intervalInMilliseconds) throw();

    /** Stops the timer.

        No more callbacks will be made after this method returns.

        If this is called from a different thread, any callbacks that may
        be currently executing may be allowed to finish before the method
        returns.
    */
    void stopTimer() throw();

    /** Checks if the timer has been started.

        @returns true if the timer is running.
    */
    bool isTimerRunning() const throw()                     { return periodMs > 0; }

    /** Returns the timer's interval.

        @returns the timer's interval in milliseconds if it's running, or 0 if it's not.
    */
    int getTimerInterval() const throw()                    { return periodMs; }

private:
    friend class InternalTimerThread;
    int countdownMs, periodMs;
    Timer* previous;
    Timer* next;

    const Timer& operator= (const Timer&);
};

#endif   // __JUCE_TIMER_JUCEHEADER__
/********* End of inlined file: juce_Timer.h *********/

/**
    Classes can implement this interface and register themselves with the Desktop class
    to receive callbacks when the currently focused component changes.

    @see Desktop::addFocusChangeListener, Desktop::removeFocusChangeListener
*/
class JUCE_API  FocusChangeListener
{
public:
    /** Destructor. */
    virtual ~FocusChangeListener()  {}

    /** Callback to indicate that the currently focused component has changed. */
    virtual void globalFocusChanged (Component* focusedComponent) = 0;
};

/**
    Describes and controls aspects of the computer's desktop.

*/
class JUCE_API  Desktop  : private DeletedAtShutdown,
                           private Timer,
                           private AsyncUpdater
{
public:

    /** There's only one dektop object, and this method will return it.
    */
    static Desktop& JUCE_CALLTYPE getInstance() throw();

    /** Returns a list of the positions of all the monitors available.

        The first rectangle in the list will be the main monitor area.

        If clippedToWorkArea is true, it will exclude any areas like the taskbar on Windows,
        or the menu bar on Mac. If clippedToWorkArea is false, the entire monitor area is returned.
    */
    const RectangleList getAllMonitorDisplayAreas (const bool clippedToWorkArea = true) const throw();

    /** Returns the position and size of the main monitor.

        If clippedToWorkArea is true, it will exclude any areas like the taskbar on Windows,
        or the menu bar on Mac. If clippedToWorkArea is false, the entire monitor area is returned.
    */
    const Rectangle getMainMonitorArea (const bool clippedToWorkArea = true) const throw();

    /** Returns the position and size of the monitor which contains this co-ordinate.

        If none of the monitors contains the point, this will just return the
        main monitor.

        If clippedToWorkArea is true, it will exclude any areas like the taskbar on Windows,
        or the menu bar on Mac. If clippedToWorkArea is false, the entire monitor area is returned.
    */
    const Rectangle getMonitorAreaContaining (int x, int y, const bool clippedToWorkArea = true) const throw();

    /** Returns the mouse position.

        The co-ordinates are relative to the top-left of the main monitor.
    */
    static void getMousePosition (int& x, int& y) throw();

    /** Makes the mouse pointer jump to a given location.

        The co-ordinates are relative to the top-left of the main monitor.
    */
    static void setMousePosition (int x, int y) throw();

    /** Returns the last position at which a mouse button was pressed.
    */
    static void getLastMouseDownPosition (int& x, int& y) throw();

    /** Returns the number of times the mouse button has been clicked since the
        app started.

        Each mouse-down event increments this number by 1.
    */
    static int getMouseButtonClickCounter() throw();

    /** This lets you prevent the screensaver from becoming active.

        Handy if you're running some sort of presentation app where having a screensaver
        appear would be annoying.

        Pass false to disable the screensaver, and true to re-enable it. (Note that this
        won't enable a screensaver unless the user has actually set one up).

        The disablement will only happen while the Juce application is the foreground
        process - if another task is running in front of it, then the screensaver will
        be unaffected.

        @see isScreenSaverEnabled
    */
    static void setScreenSaverEnabled (const bool isEnabled) throw();

    /** Returns true if the screensaver has not been turned off.

        This will return the last value passed into setScreenSaverEnabled(). Note that
        it won't tell you whether the user is actually using a screen saver, just
        whether this app is deliberately preventing one from running.

        @see setScreenSaverEnabled
    */
    static bool isScreenSaverEnabled() throw();

    /** Registers a MouseListener that will receive all mouse events that occur on
        any component.

        @see removeGlobalMouseListener
    */
    void addGlobalMouseListener (MouseListener* const listener) throw();

    /** Unregisters a MouseListener that was added with the addGlobalMouseListener()
        method.

        @see addGlobalMouseListener
    */
    void removeGlobalMouseListener (MouseListener* const listener) throw();

    /** Registers a MouseListener that will receive a callback whenever the focused
        component changes.
    */
    void addFocusChangeListener (FocusChangeListener* const listener) throw();

    /** Unregisters a listener that was added with addFocusChangeListener(). */
    void removeFocusChangeListener (FocusChangeListener* const listener) throw();

    /** Takes a component and makes it full-screen, removing the taskbar, dock, etc.

        The component must already be on the desktop for this method to work. It will
        be resized to completely fill the screen and any extraneous taskbars, menu bars,
        etc will be hidden.

        To exit kiosk mode, just call setKioskModeComponent (0). When this is called,
        the component that's currently being used will be resized back to the size
        and position it was in before being put into this mode.

        If allowMenusAndBars is true, things like the menu and dock (on mac) are still
        allowed to pop up when the mouse moves onto them. If this is false, it'll try
        to hide as much on-screen paraphenalia as possible.
    */
    void setKioskModeComponent (Component* componentToUse,
                                const bool allowMenusAndBars = true);

    /** Returns the component that is currently being used in kiosk-mode.

        This is the component that was last set by setKioskModeComponent(). If none
        has been set, this returns 0.
    */
    Component* getKioskModeComponent() const             { return kioskModeComponent; }

    /** Returns the number of components that are currently active as top-level
        desktop windows.

        @see getComponent, Component::addToDesktop
    */
    int getNumComponents() const throw();

    /** Returns one of the top-level desktop window components.

        The index is from 0 to getNumComponents() - 1. This could return 0 if the
        index is out-of-range.

        @see getNumComponents, Component::addToDesktop
    */
    Component* getComponent (const int index) const throw();

    /** Finds the component at a given screen location.

        This will drill down into top-level windows to find the child component at
        the given position.

        Returns 0 if the co-ordinates are inside a non-Juce window.
    */
    Component* findComponentAt (const int screenX,
                                const int screenY) const;

    juce_UseDebuggingNewOperator

    /** Tells this object to refresh its idea of what the screen resolution is.

        (Called internally by the native code).
    */
    void refreshMonitorSizes() throw();

    /** True if the OS supports semitransparent windows */
    static bool canUseSemiTransparentWindows() throw();

private:

    friend class Component;
    friend class ComponentPeer;
    SortedSet <void*> mouseListeners, focusListeners;
    VoidArray desktopComponents;

    friend class DeletedAtShutdown;
    friend class TopLevelWindowManager;
    Desktop() throw();
    ~Desktop() throw();

    Array <Rectangle> monitorCoordsClipped, monitorCoordsUnclipped;
    int lastMouseX, lastMouseY;

    Component* kioskModeComponent;
    Rectangle kioskComponentOriginalBounds;

    void timerCallback();
    void sendMouseMove();
    void resetTimer() throw();

    int getNumDisplayMonitors() const throw();
    const Rectangle getDisplayMonitorCoordinates (const int index, const bool clippedToWorkArea) const throw();

    void addDesktopComponent (Component* const c) throw();
    void removeDesktopComponent (Component* const c) throw();
    void componentBroughtToFront (Component* const c) throw();

    void triggerFocusCallback() throw();
    void handleAsyncUpdate();

    Desktop (const Desktop&);
    const Desktop& operator= (const Desktop&);
};

#endif   // __JUCE_DESKTOP_JUCEHEADER__
/********* End of inlined file: juce_Desktop.h *********/

class KeyPressMappingSet;
class ApplicationCommandManagerListener;

/**
    One of these objects holds a list of all the commands your app can perform,
    and despatches these commands when needed.

    Application commands are a good way to trigger actions in your app, e.g. "Quit",
    "Copy", "Paste", etc. Menus, buttons and keypresses can all be given commands
    to invoke automatically, which means you don't have to handle the result of a menu
    or button click manually. Commands are despatched to ApplicationCommandTarget objects
    which can choose which events they want to handle.

    This architecture also allows for nested ApplicationCommandTargets, so that for example
    you could have two different objects, one inside the other, both of which can respond to
    a "delete" command. Depending on which one has focus, the command will be sent to the
    appropriate place, regardless of whether it was triggered by a menu, keypress or some other
    method.

    To set up your app to use commands, you'll need to do the following:

    - Create a global ApplicationCommandManager to hold the list of all possible
      commands. (This will also manage a set of key-mappings for them).

    - Make some of your UI components (or other objects) inherit from ApplicationCommandTarget.
      This allows the object to provide a list of commands that it can perform, and
      to handle them.

    - Register each type of command using ApplicationCommandManager::registerAllCommandsForTarget(),
      or ApplicationCommandManager::registerCommand().

    - If you want key-presses to trigger your commands, use the ApplicationCommandManager::getKeyMappings()
      method to access the key-mapper object, which you will need to register as a key-listener
      in whatever top-level component you're using. See the KeyPressMappingSet class for more help
      about setting this up.

    - Use methods such as PopupMenu::addCommandItem() or Button::setCommandToTrigger() to
      cause these commands to be invoked automatically.

    - Commands can be invoked directly by your code using ApplicationCommandManager::invokeDirectly().

    When a command is invoked, the ApplicationCommandManager will try to choose the best
    ApplicationCommandTarget to receive the specified command. To do this it will use the
    current keyboard focus to see which component might be interested, and will search the
    component hierarchy for those that also implement the ApplicationCommandTarget interface.
    If an ApplicationCommandTarget isn't interested in the command that is being invoked, then
    the next one in line will be tried (see the ApplicationCommandTarget::getNextCommandTarget()
    method), and so on until ApplicationCommandTarget::getNextCommandTarget() returns 0. At this
    point if the command still hasn't been performed, it will be passed to the current
    JUCEApplication object (which is itself an ApplicationCommandTarget).

    To exert some custom control over which ApplicationCommandTarget is chosen to invoke a command,
    you can override the ApplicationCommandManager::getFirstCommandTarget() method and choose
    the object yourself.

    @see ApplicationCommandTarget, ApplicationCommandInfo
*/
class JUCE_API  ApplicationCommandManager   : private AsyncUpdater,
                                              private FocusChangeListener
{
public:

    /** Creates an ApplicationCommandManager.

        Once created, you'll need to register all your app's commands with it, using
        ApplicationCommandManager::registerAllCommandsForTarget() or
        ApplicationCommandManager::registerCommand().
    */
    ApplicationCommandManager();

    /** Destructor.

        Make sure that you don't delete this if pointers to it are still being used by
        objects such as PopupMenus or Buttons.
    */
    virtual ~ApplicationCommandManager();

    /** Clears the current list of all commands.

        Note that this will also clear the contents of the KeyPressMappingSet.
    */
    void clearCommands();

    /** Adds a command to the list of registered commands.

        @see registerAllCommandsForTarget
    */
    void registerCommand (const ApplicationCommandInfo& newCommand);

    /** Adds all the commands that this target publishes to the manager's list.

        This will use ApplicationCommandTarget::getAllCommands() and ApplicationCommandTarget::getCommandInfo()
        to get details about all the commands that this target can do, and will call
        registerCommand() to add each one to the manger's list.

        @see registerCommand
    */
    void registerAllCommandsForTarget (ApplicationCommandTarget* target);

    /** Removes the command with a specified ID.

        Note that this will also remove any key mappings that are mapped to the command.
    */
    void removeCommand (const CommandID commandID);

    /** This should be called to tell the manager that one of its registered commands may have changed
        its active status.

        Because the command manager only finds out whether a command is active or inactive by querying
        the current ApplicationCommandTarget, this is used to tell it that things may have changed. It
        allows things like buttons to update their enablement, etc.

        This method will cause an asynchronous call to ApplicationCommandManagerListener::applicationCommandListChanged()
        for any registered listeners.
    */
    void commandStatusChanged();

    /** Returns the number of commands that have been registered.

        @see registerCommand
    */
    int getNumCommands() const throw()                                                  { return commands.size(); }

    /** Returns the details about one of the registered commands.

        The index is between 0 and (getNumCommands() - 1).
    */
    const ApplicationCommandInfo* getCommandForIndex (const int index) const throw()    { return commands [index]; }

    /** Returns the details about a given command ID.

        This will search the list of registered commands for one with the given command
        ID number, and return its associated info. If no matching command is found, this
        will return 0.
    */
    const ApplicationCommandInfo* getCommandForID (const CommandID commandID) const throw();

    /** Returns the name field for a command.

        An empty string is returned if no command with this ID has been registered.
        @see getDescriptionOfCommand
    */
    const String getNameOfCommand (const CommandID commandID) const throw();

    /** Returns the description field for a command.

        An empty string is returned if no command with this ID has been registered. If the
        command has no description, this will return its short name field instead.

        @see getNameOfCommand
    */
    const String getDescriptionOfCommand (const CommandID commandID) const throw();

    /** Returns the list of categories.

        This will go through all registered commands, and return a list of all the distict
        categoryName values from their ApplicationCommandInfo structure.

        @see getCommandsInCategory()
    */
    const StringArray getCommandCategories() const throw();

    /** Returns a list of all the command UIDs in a particular category.

        @see getCommandCategories()
    */
    const Array <CommandID> getCommandsInCategory (const String& categoryName) const throw();

    /** Returns the manager's internal set of key mappings.

        This object can be used to edit the keypresses. To actually link this object up
        to invoke commands when a key is pressed, see the comments for the KeyPressMappingSet
        class.

        @see KeyPressMappingSet
    */
    KeyPressMappingSet* getKeyMappings() const throw()                          { return keyMappings; }

    /** Invokes the given command directly, sending it to the default target.

        This is just an easy way to call invoke() without having to fill out the InvocationInfo
        structure.
    */
    bool invokeDirectly (const CommandID commandID,
                         const bool asynchronously);

    /** Sends a command to the default target.

        This will choose a target using getFirstCommandTarget(), and send the specified command
        to it using the ApplicationCommandTarget::invoke() method. This means that if the
        first target can't handle the command, it will be passed on to targets further down the
        chain (see ApplicationCommandTarget::invoke() for more info).

        @param invocationInfo       this must be correctly filled-in, describing the context for
                                    the invocation.
        @param asynchronously       if false, the command will be performed before this method returns.
                                    If true, a message will be posted so that the command will be performed
                                    later on the message thread, and this method will return immediately.

        @see ApplicationCommandTarget::invoke
    */
    bool invoke (const ApplicationCommandTarget::InvocationInfo& invocationInfo,
                 const bool asynchronously);

    /** Chooses the ApplicationCommandTarget to which a command should be sent.

        Whenever the manager needs to know which target a command should be sent to, it calls
        this method to determine the first one to try.

        By default, this method will return the target that was set by calling setFirstCommandTarget().
        If no target is set, it will return the result of findDefaultComponentTarget().

        If you need to make sure all commands go via your own custom target, then you can
        either use setFirstCommandTarget() to specify a single target, or override this method
        if you need more complex logic to choose one.

        It may return 0 if no targets are available.

        @see getTargetForCommand, invoke, invokeDirectly
    */
    virtual ApplicationCommandTarget* getFirstCommandTarget (const CommandID commandID);

    /** Sets a target to be returned by getFirstCommandTarget().

        If this is set to 0, then getFirstCommandTarget() will by default return the
        result of findDefaultComponentTarget().

        If you use this to set a target, make sure you call setFirstCommandTarget (0) before
        deleting the target object.
    */
    void setFirstCommandTarget (ApplicationCommandTarget* const newTarget) throw();

    /** Tries to find the best target to use to perform a given command.

        This will call getFirstCommandTarget() to find the preferred target, and will
        check whether that target can handle the given command. If it can't, then it'll use
        ApplicationCommandTarget::getNextCommandTarget() to find the next one to try, and
        so on until no more are available.

        If no targets are found that can perform the command, this method will return 0.

        If a target is found, then it will get the target to fill-in the upToDateInfo
        structure with the latest info about that command, so that the caller can see
        whether the command is disabled, ticked, etc.
    */
    ApplicationCommandTarget* getTargetForCommand (const CommandID commandID,
                                                   ApplicationCommandInfo& upToDateInfo);

    /** Registers a listener that will be called when various events occur. */
    void addListener (ApplicationCommandManagerListener* const listener) throw();

    /** Deregisters a previously-added listener. */
    void removeListener (ApplicationCommandManagerListener* const listener) throw();

    /** Looks for a suitable command target based on which Components have the keyboard focus.

        This is used by the default implementation of ApplicationCommandTarget::getFirstCommandTarget(),
        but is exposed here in case it's useful.

        It tries to pick the best ApplicationCommandTarget by looking at focused components, top level
        windows, etc., and using the findTargetForComponent() method.
    */
    static ApplicationCommandTarget* findDefaultComponentTarget();

    /** Examines this component and all its parents in turn, looking for the first one
        which is a ApplicationCommandTarget.

        Returns the first ApplicationCommandTarget that it finds, or 0 if none of them implement
        that class.
    */
    static ApplicationCommandTarget* findTargetForComponent (Component* component);

    juce_UseDebuggingNewOperator

private:

    OwnedArray <ApplicationCommandInfo> commands;
    SortedSet <void*> listeners;
    KeyPressMappingSet* keyMappings;
    ApplicationCommandTarget* firstTarget;

    void sendListenerInvokeCallback (const ApplicationCommandTarget::InvocationInfo& info) const;
    void handleAsyncUpdate();
    void globalFocusChanged (Component*);

    // xxx this is just here to cause a compile error in old code that hasn't been changed to use the new
    // version of this method.
    virtual short getFirstCommandTarget() { return 0; }
};

/**
    A listener that receives callbacks from an ApplicationCommandManager when
    commands are invoked or the command list is changed.

    @see ApplicationCommandManager::addListener, ApplicationCommandManager::removeListener

*/
class JUCE_API  ApplicationCommandManagerListener
{
public:

    /** Destructor. */
    virtual ~ApplicationCommandManagerListener()  {}

    /** Called when an app command is about to be invoked. */
    virtual void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info) = 0;

    /** Called when commands are registered or deregistered from the
        command manager, or when commands are made active or inactive.

        Note that if you're using this to watch for changes to whether a command is disabled,
        you'll need to make sure that ApplicationCommandManager::commandStatusChanged() is called
        whenever the status of your command might have changed.
    */
    virtual void applicationCommandListChanged() = 0;
};

#endif   // __JUCE_APPLICATIONCOMMANDMANAGER_JUCEHEADER__
/********* End of inlined file: juce_ApplicationCommandManager.h *********/

#endif
#ifndef __JUCE_APPLICATIONCOMMANDTARGET_JUCEHEADER__

#endif
#ifndef __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__

/********* Start of inlined file: juce_ApplicationProperties.h *********/
#ifndef __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__
#define __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__

/********* Start of inlined file: juce_PropertiesFile.h *********/
#ifndef __JUCE_PROPERTIESFILE_JUCEHEADER__
#define __JUCE_PROPERTIESFILE_JUCEHEADER__

/********* Start of inlined file: juce_ChangeBroadcaster.h *********/
#ifndef __JUCE_CHANGEBROADCASTER_JUCEHEADER__
#define __JUCE_CHANGEBROADCASTER_JUCEHEADER__

/********* Start of inlined file: juce_ChangeListenerList.h *********/
#ifndef __JUCE_CHANGELISTENERLIST_JUCEHEADER__
#define __JUCE_CHANGELISTENERLIST_JUCEHEADER__

/********* Start of inlined file: juce_ChangeListener.h *********/
#ifndef __JUCE_CHANGELISTENER_JUCEHEADER__
#define __JUCE_CHANGELISTENER_JUCEHEADER__

/**
    Receives callbacks about changes to some kind of object.

    Many objects use a ChangeListenerList to keep a set of listeners which they
    will inform when something changes. A subclass of ChangeListener
    is used to receive these callbacks.

    Note that the major difference between an ActionListener and a ChangeListener
    is that for a ChangeListener, multiple changes will be coalesced into fewer
    callbacks, but ActionListeners perform one callback for every event posted.

    @see ChangeListenerList, ChangeBroadcaster, ActionListener
*/
class JUCE_API  ChangeListener
{
public:
    /** Destructor. */
    virtual ~ChangeListener()  {}

    /** Overridden by your subclass to receive the callback.

        @param objectThatHasChanged the value that was passed to the
                                    ChangeListenerList::sendChangeMessage() method
    */
    virtual void changeListenerCallback (void* objectThatHasChanged) = 0;
};

#endif   // __JUCE_CHANGELISTENER_JUCEHEADER__
/********* End of inlined file: juce_ChangeListener.h *********/

/**
    A set of ChangeListeners.

    Listeners can be added and removed from the list, and change messages can be
    broadcast to all the listeners.

    @see ChangeListener, ChangeBroadcaster
*/
class JUCE_API  ChangeListenerList  : public MessageListener
{
public:

    /** Creates an empty list. */
    ChangeListenerList() throw();

    /** Destructor. */
    ~ChangeListenerList() throw();

    /** Adds a listener to the list.

        (Trying to add a listener that's already on the list will have no effect).
    */
    void addChangeListener (ChangeListener* const listener) throw();

    /** Removes a listener from the list.

        If the listener isn't on the list, this won't have any effect.
    */
    void removeChangeListener (ChangeListener* const listener) throw();

    /** Removes all listeners from the list. */
    void removeAllChangeListeners() throw();

    /** Posts an asynchronous change message to all the listeners.

        If a message has already been sent and hasn't yet been delivered, this
        method won't send another - in this way it coalesces multiple frequent
        changes into fewer actual callbacks to the ChangeListeners. Contrast this
        with the ActionListener, which posts a new event for every call to its
        sendActionMessage() method.

        Only listeners which are on the list when the change event is delivered
        will receive the event - and this may include listeners that weren't on
        the list when the change message was sent.

        @param objectThatHasChanged     this pointer is passed to the
                                        ChangeListener::changeListenerCallback() method,
                                        and can be any value the application needs
        @see sendSynchronousChangeMessage
    */
    void sendChangeMessage (void* objectThatHasChanged) throw();

    /** This will synchronously callback all the ChangeListeners.

        Use this if you need to synchronously force a call to all the
        listeners' ChangeListener::changeListenerCallback() methods.
    */
    void sendSynchronousChangeMessage (void* objectThatHasChanged);

    /** If a change message has been sent but not yet dispatched, this will
        use sendSynchronousChangeMessage() to make the callback immediately.
    */
    void dispatchPendingMessages();

    /** @internal */
    void handleMessage (const Message&);

    juce_UseDebuggingNewOperator

private:
    SortedSet <void*> listeners;
    CriticalSection lock;
    void* lastChangedObject;
    bool messagePending;

    ChangeListenerList (const ChangeListenerList&);
    const ChangeListenerList& operator= (const ChangeListenerList&);
};

#endif   // __JUCE_CHANGELISTENERLIST_JUCEHEADER__
/********* End of inlined file: juce_ChangeListenerList.h *********/

/** Manages a list of ChangeListeners, and can send them messages.

    To quickly add methods to your class that can add/remove change
    listeners and broadcast to them, you can derive from this.

    @see ChangeListenerList, ChangeListener
*/
class JUCE_API  ChangeBroadcaster
{
public:

    /** Creates an ChangeBroadcaster. */
    ChangeBroadcaster() throw();

    /** Destructor. */
    virtual ~ChangeBroadcaster();

    /** Adds a listener to the list.

        (Trying to add a listener that's already on the list will have no effect).
    */
    void addChangeListener (ChangeListener* const listener) throw();

    /** Removes a listener from the list.

        If the listener isn't on the list, this won't have any effect.
    */
    void removeChangeListener (ChangeListener* const listener) throw();

    /** Removes all listeners from the list. */
    void removeAllChangeListeners() throw();

    /** Broadcasts a change message to all the registered listeners.

        The message will be delivered asynchronously by the event thread, so this
        method will not directly call any of the listeners. For a synchronous
        message, use sendSynchronousChangeMessage().

        @see ChangeListenerList::sendActionMessage
    */
    void sendChangeMessage (void* objectThatHasChanged) throw();

    /** Sends a synchronous change message to all the registered listeners.

        @see ChangeListenerList::sendSynchronousChangeMessage
    */
    void sendSynchronousChangeMessage (void* objectThatHasChanged);

    /** If a change message has been sent but not yet dispatched, this will
        use sendSynchronousChangeMessage() to make the callback immediately.
    */
    void dispatchPendingMessages();

private:

    ChangeListenerList changeListenerList;

    ChangeBroadcaster (const ChangeBroadcaster&);
    const ChangeBroadcaster& operator= (const ChangeBroadcaster&);
};

#endif   // __JUCE_CHANGEBROADCASTER_JUCEHEADER__
/********* End of inlined file: juce_ChangeBroadcaster.h *********/

/** Wrapper on a file that stores a list of key/value data pairs.

    Useful for storing application settings, etc. See the PropertySet class for
    the interfaces that read and write values.

    Not designed for very large amounts of data, as it keeps all the values in
    memory and writes them out to disk lazily when they are changed.

    Because this class derives from ChangeBroadcaster, ChangeListeners can be registered
    with it, and these will be signalled when a value changes.

    @see PropertySet
*/
class JUCE_API  PropertiesFile  : public PropertySet,
                                  public ChangeBroadcaster,
                                  private Timer
{
public:

    enum FileFormatOptions
    {
        ignoreCaseOfKeyNames            = 1,
        storeAsBinary                   = 2,
        storeAsCompressedBinary         = 4,
        storeAsXML                      = 8
    };

    /**
        Creates a PropertiesFile object.

        @param file                         the file to use
        @param millisecondsBeforeSaving     if this is zero or greater, then after a value
                                            is changed, the object will wait for this amount
                                            of time and then save the file. If zero, the file
                                            will be written to disk immediately on being changed
                                            (which might be slow, as it'll re-write synchronously
                                            each time a value-change method is called). If it is
                                            less than zero, the file won't be saved until
                                            save() or saveIfNeeded() are explicitly called.
        @param options                      a combination of the flags in the FileFormatOptions
                                            enum, which specify the type of file to save, and other
                                            options.
    */
    PropertiesFile (const File& file,
                    const int millisecondsBeforeSaving,
                    const int options) throw();

    /** Destructor.

        When deleted, the file will first call saveIfNeeded() to flush any changes to disk.
    */
    ~PropertiesFile();

    /** This will flush all the values to disk if they've changed since the last
        time they were saved.

        Returns false if it fails to write to the file for some reason (maybe because
        it's read-only or the directory doesn't exist or something).

        @see save
    */
    bool saveIfNeeded();

    /** This will force a write-to-disk of the current values, regardless of whether
        anything has changed since the last save.

        Returns false if it fails to write to the file for some reason (maybe because
        it's read-only or the directory doesn't exist or something).

        @see saveIfNeeded
    */
    bool save();

    /** Returns true if the properties have been altered since the last time they were
        saved.
    */
    bool needsToBeSaved() const throw();

    /** Returns the file that's being used. */
    const File getFile() const throw();

    /** Handy utility to create a properties file in whatever the standard OS-specific
        location is for these things.

        This uses getDefaultAppSettingsFile() to decide what file to create, then
        creates a PropertiesFile object with the specified properties. See
        getDefaultAppSettingsFile() and the class's constructor for descriptions of
        what the parameters do.

        @see getDefaultAppSettingsFile
    */
    static PropertiesFile* createDefaultAppPropertiesFile (const String& applicationName,
                                                           const String& fileNameSuffix,
                                                           const String& folderName,
                                                           const bool commonToAllUsers,
                                                           const int millisecondsBeforeSaving,
                                                           const int propertiesFileOptions);

    /** Handy utility to choose a file in the standard OS-dependent location for application
        settings files.

        So on a Mac, this will return a file called:
        ~/Library/Preferences/[folderName]/[applicationName].[fileNameSuffix]

        On Windows it'll return something like:
        C:\\Documents and Settings\\username\\Application Data\\[folderName]\\[applicationName].[fileNameSuffix]

        On Linux it'll return
        ~/.[folderName]/[applicationName].[fileNameSuffix]

        If you pass an empty string as the folder name, it'll use the app name for this (or
        omit the folder name on the Mac).

        If commonToAllUsers is true, then this will return the same file for all users of the
        computer, regardless of the current user. If it is false, the file will be specific to
        only the current user. Use this to choose whether you're saving settings that are common
        or user-specific.
    */
    static const File getDefaultAppSettingsFile (const String& applicationName,
                                                 const String& fileNameSuffix,
                                                 const String& folderName,
                                                 const bool commonToAllUsers);

    juce_UseDebuggingNewOperator

protected:
    virtual void propertyChanged();

private:

    File file;
    int timerInterval;
    const int options;
    bool needsWriting;

    void timerCallback();

    PropertiesFile (const PropertiesFile&);
    const PropertiesFile& operator= (const PropertiesFile&);
};

#endif   // __JUCE_PROPERTIESFILE_JUCEHEADER__
/********* End of inlined file: juce_PropertiesFile.h *********/

/**
    Manages a collection of properties.

    This is a slightly higher-level wrapper for PropertiesFile, which can be used
    as a singleton.

    It holds two different PropertiesFile objects internally, one for user-specific
    settings (stored in your user directory), and one for settings that are common to
    all users (stored in a folder accessible to all users).

    The class manages the creation of these files on-demand, allowing access via the
    getUserSettings() and getCommonSettings() methods. It also has a few handy
    methods like testWriteAccess() to check that the files can be saved.

    If you're using one of these as a singleton, then your app's start-up code should
    first of all call setStorageParameters() to tell it the parameters to use to create
    the properties files.

    @see PropertiesFile
*/
class JUCE_API  ApplicationProperties   : public DeletedAtShutdown
{
public:

    /**
        Creates an ApplicationProperties object.

        Before using it, you must call setStorageParameters() to give it the info
        it needs to create the property files.
    */
    ApplicationProperties() throw();

    /** Destructor.
    */
    ~ApplicationProperties();

    juce_DeclareSingleton (ApplicationProperties, false)

    /** Gives the object the information it needs to create the appropriate properties files.

        See the comments for PropertiesFile::createDefaultAppPropertiesFile() for more
        info about how these parameters are used.
    */
    void setStorageParameters (const String& applicationName,
                               const String& fileNameSuffix,
                               const String& folderName,
                               const int millisecondsBeforeSaving,
                               const int propertiesFileOptions) throw();

    /** Tests whether the files can be successfully written to, and can show
        an error message if not.

        Returns true if none of the tests fail.

        @param testUserSettings     if true, the user settings file will be tested
        @param testCommonSettings   if true, the common settings file will be tested
        @param showWarningDialogOnFailure   if true, the method will show a helpful error
                                    message box if either of the tests fail
    */
    bool testWriteAccess (const bool testUserSettings,
                          const bool testCommonSettings,
                          const bool showWarningDialogOnFailure);

    /** Returns the user settings file.

        The first time this is called, it will create and load the properties file.

        Note that when you search the user PropertiesFile for a value that it doesn't contain,
        the common settings are used as a second-chance place to look. This is done via the
        PropertySet::setFallbackPropertySet() method - by default the common settings are set
        to the fallback for the user settings.

        @see getCommonSettings
    */
    PropertiesFile* getUserSettings() throw();

    /** Returns the common settings file.

        The first time this is called, it will create and load the properties file.

        @param returnUserPropsIfReadOnly  if this is true, and the common properties file is
                            read-only (e.g. because the user doesn't have permission to write
                            to shared files), then this will return the user settings instead,
                            (like getUserSettings() would do). This is handy if you'd like to
                            write a value to the common settings, but if that's no possible,
                            then you'd rather write to the user settings than none at all.
                            If returnUserPropsIfReadOnly is false, this method will always return
                            the common settings, even if any changes to them can't be saved.
        @see getUserSettings
    */
    PropertiesFile* getCommonSettings (const bool returnUserPropsIfReadOnly) throw();

    /** Saves both files if they need to be saved.

        @see PropertiesFile::saveIfNeeded
    */
    bool saveIfNeeded();

    /** Flushes and closes both files if they are open.

        This flushes any pending changes to disk with PropertiesFile::saveIfNeeded()
        and closes both files. They will then be re-opened the next time getUserSettings()
        or getCommonSettings() is called.
    */
    void closeFiles();

    juce_UseDebuggingNewOperator

private:

    PropertiesFile* userProps;
    PropertiesFile* commonProps;

    String appName, fileSuffix, folderName;
    int msBeforeSaving, options;
    int commonSettingsAreReadOnly;

    ApplicationProperties (const ApplicationProperties&);
    const ApplicationProperties& operator= (const ApplicationProperties&);

    void openFiles() throw();
};

#endif   // __JUCE_APPLICATIONPROPERTIES_JUCEHEADER__
/********* End of inlined file: juce_ApplicationProperties.h *********/

#endif
#ifndef __JUCE_PROPERTIESFILE_JUCEHEADER__

#endif
#ifndef __JUCE_SYSTEMCLIPBOARD_JUCEHEADER__

/********* Start of inlined file: juce_SystemClipboard.h *********/
#ifndef __JUCE_SYSTEMCLIPBOARD_JUCEHEADER__
#define __JUCE_SYSTEMCLIPBOARD_JUCEHEADER__

/**
    Handles reading/writing to the system's clipboard.
*/
class JUCE_API  SystemClipboard
{
public:
    /** Copies a string of text onto the clipboard */
    static void copyTextToClipboard (const String& text) throw();

    /** Gets the current clipboard's contents.

        Obviously this might have come from another app, so could contain
        anything..
    */
    static const String getTextFromClipboard() throw();
};

#endif   // __JUCE_SYSTEMCLIPBOARD_JUCEHEADER__
/********* End of inlined file: juce_SystemClipboard.h *********/

#endif
#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__

/********* Start of inlined file: juce_MidiBuffer.h *********/
#ifndef __JUCE_MIDIBUFFER_JUCEHEADER__
#define __JUCE_MIDIBUFFER_JUCEHEADER__

/********* Start of inlined file: juce_MidiMessage.h *********/
#ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__
#define __JUCE_MIDIMESSAGE_JUCEHEADER__

/**
    Encapsulates a MIDI message.

    @see MidiMessageSequence, MidiOutput, MidiInput
*/
class JUCE_API  MidiMessage
{
public:

    /** Creates a 3-byte short midi message.

        @param byte1            message byte 1
        @param byte2            message byte 2
        @param byte3            message byte 3
        @param timeStamp        the time to give the midi message - this value doesn't
                                use any particular units, so will be application-specific
    */
    MidiMessage (const int byte1,
                 const int byte2,
                 const int byte3,
                 const double timeStamp = 0) throw();

    /** Creates a 2-byte short midi message.

        @param byte1            message byte 1
        @param byte2            message byte 2
        @param timeStamp        the time to give the midi message - this value doesn't
                                use any particular units, so will be application-specific
    */
    MidiMessage (const int byte1,
                 const int byte2,
                 const double timeStamp = 0) throw();

    /** Creates a 1-byte short midi message.

        @param byte1            message byte 1
        @param timeStamp        the time to give the midi message - this value doesn't
                                use any particular units, so will be application-specific
    */
    MidiMessage (const int byte1,
                 const double timeStamp = 0) throw();

    /** Creates a midi message from a block of data. */
    MidiMessage (const uint8* const data,
                 const int dataSize,
                 const double timeStamp = 0) throw();

    /** Reads the next midi message from some data.

        This will read as many bytes from a data stream as it needs to make a
        complete message, and will return the number of bytes it used. This lets
        you read a sequence of midi messages from a file or stream.

        @param data             the data to read from
        @param size             the maximum number of bytes it's allowed to read
        @param numBytesUsed     returns the number of bytes that were actually needed
        @param lastStatusByte   in a sequence of midi messages, the initial byte
                                can be dropped from a message if it's the same as the
                                first byte of the previous message, so this lets you
                                supply the byte to use if the first byte of the message
                                has in fact been dropped.
        @param timeStamp        the time to give the midi message - this value doesn't
                                use any particular units, so will be application-specific
    */
    MidiMessage (const uint8* data,
                 int size,
                 int& numBytesUsed,
                 uint8 lastStatusByte,
                 double timeStamp = 0) throw();

    /** Creates a copy of another midi message. */
    MidiMessage (const MidiMessage& other) throw();

    /** Creates a copy of another midi message, with a different timestamp. */
    MidiMessage (const MidiMessage& other,
                 const double newTimeStamp) throw();

    /** Destructor. */
    ~MidiMessage() throw();

    /** Copies this message from another one. */
    const MidiMessage& operator= (const MidiMessage& other) throw();

    /** Returns a pointer to the raw midi data.

        @see getRawDataSize
    */
    uint8* getRawData() const throw()                           { return data; }

    /** Returns the number of bytes of data in the message.

        @see getRawData
    */
    int getRawDataSize() const throw()                          { return size; }

    /** Returns the timestamp associated with this message.

        The units for the timestamp will be application-specific.

        @see setTimeStamp, addToTimeStamp
    */
    double getTimeStamp() const throw()                         { return timeStamp; }

    /** Changes the message's associated timestamp.

        The units for the timestamp will be application-specific.

        @see addToTimeStamp, getTimeStamp
    */
    void setTimeStamp (const double newTimestamp) throw()       { timeStamp = newTimestamp; }

    /** Adds a value to the message's timestamp.

        The units for the timestamp will be application-specific.
    */
    void addToTimeStamp (const double delta) throw()            { timeStamp += delta; }

    /** Returns the midi channel associated with the message.

        @returns    a value 1 to 16 if the message has a channel, or 0 if it hasn't (e.g.
                    if it's a sysex)
        @see isForChannel, setChannel
    */
    int getChannel() const throw();

    /** Returns true if the message applies to the given midi channel.

        @param channelNumber    the channel number to look for, in the range 1 to 16
        @see getChannel, setChannel
    */
    bool isForChannel (const int channelNumber) const throw();

    /** Changes the message's midi channel.

        This won't do anything for non-channel messages like sysexes.

        @param newChannelNumber    the channel number to change it to, in the range 1 to 16
    */
    void setChannel (const int newChannelNumber) throw();

    /** Returns true if this is a system-exclusive message.
    */
    bool isSysEx() const throw();

    /** Returns a pointer to the sysex data inside the message.

        If this event isn't a sysex event, it'll return 0.

        @see getSysExDataSize
    */
    const uint8* getSysExData() const throw();

    /** Returns the size of the sysex data.

        This value excludes the 0xf0 header byte and the 0xf7 at the end.

        @see getSysExData
    */
    int getSysExDataSize() const throw();

    /** Returns true if this message is a 'key-down' event.

        This will return false for a note-on event with a velocity of 0.

        @see isNoteOff, getNoteNumber, getVelocity, noteOn
    */
    bool isNoteOn() const throw();

    /** Creates a key-down message (using a floating-point velocity).

        @param channel      the midi channel, in the range 1 to 16
        @param noteNumber   the key number, 0 to 127
        @param velocity     in the range 0 to 1.0
        @see isNoteOn
    */
    static const MidiMessage noteOn (const int channel,
                                     const int noteNumber,
                                     const float velocity) throw();

    /** Creates a key-down message (using an integer velocity).

        @param channel      the midi channel, in the range 1 to 16
        @param noteNumber   the key number, 0 to 127
        @param velocity     in the range 0 to 127
        @see isNoteOn
    */
    static const MidiMessage noteOn (const int channel,
                                     const int noteNumber,
                                     const uint8 velocity) throw();

    /** Returns true if this message is a 'key-up' event.

        This will also return true for a note-on event with a velocity of 0.

        @see isNoteOn, getNoteNumber, getVelocity, noteOff
    */
    bool isNoteOff() const throw();

    /** Creates a key-up message.

        @param channel      the midi channel, in the range 1 to 16
        @param noteNumber   the key number, 0 to 127
        @see isNoteOff
    */
    static const MidiMessage noteOff (const int channel,
                                      const int noteNumber) throw();

    /** Returns true if this message is a 'key-down' or 'key-up' event.

        @see isNoteOn, isNoteOff
    */
    bool isNoteOnOrOff() const throw();

    /** Returns the midi note number for note-on and note-off messages.

        If the message isn't a note-on or off, the value returned will be
        meaningless.

        @see isNoteOff, getMidiNoteName, getMidiNoteInHertz, setNoteNumber
    */
    int getNoteNumber() const throw();

    /** Changes the midi note number of a note-on or note-off message.

        If the message isn't a note on or off, this will do nothing.
    */
    void setNoteNumber (const int newNoteNumber) throw();

    /** Returns the velocity of a note-on or note-off message.

        The value returned will be in the range 0 to 127.

        If the message isn't a note-on or off event, it will return 0.

        @see getFloatVelocity
    */
    uint8 getVelocity() const throw();

    /** Returns the velocity of a note-on or note-off message.

        The value returned will be in the range 0 to 1.0

        If the message isn't a note-on or off event, it will return 0.

        @see getVelocity, setVelocity
    */
    float getFloatVelocity() const throw();

    /** Changes the velocity of a note-on or note-off message.

        If the message isn't a note on or off, this will do nothing.

        @param newVelocity  the new velocity, in the range 0 to 1.0
        @see getFloatVelocity, multiplyVelocity
    */
    void setVelocity (const float newVelocity) throw();

    /** Multiplies the velocity of a note-on or note-off message by a given amount.

        If the message isn't a note on or off, this will do nothing.

        @param scaleFactor  the value by which to multiply the velocity
        @see setVelocity
    */
    void multiplyVelocity (const float scaleFactor) throw();

    /** Returns true if the message is a program (patch) change message.

        @see getProgramChangeNumber, getGMInstrumentName
    */
    bool isProgramChange() const throw();

    /** Returns the new program number of a program change message.

        If the message isn't a program change, the value returned will be
        nonsense.

        @see isProgramChange, getGMInstrumentName
    */
    int getProgramChangeNumber() const throw();

    /** Creates a program-change message.

        @param channel          the midi channel, in the range 1 to 16
        @param programNumber    the midi program number, 0 to 127
        @see isProgramChange, getGMInstrumentName
    */
    static const MidiMessage programChange (const int channel,
                                            const int programNumber) throw();

    /** Returns true if the message is a pitch-wheel move.

        @see getPitchWheelValue, pitchWheel
    */
    bool isPitchWheel() const throw();

    /** Returns the pitch wheel position from a pitch-wheel move message.

        The value returned is a 14-bit number from 0 to 0x3fff, indicating the wheel position.
        If called for messages which aren't pitch wheel events, the number returned will be
        nonsense.

        @see isPitchWheel
    */
    int getPitchWheelValue() const throw();

    /** Creates a pitch-wheel move message.

        @param channel      the midi channel, in the range 1 to 16
        @param position     the wheel position, in the range 0 to 16383
        @see isPitchWheel
    */
    static const MidiMessage pitchWheel (const int channel,
                                         const int position) throw();

    /** Returns true if the message is an aftertouch event.

        For aftertouch events, use the getNoteNumber() method to find out the key
        that it applies to, and getAftertouchValue() to find out the amount. Use
        getChannel() to find out the channel.

        @see getAftertouchValue, getNoteNumber
    */
    bool isAftertouch() const throw();

    /** Returns the amount of aftertouch from an aftertouch messages.

        The value returned is in the range 0 to 127, and will be nonsense for messages
        other than aftertouch messages.

        @see isAftertouch
    */
    int getAfterTouchValue() const throw();

    /** Creates an aftertouch message.

        @param channel              the midi channel, in the range 1 to 16
        @param noteNumber           the key number, 0 to 127
        @param aftertouchAmount     the amount of aftertouch, 0 to 127
        @see isAftertouch
    */
    static const MidiMessage aftertouchChange (const int channel,
                                               const int noteNumber,
                                               const int aftertouchAmount) throw();

    /** Returns true if the message is a channel-pressure change event.

        This is like aftertouch, but common to the whole channel rather than a specific
        note. Use getChannelPressureValue() to find out the pressure, and getChannel()
        to find out the channel.

        @see channelPressureChange
    */
    bool isChannelPressure() const throw();

    /** Returns the pressure from a channel pressure change message.

        @returns the pressure, in the range 0 to 127
        @see isChannelPressure, channelPressureChange
    */
    int getChannelPressureValue() const throw();

    /** Creates a channel-pressure change event.

        @param channel              the midi channel: 1 to 16
        @param pressure             the pressure, 0 to 127
        @see isChannelPressure
    */
    static const MidiMessage channelPressureChange (const int channel,
                                                    const int pressure) throw();

    /** Returns true if this is a midi controller message.

        @see getControllerNumber, getControllerValue, controllerEvent
    */
    bool isController() const throw();

    /** Returns the controller number of a controller message.

        The name of the controller can be looked up using the getControllerName() method.

        Note that the value returned is invalid for messages that aren't controller changes.

        @see isController, getControllerName, getControllerValue
    */
    int getControllerNumber() const throw();

    /** Returns the controller value from a controller message.

        A value 0 to 127 is returned to indicate the new controller position.

        Note that the value returned is invalid for messages that aren't controller changes.

        @see isController, getControllerNumber
    */
    int getControllerValue() const throw();

    /** Creates a controller message.

        @param channel          the midi channel, in the range 1 to 16
        @param controllerType   the type of controller
        @param value            the controller value
        @see isController
    */
    static const MidiMessage controllerEvent (const int channel,
                                              const int controllerType,
                                              const int value) throw();

    /** Checks whether this message is an all-notes-off message.

        @see allNotesOff
    */
    bool isAllNotesOff() const throw();

    /** Checks whether this message is an all-sound-off message.

        @see allSoundOff
    */
    bool isAllSoundOff() const throw();

    /** Creates an all-notes-off message.

        @param channel              the midi channel, in the range 1 to 16
        @see isAllNotesOff
    */
    static const MidiMessage allNotesOff (const int channel) throw();

    /** Creates an all-sound-off message.

        @param channel              the midi channel, in the range 1 to 16
        @see isAllSoundOff
    */
    static const MidiMessage allSoundOff (const int channel) throw();

    /** Creates an all-controllers-off message.

        @param channel              the midi channel, in the range 1 to 16
    */
    static const MidiMessage allControllersOff (const int channel) throw();

    /** Returns true if this event is a meta-event.

        Meta-events are things like tempo changes, track names, etc.

        @see getMetaEventType, isTrackMetaEvent, isEndOfTrackMetaEvent,
             isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent,
             isKeySignatureMetaEvent, isMidiChannelMetaEvent
    */
    bool isMetaEvent() const throw();

    /** Returns a meta-event's type number.

        If the message isn't a meta-event, this will return -1.

        @see isMetaEvent, isTrackMetaEvent, isEndOfTrackMetaEvent,
             isTextMetaEvent, isTrackNameEvent, isTempoMetaEvent, isTimeSignatureMetaEvent,
             isKeySignatureMetaEvent, isMidiChannelMetaEvent
    */
    int getMetaEventType() const throw();

    /** Returns a pointer to the data in a meta-event.

        @see isMetaEvent, getMetaEventLength
    */
    const uint8* getMetaEventData() const throw();

    /** Returns the length of the data for a meta-event.

        @see isMetaEvent, getMetaEventData
    */
    int getMetaEventLength() const throw();

    /** Returns true if this is a 'track' meta-event. */
    bool isTrackMetaEvent() const throw();

    /** Returns true if this is an 'end-of-track' meta-event. */
    bool isEndOfTrackMetaEvent() const throw();

    /** Creates an end-of-track meta-event.

        @see isEndOfTrackMetaEvent
    */
    static const MidiMessage endOfTrack() throw();

    /** Returns true if this is an 'track name' meta-event.

        You can use the getTextFromTextMetaEvent() method to get the track's name.
    */
    bool isTrackNameEvent() const throw();

    /** Returns true if this is a 'text' meta-event.

        @see getTextFromTextMetaEvent
    */
    bool isTextMetaEvent() const throw();

    /** Returns the text from a text meta-event.

        @see isTextMetaEvent
    */
    const String getTextFromTextMetaEvent() const throw();

    /** Returns true if this is a 'tempo' meta-event.

        @see getTempoMetaEventTickLength, getTempoSecondsPerQuarterNote
    */
    bool isTempoMetaEvent() const throw();

    /** Returns the tick length from a tempo meta-event.

        @param timeFormat   the 16-bit time format value from the midi file's header.
        @returns the tick length (in seconds).
        @see isTempoMetaEvent
    */
    double getTempoMetaEventTickLength (const short timeFormat) const throw();

    /** Calculates the seconds-per-quarter-note from a tempo meta-event.

        @see isTempoMetaEvent, getTempoMetaEventTickLength
    */
    double getTempoSecondsPerQuarterNote() const throw();

    /** Creates a tempo meta-event.

        @see isTempoMetaEvent
    */
    static const MidiMessage tempoMetaEvent (const int microsecondsPerQuarterNote) throw();

    /** Returns true if this is a 'time-signature' meta-event.

        @see getTimeSignatureInfo
    */
    bool isTimeSignatureMetaEvent() const throw();

    /** Returns the time-signature values from a time-signature meta-event.

        @see isTimeSignatureMetaEvent
    */
    void getTimeSignatureInfo (int& numerator,
                               int& denominator) const throw();

    /** Creates a time-signature meta-event.

        @see isTimeSignatureMetaEvent
    */
    static const MidiMessage timeSignatureMetaEvent (const int numerator,
                                                     const int denominator) throw();

    /** Returns true if this is a 'key-signature' meta-event.

        @see getKeySignatureNumberOfSharpsOrFlats
    */
    bool isKeySignatureMetaEvent() const throw();

    /** Returns the key from a key-signature meta-event.

        @see isKeySignatureMetaEvent
    */
    int getKeySignatureNumberOfSharpsOrFlats() const throw();

    /** Returns true if this is a 'channel' meta-event.

        A channel meta-event specifies the midi channel that should be used
        for subsequent meta-events.

        @see getMidiChannelMetaEventChannel
    */
    bool isMidiChannelMetaEvent() const throw();

    /** Returns the channel number from a channel meta-event.

        @returns the channel, in the range 1 to 16.
        @see isMidiChannelMetaEvent
    */
    int getMidiChannelMetaEventChannel() const throw();

    /** Creates a midi channel meta-event.

        @param channel              the midi channel, in the range 1 to 16
        @see isMidiChannelMetaEvent
    */
    static const MidiMessage midiChannelMetaEvent (const int channel) throw();

    /** Returns true if this is an active-sense message. */
    bool isActiveSense() const throw();

    /** Returns true if this is a midi start event.

        @see midiStart
    */
    bool isMidiStart() const throw();

    /** Creates a midi start event. */
    static const MidiMessage midiStart() throw();

    /** Returns true if this is a midi continue event.

        @see midiContinue
    */
    bool isMidiContinue() const throw();

    /** Creates a midi continue event. */
    static const MidiMessage midiContinue() throw();

    /** Returns true if this is a midi stop event.

        @see midiStop
    */
    bool isMidiStop() const throw();

    /** Creates a midi stop event. */
    static const MidiMessage midiStop() throw();

    /** Returns true if this is a midi clock event.

        @see midiClock, songPositionPointer
    */
    bool isMidiClock() const throw();

    /** Creates a midi clock event. */
    static const MidiMessage midiClock() throw();

    /** Returns true if this is a song-position-pointer message.

        @see getSongPositionPointerMidiBeat, songPositionPointer
    */
    bool isSongPositionPointer() const throw();

    /** Returns the midi beat-number of a song-position-pointer message.

        @see isSongPositionPointer, songPositionPointer
    */
    int getSongPositionPointerMidiBeat() const throw();

    /** Creates a song-position-pointer message.

        The position is a number of midi beats from the start of the song, where 1 midi
        beat is 6 midi clocks, and there are 24 midi clocks in a quarter-note. So there
        are 4 midi beats in a quarter-note.

        @see isSongPositionPointer, getSongPositionPointerMidiBeat
    */
    static const MidiMessage songPositionPointer (const int positionInMidiBeats) throw();

    /** Returns true if this is a quarter-frame midi timecode message.

        @see quarterFrame, getQuarterFrameSequenceNumber, getQuarterFrameValue
    */
    bool isQuarterFrame() const throw();

    /** Returns the sequence number of a quarter-frame midi timecode message.

        This will be a value between 0 and 7.

        @see isQuarterFrame, getQuarterFrameValue, quarterFrame
    */
    int getQuarterFrameSequenceNumber() const throw();

    /** Returns the value from a quarter-frame message.

        This will be the lower nybble of the message's data-byte, a value
        between 0 and 15
    */
    int getQuarterFrameValue() const throw();

    /** Creates a quarter-frame MTC message.

        @param sequenceNumber   a value 0 to 7 for the upper nybble of the message's data byte
        @param value            a value 0 to 15 for the lower nybble of the message's data byte
    */
    static const MidiMessage quarterFrame (const int sequenceNumber,
                                           const int value) throw();

    /** SMPTE timecode types.

        Used by the getFullFrameParameters() and fullFrame() methods.
    */
    enum SmpteTimecodeType
    {
        fps24       = 0,
        fps25       = 1,
        fps30drop   = 2,
        fps30       = 3
    };

    /** Returns true if this is a full-frame midi timecode message.
    */
    bool isFullFrame() const throw();

    /** Extracts the timecode information from a full-frame midi timecode message.

        You should only call this on messages where you've used isFullFrame() to
        check that they're the right kind.
    */
    void getFullFrameParameters (int& hours,
                                 int& minutes,
                                 int& seconds,
                                 int& frames,
                                 SmpteTimecodeType& timecodeType) const throw();

    /** Creates a full-frame MTC message.
    */
    static const MidiMessage fullFrame (const int hours,
                                        const int minutes,
                                        const int seconds,
                                        const int frames,
                                        SmpteTimecodeType timecodeType);

    /** Types of MMC command.

        @see isMidiMachineControlMessage, getMidiMachineControlCommand, midiMachineControlCommand
    */
    enum MidiMachineControlCommand
    {
        mmc_stop            = 1,
        mmc_play            = 2,
        mmc_deferredplay    = 3,
        mmc_fastforward     = 4,
        mmc_rewind          = 5,
        mmc_recordStart     = 6,
        mmc_recordStop      = 7,
        mmc_pause           = 9
    };

    /** Checks whether this is an MMC message.

        If it is, you can use the getMidiMachineControlCommand() to find out its type.
    */
    bool isMidiMachineControlMessage() const throw();

    /** For an MMC message, this returns its type.

        Make sure it's actually an MMC message with isMidiMachineControlMessage() before
        calling this method.
    */
    MidiMachineControlCommand getMidiMachineControlCommand() const throw();

    /** Creates an MMC message.
    */
    static const MidiMessage midiMachineControlCommand (MidiMachineControlCommand command);

    /** Checks whether this is an MMC "goto" message.

        If it is, the parameters passed-in are set to the time that the message contains.

        @see midiMachineControlGoto
    */
    bool isMidiMachineControlGoto (int& hours,
                                   int& minutes,
                                   int& seconds,
                                   int& frames) const throw();

    /** Creates an MMC "goto" message.

        This messages tells the device to go to a specific frame.

        @see isMidiMachineControlGoto
    */
    static const MidiMessage midiMachineControlGoto (int hours,
                                                     int minutes,
                                                     int seconds,
                                                     int frames);

    /** Creates a master-volume change message.

        @param volume   the volume, 0 to 1.0
    */
    static const MidiMessage masterVolume (const float volume) throw();

    /** Creates a system-exclusive message.

        The data passed in is wrapped with header and tail bytes of 0xf0 and 0xf7.
    */
    static const MidiMessage createSysExMessage (const uint8* sysexData,
                                                 const int dataSize) throw();

    /** Reads a midi variable-length integer.

        @param data             the data to read the number from
        @param numBytesUsed     on return, this will be set to the number of bytes that were read
    */
    static int readVariableLengthVal (const uint8* data,
                                      int& numBytesUsed) throw();

    /** Based on the first byte of a short midi message, this uses a lookup table
        to return the message length (either 1, 2, or 3 bytes).

        The value passed in must be 0x80 or higher.
    */
    static int getMessageLengthFromFirstByte (const uint8 firstByte) throw();

    /** Returns the name of a midi note number.

        E.g "C", "D#", etc.

        @param noteNumber           the midi note number, 0 to 127
        @param useSharps            if true, sharpened notes are used, e.g. "C#", otherwise
                                    they'll be flattened, e.g. "Db"
        @param includeOctaveNumber  if true, the octave number will be appended to the string,
                                    e.g. "C#4"
        @param octaveNumForMiddleC  if an octave number is being appended, this indicates the
                                    number that will be used for middle C's octave

        @see getMidiNoteInHertz
    */
    static const String getMidiNoteName (int noteNumber,
                                         bool useSharps,
                                         bool includeOctaveNumber,
                                         int octaveNumForMiddleC) throw();

    /** Returns the frequency of a midi note number.

        @see getMidiNoteName
    */
    static const double getMidiNoteInHertz (int noteNumber) throw();

    /** Returns the standard name of a GM instrument.

        @param midiInstrumentNumber     the program number 0 to 127
        @see getProgramChangeNumber
    */
    static const String getGMInstrumentName (int midiInstrumentNumber) throw();

    /** Returns the name of a bank of GM instruments.

        @param midiBankNumber   the bank, 0 to 15
    */
    static const String getGMInstrumentBankName (int midiBankNumber) throw();

    /** Returns the standard name of a channel 10 percussion sound.

        @param midiNoteNumber   the key number, 35 to 81
    */
    static const String getRhythmInstrumentName (int midiNoteNumber) throw();

    /** Returns the name of a controller type number.

        @see getControllerNumber
    */
    static const String getControllerName (int controllerNumber) throw();

    juce_UseDebuggingNewOperator

private:
    double timeStamp;
    uint8* data;
    int message, size;
};

#endif   // __JUCE_MIDIMESSAGE_JUCEHEADER__
/********* End of inlined file: juce_MidiMessage.h *********/

/**
    Holds a sequence of time-stamped midi events.

    Analogous to the AudioSampleBuffer, this holds a set of midi events with
    integer time-stamps. The buffer is kept sorted in order of the time-stamps.

    @see MidiMessage
*/
class JUCE_API  MidiBuffer  : private ArrayAllocationBase <uint8>
{
public:

    /** Creates an empty MidiBuffer. */
    MidiBuffer() throw();

    /** Creates a MidiBuffer containing a single midi message. */
    MidiBuffer (const MidiMessage& message) throw();

    /** Creates a copy of another MidiBuffer. */
    MidiBuffer (const MidiBuffer& other) throw();

    /** Makes a copy of another MidiBuffer. */
    const MidiBuffer& operator= (const MidiBuffer& other) throw();

    /** Destructor */
    ~MidiBuffer() throw();

    /** Removes all events from the buffer. */
    void clear() throw();

    /** Removes all events between two times from the buffer.

        All events for which (start <= event position < start + numSamples) will
        be removed.
    */
    void clear (const int start,
                const int numSamples) throw();

    /** Returns true if the buffer is empty.

        To actually retrieve the events, use a MidiBuffer::Iterator object
    */
    bool isEmpty() const throw();

    /** Counts the number of events in the buffer.

        This is actually quite a slow operation, as it has to iterate through all
        the events, so you might prefer to call isEmpty() if that's all you need
        to know.
    */
    int getNumEvents() const throw();

    /** Adds an event to the buffer.

        The sample number will be used to determine the position of the event in
        the buffer, which is always kept sorted. The MidiMessage's timestamp is
        ignored.

        If an event is added whose sample position is the same as one or more events
        already in the buffer, the new event will be placed after the existing ones.

        To retrieve events, use a MidiBuffer::Iterator object
    */
    void addEvent (const MidiMessage& midiMessage,
                   const int sampleNumber) throw();

    /** Adds an event to the buffer from raw midi data.

        The sample number will be used to determine the position of the event in
        the buffer, which is always kept sorted.

        If an event is added whose sample position is the same as one or more events
        already in the buffer, the new event will be placed after the existing ones.

        The event data will be inspected to calculate the number of bytes in length that
        the midi event really takes up, so maxBytesOfMidiData may be longer than the data
        that actually gets stored. E.g. if you pass in a note-on and a length of 4 bytes,
        it'll actually only store 3 bytes. If the midi data is invalid, it might not
        add an event at all.

        To retrieve events, use a MidiBuffer::Iterator object
    */
    void addEvent (const uint8* const rawMidiData,
                   const int maxBytesOfMidiData,
                   const int sampleNumber) throw();

    /** Adds some events from another buffer to this one.

        @param otherBuffer          the buffer containing the events you want to add
        @param startSample          the lowest sample number in the source buffer for which
                                    events should be added. Any source events whose timestamp is
                                    less than this will be ignored
        @param numSamples           the valid range of samples from the source buffer for which
                                    events should be added - i.e. events in the source buffer whose
                                    timestamp is greater than or equal to (startSample + numSamples)
                                    will be ignored. If this value is less than 0, all events after
                                    startSample will be taken.
        @param sampleDeltaToAdd     a value which will be added to the source timestamps of the events
                                    that are added to this buffer
    */
    void addEvents (const MidiBuffer& otherBuffer,
                    const int startSample,
                    const int numSamples,
                    const int sampleDeltaToAdd) throw();

    /** Returns the sample number of the first event in the buffer.

        If the buffer's empty, this will just return 0.
    */
    int getFirstEventTime() const throw();

    /** Returns the sample number of the last event in the buffer.

        If the buffer's empty, this will just return 0.
    */
    int getLastEventTime() const throw();

    /** Exchanges the contents of this buffer with another one.

        This is a quick operation, because no memory allocating or copying is done, it
        just swaps the internal state of the two buffers.
    */
    void swap (MidiBuffer& other);

    /**
        Used to iterate through the events in a MidiBuffer.

        Note that altering the buffer while an iterator is using it isn't a
        safe operation.

        @see MidiBuffer
    */
    class Iterator
    {
    public:

        /** Creates an Iterator for this MidiBuffer. */
        Iterator (const MidiBuffer& buffer) throw();

        /** Destructor. */
        ~Iterator() throw();

        /** Repositions the iterator so that the next event retrieved will be the first
            one whose sample position is at greater than or equal to the given position.
        */
        void setNextSamplePosition (const int samplePosition) throw();

        /** Retrieves a copy of the next event from the buffer.

            @param result   on return, this will be the message (the MidiMessage's timestamp
                            is not set)
            @param samplePosition   on return, this will be the position of the event
            @returns        true if an event was found, or false if the iterator has reached
                            the end of the buffer
        */
        bool getNextEvent (MidiMessage& result,
                           int& samplePosition) throw();

        /** Retrieves the next event from the buffer.

            @param midiData     on return, this pointer will be set to a block of data containing
                                the midi message. Note that to make it fast, this is a pointer
                                directly into the MidiBuffer's internal data, so is only valid
                                temporarily until the MidiBuffer is altered.
            @param numBytesOfMidiData   on return, this is the number of bytes of data used by the
                                        midi message
            @param samplePosition   on return, this will be the position of the event
            @returns        true if an event was found, or false if the iterator has reached
                            the end of the buffer
        */
        bool getNextEvent (const uint8* &midiData,
                           int& numBytesOfMidiData,
                           int& samplePosition) throw();

        juce_UseDebuggingNewOperator

    private:
        const MidiBuffer& buffer;
        const uint8* data;

        Iterator (const Iterator&);
        const Iterator& operator= (const Iterator&);
    };

    juce_UseDebuggingNewOperator

private:
    friend class MidiBuffer::Iterator;
    int bytesUsed;

    uint8* findEventAfter (uint8* d, const int samplePosition) const throw();
};

#endif   // __JUCE_MIDIBUFFER_JUCEHEADER__
/********* End of inlined file: juce_MidiBuffer.h *********/

#endif
#ifndef __JUCE_MIDIFILE_JUCEHEADER__

/********* Start of inlined file: juce_MidiFile.h *********/
#ifndef __JUCE_MIDIFILE_JUCEHEADER__
#define __JUCE_MIDIFILE_JUCEHEADER__

/********* Start of inlined file: juce_MidiMessageSequence.h *********/
#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__
#define __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__

/**
    A sequence of timestamped midi messages.

    This allows the sequence to be manipulated, and also to be read from and
    written to a standard midi file.

    @see MidiMessage, MidiFile
*/
class JUCE_API  MidiMessageSequence
{
public:

    /** Creates an empty midi sequence object. */
    MidiMessageSequence();

    /** Creates a copy of another sequence. */
    MidiMessageSequence (const MidiMessageSequence& other);

    /** Replaces this sequence with another one. */
    const MidiMessageSequence& operator= (const MidiMessageSequence& other);

    /** Destructor. */
    ~MidiMessageSequence();

    /** Structure used to hold midi events in the sequence.

        These structures act as 'handles' on the events as they are moved about in
        the list, and make it quick to find the matching note-offs for note-on events.

        @see MidiMessageSequence::getEventPointer
    */
    class MidiEventHolder
    {
    public:

        /** Destructor. */
        ~MidiEventHolder();

        /** The message itself, whose timestamp is used to specify the event's time.
        */
        MidiMessage message;

        /** The matching note-off event (if this is a note-on event).

            If this isn't a note-on, this pointer will be null.

            Use the MidiMessageSequence::updateMatchedPairs() method to keep these
            note-offs up-to-date after events have been moved around in the sequence
            or deleted.
        */
        MidiEventHolder* noteOffObject;

        juce_UseDebuggingNewOperator

    private:
        friend class MidiMessageSequence;
        MidiEventHolder (const MidiMessage& message);
    };

    /** Clears the sequence. */
    void clear();

    /** Returns the number of events in the sequence. */
    int getNumEvents() const;

    /** Returns a pointer to one of the events. */
    MidiEventHolder* getEventPointer (const int index) const;

    /** Returns the time of the note-up that matches the note-on at this index.

        If the event at this index isn't a note-on, it'll just return 0.

        @see MidiMessageSequence::MidiEventHolder::noteOffObject
    */
    double getTimeOfMatchingKeyUp (const int index) const;

    /** Returns the index of the note-up that matches the note-on at this index.

        If the event at this index isn't a note-on, it'll just return -1.

        @see MidiMessageSequence::MidiEventHolder::noteOffObject
    */
    int getIndexOfMatchingKeyUp (const int index) const;

    /** Returns the index of an event. */
    int getIndexOf (MidiEventHolder* const event) const;

    /** Returns the index of the first event on or after the given timestamp.

        If the time is beyond the end of the sequence, this will return the
        number of events.
    */
    int getNextIndexAtTime (const double timeStamp) const;

    /** Returns the timestamp of the first event in the sequence.

        @see getEndTime
    */
    double getStartTime() const;

    /** Returns the timestamp of the last event in the sequence.

        @see getStartTime
    */
    double getEndTime() const;

    /** Returns the timestamp of the event at a given index.

        If the index is out-of-range, this will return 0.0
    */
    double getEventTime (const int index) const;

    /** Inserts a midi message into the sequence.

        The index at which the new message gets inserted will depend on its timestamp,
        because the sequence is kept sorted.

        Remember to call updateMatchedPairs() after adding note-on events.

        @param newMessage       the new message to add (an internal copy will be made)
        @param timeAdjustment   an optional value to add to the timestamp of the message
                                that will be inserted
        @see updateMatchedPairs
    */
    void addEvent (const MidiMessage& newMessage,
                   double timeAdjustment = 0);

    /** Deletes one of the events in the sequence.

        Remember to call updateMatchedPairs() after removing events.

        @param index                 the index of the event to delete
        @param deleteMatchingNoteUp  whether to also remove the matching note-off
                                     if the event you're removing is a note-on
    */
    void deleteEvent (const int index,
                      const bool deleteMatchingNoteUp);

    /** Merges another sequence into this one.

        Remember to call updateMatchedPairs() after using this method.

        @param other                    the sequence to add from
        @param timeAdjustmentDelta      an amount to add to the timestamps of the midi events
                                        as they are read from the other sequence
        @param firstAllowableDestTime   events will not be added if their time is earlier
                                        than this time. (This is after their time has been adjusted
                                        by the timeAdjustmentDelta)
        @param endOfAllowableDestTimes  events will not be added if their time is equal to
                                        or greater than this time. (This is after their time has
                                        been adjusted by the timeAdjustmentDelta)
    */
    void addSequence (const MidiMessageSequence& other,
                      double timeAdjustmentDelta,
                      double firstAllowableDestTime,
                      double endOfAllowableDestTimes);

    /** Makes sure all the note-on and note-off pairs are up-to-date.

        Call this after moving messages about or deleting/adding messages, and it
        will scan the list and make sure all the note-offs in the MidiEventHolder
        structures are pointing at the correct ones.
    */
    void updateMatchedPairs();

    /** Copies all the messages for a particular midi channel to another sequence.

        @param channelNumberToExtract   the midi channel to look for, in the range 1 to 16
        @param destSequence             the sequence that the chosen events should be copied to
        @param alsoIncludeMetaEvents    if true, any meta-events (which don't apply to a specific
                                        channel) will also be copied across.
        @see extractSysExMessages
    */
    void extractMidiChannelMessages (const int channelNumberToExtract,
                                     MidiMessageSequence& destSequence,
                                     const bool alsoIncludeMetaEvents) const;

    /** Copies all midi sys-ex messages to another sequence.

        @param destSequence     this is the sequence to which any sys-exes in this sequence
                                will be added
        @see extractMidiChannelMessages
    */
    void extractSysExMessages (MidiMessageSequence& destSequence) const;

    /** Removes any messages in this sequence that have a specific midi channel.

        @param channelNumberToRemove    the midi channel to look for, in the range 1 to 16
    */
    void deleteMidiChannelMessages (const int channelNumberToRemove);

    /** Removes any sys-ex messages from this sequence.
    */
    void deleteSysExMessages();

    /** Adds an offset to the timestamps of all events in the sequence.

        @param deltaTime    the amount to add to each timestamp.
    */
    void addTimeToMessages (const double deltaTime);

    /** Scans through the sequence to determine the state of any midi controllers at
        a given time.

        This will create a sequence of midi controller changes that can be
        used to set all midi controllers to the state they would be in at the
        specified time within this sequence.

        As well as controllers, it will also recreate the midi program number
        and pitch bend position.

        @param channelNumber    the midi channel to look for, in the range 1 to 16. Controllers
                                for other channels will be ignored.
        @param time             the time at which you want to find out the state - there are
                                no explicit units for this time measurement, it's the same units
                                as used for the timestamps of the messages
        @param resultMessages   an array to which midi controller-change messages will be added. This
                                will be the minimum number of controller changes to recreate the
                                state at the required time.
    */
    void createControllerUpdatesForTime (const int channelNumber,
                                         const double time,
                                         OwnedArray<MidiMessage>& resultMessages);

    juce_UseDebuggingNewOperator

    /** @internal */
    static int compareElements (const MidiMessageSequence::MidiEventHolder* const first,
                                const MidiMessageSequence::MidiEventHolder* const second) throw();

private:

    friend class MidiComparator;
    friend class MidiFile;
    OwnedArray <MidiEventHolder> list;

    void sort();
};

#endif   // __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__
/********* End of inlined file: juce_MidiMessageSequence.h *********/

/**
    Reads/writes standard midi format files.

    To read a midi file, create a MidiFile object and call its readFrom() method. You
    can then get the individual midi tracks from it using the getTrack() method.

    To write a file, create a MidiFile object, add some MidiMessageSequence objects
    to it using the addTrack() method, and then call its writeTo() method to stream
    it out.

    @see MidiMessageSequence
*/
class JUCE_API  MidiFile
{
public:

    /** Creates an empty MidiFile object.
    */
    MidiFile() throw();

    /** Destructor. */
    ~MidiFile() throw();

    /** Returns the number of tracks in the file.

        @see getTrack, addTrack
    */
    int getNumTracks() const throw();

    /** Returns a pointer to one of the tracks in the file.

        @returns a pointer to the track, or 0 if the index is out-of-range
        @see getNumTracks, addTrack
    */
    const MidiMessageSequence* getTrack (const int index) const throw();

    /** Adds a midi track to the file.

        This will make its own internal copy of the sequence that is passed-in.

        @see getNumTracks, getTrack
    */
    void addTrack (const MidiMessageSequence& trackSequence)  throw();

    /** Removes all midi tracks from the file.

        @see getNumTracks
    */
    void clear() throw();

    /** Returns the raw time format code that will be written to a stream.

        After reading a midi file, this method will return the time-format that
        was read from the file's header. It can be changed using the setTicksPerQuarterNote()
        or setSmpteTimeFormat() methods.

        If the value returned is positive, it indicates the number of midi ticks
        per quarter-note - see setTicksPerQuarterNote().

        It it's negative, the upper byte indicates the frames-per-second (but negative), and
        the lower byte is the number of ticks per frame - see setSmpteTimeFormat().
    */
    short getTimeFormat() const throw();

    /** Sets the time format to use when this file is written to a stream.

        If this is called, the file will be written as bars/beats using the
        specified resolution, rather than SMPTE absolute times, as would be
        used if setSmpteTimeFormat() had been called instead.

        @param ticksPerQuarterNote  e.g. 96, 960
        @see setSmpteTimeFormat
    */
    void setTicksPerQuarterNote (const int ticksPerQuarterNote) throw();

    /** Sets the time format to use when this file is written to a stream.

        If this is called, the file will be written using absolute times, rather
        than bars/beats as would be the case if setTicksPerBeat() had been called
        instead.

        @param framesPerSecond      must be 24, 25, 29 or 30
        @param subframeResolution   the sub-second resolution, e.g. 4 (midi time code),
                                    8, 10, 80 (SMPTE bit resolution), or 100. For millisecond
                                    timing, setSmpteTimeFormat (25, 40)
        @see setTicksPerBeat
    */
    void setSmpteTimeFormat (const int framesPerSecond,
                             const int subframeResolution) throw();

    /** Makes a list of all the tempo-change meta-events from all tracks in the midi file.

        Useful for finding the positions of all the tempo changes in a file.

        @param tempoChangeEvents    a list to which all the events will be added
    */
    void findAllTempoEvents (MidiMessageSequence& tempoChangeEvents) const;

    /** Makes a list of all the time-signature meta-events from all tracks in the midi file.

        Useful for finding the positions of all the tempo changes in a file.

        @param timeSigEvents        a list to which all the events will be added
    */
    void findAllTimeSigEvents (MidiMessageSequence& timeSigEvents) const;

    /** Returns the latest timestamp in any of the tracks.

        (Useful for finding the length of the file).
    */
    double getLastTimestamp() const;

    /** Reads a midi file format stream.

        After calling this, you can get the tracks that were read from the file by using the
        getNumTracks() and getTrack() methods.

        The timestamps of the midi events in the tracks will represent their positions in
        terms of midi ticks. To convert them to seconds, use the convertTimestampTicksToSeconds()
        method.

        @returns true if the stream was read successfully
    */
    bool readFrom (InputStream& sourceStream);

    /** Writes the midi tracks as a standard midi file.

        @returns true if the operation succeeded.
    */
    bool writeTo (OutputStream& destStream);

    /** Converts the timestamp of all the midi events from midi ticks to seconds.

        This will use the midi time format and tempo/time signature info in the
        tracks to convert all the timestamps to absolute values in seconds.
    */
    void convertTimestampTicksToSeconds();

    juce_UseDebuggingNewOperator

    /** @internal */
    static int compareElements (const MidiMessageSequence::MidiEventHolder* const first,
                                const MidiMessageSequence::MidiEventHolder* const second) throw();

private:
    MidiMessageSequence* tracks [128];
    short numTracks, timeFormat;

    MidiFile (const MidiFile&);
    const MidiFile& operator= (const MidiFile&);

    void readNextTrack (const char* data, int size);
    void writeTrack (OutputStream& mainOut, const int trackNum);
};

#endif   // __JUCE_MIDIFILE_JUCEHEADER__
/********* End of inlined file: juce_MidiFile.h *********/

#endif
#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__

/********* Start of inlined file: juce_MidiKeyboardState.h *********/
#ifndef __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__
#define __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__

class MidiKeyboardState;

/**
    Receives events from a MidiKeyboardState object.

    @see MidiKeyboardState
*/
class JUCE_API  MidiKeyboardStateListener
{
public:

    MidiKeyboardStateListener() throw()         {}
    virtual ~MidiKeyboardStateListener()        {}

    /** Called when one of the MidiKeyboardState's keys is pressed.

        This will be called synchronously when the state is either processing a
        buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
        when a note is being played with its MidiKeyboardState::noteOn() method.

        Note that this callback could happen from an audio callback thread, so be
        careful not to block, and avoid any UI activity in the callback.
    */
    virtual void handleNoteOn (MidiKeyboardState* source,
                               int midiChannel, int midiNoteNumber, float velocity) = 0;

    /** Called when one of the MidiKeyboardState's keys is released.

        This will be called synchronously when the state is either processing a
        buffer in its MidiKeyboardState::processNextMidiBuffer() method, or
        when a note is being played with its MidiKeyboardState::noteOff() method.

        Note that this callback could happen from an audio callback thread, so be
        careful not to block, and avoid any UI activity in the callback.
    */
    virtual void handleNoteOff (MidiKeyboardState* source,
                                int midiChannel, int midiNoteNumber) = 0;
};

/**
    Represents a piano keyboard, keeping track of which keys are currently pressed.

    This object can parse a stream of midi events, using them to update its idea
    of which keys are pressed for each individiual midi channel.

    When keys go up or down, it can broadcast these events to listener objects.

    It also allows key up/down events to be triggered with its noteOn() and noteOff()
    methods, and midi messages for these events will be merged into the
    midi stream that gets processed by processNextMidiBuffer().
*/
class JUCE_API  MidiKeyboardState
{
public:

    MidiKeyboardState();
    ~MidiKeyboardState();

    /** Resets the state of the object.

        All internal data for all the channels is reset, but no events are sent as a
        result.

        If you want to release any keys that are currently down, and to send out note-up
        midi messages for this, use the allNotesOff() method instead.
    */
    void reset();

    /** Returns true if the given midi key is currently held down for the given midi channel.

        The channel number must be between 1 and 16. If you want to see if any notes are
        on for a range of channels, use the isNoteOnForChannels() method.
    */
    bool isNoteOn (const int midiChannel, const int midiNoteNumber) const throw();

    /** Returns true if the given midi key is currently held down on any of a set of midi channels.

        The channel mask has a bit set for each midi channel you want to test for - bit
        0 = midi channel 1, bit 1 = midi channel 2, etc.

        If a note is on for at least one of the specified channels, this returns true.
    */
    bool isNoteOnForChannels (const int midiChannelMask, const int midiNoteNumber) const throw();

    /** Turns a specified note on.

        This will cause a suitable midi note-on event to be injected into the midi buffer during the
        next call to processNextMidiBuffer().

        It will also trigger a synchronous callback to the listeners to tell them that the key has
        gone down.
    */
    void noteOn (const int midiChannel, const int midiNoteNumber, const float velocity);

    /** Turns a specified note off.

        This will cause a suitable midi note-off event to be injected into the midi buffer during the
        next call to processNextMidiBuffer().

        It will also trigger a synchronous callback to the listeners to tell them that the key has
        gone up.

        But if the note isn't acutally down for the given channel, this method will in fact do nothing.
    */
    void noteOff (const int midiChannel, const int midiNoteNumber);

    /** This will turn off any currently-down notes for the given midi channel.

        If you pass 0 for the midi channel, it will in fact turn off all notes on all channels.

        Calling this method will make calls to noteOff(), so can trigger synchronous callbacks
        and events being added to the midi stream.
    */
    void allNotesOff (const int midiChannel);

    /** Looks at a key-up/down event and uses it to update the state of this object.

        To process a buffer full of midi messages, use the processNextMidiBuffer() method
        instead.
    */
    void processNextMidiEvent (const MidiMessage& message);

    /** Scans a midi stream for up/down events and adds its own events to it.

        This will look for any up/down events and use them to update the internal state,
        synchronously making suitable callbacks to the listeners.

        If injectIndirectEvents is true, then midi events to produce the recent noteOn()
        and noteOff() calls will be added into the buffer.

        Only the section of the buffer whose timestamps are between startSample and
        (startSample + numSamples) will be affected, and any events added will be placed
        between these times.

        If you're going to use this method, you'll need to keep calling it regularly for
        it to work satisfactorily.

        To process a single midi event at a time, use the processNextMidiEvent() method
        instead.
    */
    void processNextMidiBuffer (MidiBuffer& buffer,
                                const int startSample,
                                const int numSamples,
                                const bool injectIndirectEvents);

    /** Registers a listener for callbacks when keys go up or down.

        @see removeListener
    */
    void addListener (MidiKeyboardStateListener* const listener) throw();

    /** Deregisters a listener.

        @see addListener
    */
    void removeListener (MidiKeyboardStateListener* const listener) throw();

    juce_UseDebuggingNewOperator

private:
    CriticalSection lock;
    uint16 noteStates [128];
    MidiBuffer eventsToAdd;
    VoidArray listeners;

    void noteOnInternal  (const int midiChannel, const int midiNoteNumber, const float velocity);
    void noteOffInternal  (const int midiChannel, const int midiNoteNumber);

    MidiKeyboardState (const MidiKeyboardState&);
    const MidiKeyboardState& operator= (const MidiKeyboardState&);
};

#endif   // __JUCE_MIDIKEYBOARDSTATE_JUCEHEADER__
/********* End of inlined file: juce_MidiKeyboardState.h *********/

#endif
#ifndef __JUCE_MIDIMESSAGE_JUCEHEADER__

#endif
#ifndef __JUCE_MIDIMESSAGESEQUENCE_JUCEHEADER__

#endif
#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__

/********* Start of inlined file: juce_MidiMessageCollector.h *********/
#ifndef __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__
#define __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__

/********* Start of inlined file: juce_MidiInput.h *********/
#ifndef __JUCE_MIDIINPUT_JUCEHEADER__
#define __JUCE_MIDIINPUT_JUCEHEADER__

class MidiInput;

/**
    Receives midi messages from a midi input device.

    This class is overridden to handle incoming midi messages. See the MidiInput
    class for more details.

    @see MidiInput
*/
class JUCE_API  MidiInputCallback
{
public:
    /** Destructor. */
    virtual ~MidiInputCallback()  {}

    /** Receives an incoming message.

        A MidiInput object will call this method when a midi event arrives. It'll be
        called on a high-priority system thread, so avoid doing anything time-consuming
        in here, and avoid making any UI calls. You might find the MidiBuffer class helpful
        for queueing incoming messages for use later.

        @param source   the MidiInput object that generated the message
        @param message  the incoming message. The message's timestamp is set to a value
                        equivalent to (Time::getMillisecondCounter() / 1000.0) to specify the
                        time when the message arrived.
    */
    virtual void handleIncomingMidiMessage (MidiInput* source,
                                            const MidiMessage& message) = 0;

    /** Notification sent each time a packet of a multi-packet sysex message arrives.

        If a long sysex message is broken up into multiple packets, this callback is made
        for each packet that arrives until the message is finished, at which point
        the normal handleIncomingMidiMessage() callback will be made with the entire
        message.

        The message passed in will contain the start of a sysex, but won't be finished
        with the terminating 0xf7 byte.
    */
    virtual void handlePartialSysexMessage (MidiInput* source,
                                            const uint8* messageData,
                                            const int numBytesSoFar,
                                            const double timestamp)
    {
        // (this bit is just to avoid compiler warnings about unused variables)
        (void) source; (void) messageData; (void) numBytesSoFar; (void) timestamp;
    }
};

/**
    Represents a midi input device.

    To create one of these, use the static getDevices() method to find out what inputs are
    available, and then use the openDevice() method to try to open one.

    @see MidiOutput
*/
class JUCE_API  MidiInput
{
public:

    /** Returns a list of the available midi input devices.

        You can open one of the devices by passing its index into the
        openDevice() method.

        @see getDefaultDeviceIndex, openDevice
    */
    static const StringArray getDevices();

    /** Returns the index of the default midi input device to use.

        This refers to the index in the list returned by getDevices().
    */
    static int getDefaultDeviceIndex();

    /** Tries to open one of the midi input devices.

        This will return a MidiInput object if it manages to open it. You can then
        call start() and stop() on this device, and delete it when no longer needed.

        If the device can't be opened, this will return a null pointer.

        @param deviceIndex  the index of a device from the list returned by getDevices()
        @param callback     the object that will receive the midi messages from this device.

        @see MidiInputCallback, getDevices
    */
    static MidiInput* openDevice (int deviceIndex,
                                  MidiInputCallback* callback);

#if JUCE_LINUX || DOXYGEN
    /** LINUX ONLY - This will try to create a new midi input device.

        This will attempt to create a new midi input device with the specified name,
        for other apps to connect to.

        Returns 0 if a device can't be created.

        @param deviceName   the name to use for the new device
        @param callback     the object that will receive the midi messages from this device.
    */
    static MidiInput* createNewDevice (const String& deviceName,
                                       MidiInputCallback* callback);
#endif

    /** Destructor. */
    virtual ~MidiInput();

    /** Returns the name of this device.
    */
    virtual const String getName() const throw()                    { return name; }

    /** Allows you to set a custom name for the device, in case you don't like the name
        it was given when created.
    */
    virtual void setName (const String& newName) throw()            { name = newName; }

    /** Starts the device running.

        After calling this, the device will start sending midi messages to the
        MidiInputCallback object that was specified when the openDevice() method
        was called.

        @see stop
    */
    virtual void start();

    /** Stops the device running.

        @see start
    */
    virtual void stop();

    juce_UseDebuggingNewOperator

protected:
    String name;
    void* internal;

    MidiInput (const String& name);
    MidiInput (const MidiInput&);
};

#endif   // __JUCE_MIDIINPUT_JUCEHEADER__
/********* End of inlined file: juce_MidiInput.h *********/

/**
    Collects incoming realtime MIDI messages and turns them into blocks suitable for
    processing by a block-based audio callback.

    The class can also be used as either a MidiKeyboardStateListener or a MidiInputCallback
    so it can easily use a midi input or keyboard component as its source.

    @see MidiMessage, MidiInput
*/
class JUCE_API  MidiMessageCollector    : public MidiKeyboardStateListener,
                                          public MidiInputCallback
{
public:

    /** Creates a MidiMessageCollector. */
    MidiMessageCollector();

    /** Destructor. */
    ~MidiMessageCollector();

    /** Clears any messages from the queue.

        You need to call this method before starting to use the collector, so that
        it knows the correct sample rate to use.
    */
    void reset (const double sampleRate);

    /** Takes an incoming real-time message and adds it to the queue.

        The message's timestamp is taken, and it will be ready for retrieval as part
        of the block returned by the next call to removeNextBlockOfMessages().

        This method is fully thread-safe when overlapping calls are made with
        removeNextBlockOfMessages().
    */
    void addMessageToQueue (const MidiMessage& message);

    /** Removes all the pending messages from the queue as a buffer.

        This will also correct the messages' timestamps to make sure they're in
        the range 0 to numSamples - 1.

        This call should be made regularly by something like an audio processing
        callback, because the time that it happens is used in calculating the
        midi event positions.

        This method is fully thread-safe when overlapping calls are made with
        addMessageToQueue().
    */
    void removeNextBlockOfMessages (MidiBuffer& destBuffer,
                                    const int numSamples);

    /** @internal */
    void handleNoteOn (MidiKeyboardState* source, int midiChannel, int midiNoteNumber, float velocity);
    /** @internal */
    void handleNoteOff (MidiKeyboardState* source, int midiChannel, int midiNoteNumber);
    /** @internal */
    void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message);

    juce_UseDebuggingNewOperator

private:
    double lastCallbackTime;
    CriticalSection midiCallbackLock;
    MidiBuffer incomingMessages;
    double sampleRate;

    MidiMessageCollector (const MidiMessageCollector&);
    const MidiMessageCollector& operator= (const MidiMessageCollector&);
};

#endif   // __JUCE_MIDIMESSAGECOLLECTOR_JUCEHEADER__
/********* End of inlined file: juce_MidiMessageCollector.h *********/

#endif
#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__

/********* Start of inlined file: juce_AudioDataConverters.h *********/
#ifndef __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
#define __JUCE_AUDIODATACONVERTERS_JUCEHEADER__

/**
    A set of routines to convert buffers of 32-bit floating point data to and from
    various integer formats.

*/
class JUCE_API  AudioDataConverters
{
public:

    static void convertFloatToInt16LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 2);
    static void convertFloatToInt16BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 2);

    static void convertFloatToInt24LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 3);
    static void convertFloatToInt24BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 3);

    static void convertFloatToInt32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4);
    static void convertFloatToInt32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4);

    static void convertFloatToFloat32LE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4);
    static void convertFloatToFloat32BE (const float* source, void* dest, int numSamples, const int destBytesPerSample = 4);

    static void convertInt16LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 2);
    static void convertInt16BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 2);

    static void convertInt24LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 3);
    static void convertInt24BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 3);

    static void convertInt32LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4);
    static void convertInt32BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4);

    static void convertFloat32LEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4);
    static void convertFloat32BEToFloat (const void* source, float* dest, int numSamples, const int srcBytesPerSample = 4);

    enum DataFormat
    {
        int16LE,
        int16BE,
        int24LE,
        int24BE,
        int32LE,
        int32BE,
        float32LE,
        float32BE,
    };

    static void convertFloatToFormat (const DataFormat destFormat,
                                      const float* source, void* dest, int numSamples);

    static void convertFormatToFloat (const DataFormat sourceFormat,
                                      const void* source, float* dest, int numSamples);

    static void interleaveSamples (const float** source, float* dest,
                                   const int numSamples, const int numChannels);

    static void deinterleaveSamples (const float* source, float** dest,
                                     const int numSamples, const int numChannels);
};

#endif   // __JUCE_AUDIODATACONVERTERS_JUCEHEADER__
/********* End of inlined file: juce_AudioDataConverters.h *********/

#endif
#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__

/********* Start of inlined file: juce_AudioSampleBuffer.h *********/
#ifndef __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__
#define __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__

class AudioFormatReader;
class AudioFormatWriter;

/**
    A multi-channel buffer of 32-bit floating point audio samples.

*/
class JUCE_API  AudioSampleBuffer
{
public:

    /** Creates a buffer with a specified number of channels and samples.

        The contents of the buffer will initially be undefined, so use clear() to
        set all the samples to zero.

        The buffer will allocate its memory internally, and this will be released
        when the buffer is deleted.
    */
    AudioSampleBuffer (const int numChannels,
                       const int numSamples) throw();

    /** Creates a buffer using a pre-allocated block of memory.

        Note that if the buffer is resized or its number of channels is changed, it
        will re-allocate memory internally and copy the existing data to this new area,
        so it will then stop directly addressing this memory.

        @param dataToReferTo    a pre-allocated array containing pointers to the data
                                for each channel that should be used by this buffer. The
                                buffer will only refer to this memory, it won't try to delete
                                it when the buffer is deleted or resized.
        @param numChannels      the number of channels to use - this must correspond to the
                                number of elements in the array passed in
        @param numSamples       the number of samples to use - this must correspond to the
                                size of the arrays passed in
    */
    AudioSampleBuffer (float** dataToReferTo,
                       const int numChannels,
                       const int numSamples) throw();

    /** Copies another buffer.

        This buffer will make its own copy of the other's data, unless the buffer was created
        using an external data buffer, in which case boths buffers will just point to the same
        shared block of data.
    */
    AudioSampleBuffer (const AudioSampleBuffer& other) throw();

    /** Copies another buffer onto this one.

        This buffer's size will be changed to that of the other buffer.
    */
    const AudioSampleBuffer& operator= (const AudioSampleBuffer& other) throw();

    /** Destructor.

        This will free any memory allocated by the buffer.
    */
    virtual ~AudioSampleBuffer() throw();

    /** Returns the number of channels of audio data that this buffer contains.

        @see getSampleData
    */
    int getNumChannels() const throw()      { return numChannels; }

    /** Returns the number of samples allocated in each of the buffer's channels.

        @see getSampleData
    */
    int getNumSamples() const throw()       { return size; }

    /** Returns a pointer one of the buffer's channels.

        For speed, this doesn't check whether the channel number is out of range,
        so be careful when using it!
    */
    float* getSampleData (const int channelNumber) const throw()
    {
        jassert (((unsigned int) channelNumber) < (unsigned int) numChannels);
        return channels [channelNumber];
    }

    /** Returns a pointer to a sample in one of the buffer's channels.

        For speed, this doesn't check whether the channel and sample number
        are out-of-range, so be careful when using it!
    */
    float* getSampleData (const int channelNumber,
                          const int sampleOffset) const throw()
    {
        jassert (((unsigned int) channelNumber) < (unsigned int) numChannels);
        jassert (((unsigned int) sampleOffset) < (unsigned int) size);
        return channels [channelNumber] + sampleOffset;
    }

    /** Returns an array of pointers to the channels in the buffer.

        Don't modify any of the pointers that are returned, and bear in mind that
        these will become invalid if the buffer is resized.
    */
    float** getArrayOfChannels() const throw()          { return channels; }

    /** Chages the buffer's size or number of channels.

        This can expand or contract the buffer's length, and add or remove channels.

        If keepExistingContent is true, it will try to preserve as much of the
        old data as it can in the new buffer.

        If clearExtraSpace is true, then any extra channels or space that is
        allocated will be also be cleared. If false, then this space is left
        uninitialised.

        If avoidReallocating is true, then changing the buffer's size won't reduce the
        amount of memory that is currently allocated (but it will still increase it if
        the new size is bigger than the amount it currently has). If this is false, then
        a new allocation will be done so that the buffer uses takes up the minimum amount
        of memory that it needs.
    */
    void setSize (const int newNumChannels,
                  const int newNumSamples,
                  const bool keepExistingContent = false,
                  const bool clearExtraSpace = false,
                  const bool avoidReallocating = false) throw();

    /** Makes this buffer point to a pre-allocated set of channel data arrays.

        There's also a constructor that lets you specify arrays like this, but this
        lets you change the channels dynamically.

        Note that if the buffer is resized or its number of channels is changed, it
        will re-allocate memory internally and copy the existing data to this new area,
        so it will then stop directly addressing this memory.

        @param dataToReferTo    a pre-allocated array containing pointers to the data
                                for each channel that should be used by this buffer. The
                                buffer will only refer to this memory, it won't try to delete
                                it when the buffer is deleted or resized.
        @param numChannels      the number of channels to use - this must correspond to the
                                number of elements in the array passed in
        @param numSamples       the number of samples to use - this must correspond to the
                                size of the arrays passed in
    */
    void setDataToReferTo (float** dataToReferTo,
                           const int numChannels,
                           const int numSamples) throw();

    /** Clears all the samples in all channels. */
    void clear() throw();

    /** Clears a specified region of all the channels.

        For speed, this doesn't check whether the channel and sample number
        are in-range, so be careful!
    */
    void clear (const int startSample,
                const int numSamples) throw();

    /** Clears a specified region of just one channel.

        For speed, this doesn't check whether the channel and sample number
        are in-range, so be careful!
    */
    void clear (const int channel,
                const int startSample,
                const int numSamples) throw();

    /** Applies a gain multiple to a region of one channel.

        For speed, this doesn't check whether the channel and sample number
        are in-range, so be careful!
    */
    void applyGain (const int channel,
                    const int startSample,
                    int numSamples,
                    const float gain) throw();

    /** Applies a gain multiple to a region of all the channels.

        For speed, this doesn't check whether the sample numbers
        are in-range, so be careful!
    */
    void applyGain (const int startSample,
                    const int numSamples,
                    const float gain) throw();

    /** Applies a range of gains to a region of a channel.

        The gain that is applied to each sample will vary from
        startGain on the first sample to endGain on the last Sample,
        so it can be used to do basic fades.

        For speed, this doesn't check whether the sample numbers
        are in-range, so be careful!
    */
    void applyGainRamp (const int channel,
                        const int startSample,
                        int numSamples,
                        float startGain,
                        float endGain) throw();

    /** Adds samples from another buffer to this one.

        @param destChannel          the channel within this buffer to add the samples to
        @param destStartSample      the start sample within this buffer's channel
        @param source               the source buffer to add from
        @param sourceChannel        the channel within the source buffer to read from
        @param sourceStartSample    the offset within the source buffer's channel to start reading samples from
        @param numSamples           the number of samples to process
        @param gainToApplyToSource  an optional gain to apply to the source samples before they are
                                    added to this buffer's samples

        @see copyFrom
    */
    void addFrom (const int destChannel,
                  const int destStartSample,
                  const AudioSampleBuffer& source,
                  const int sourceChannel,
                  const int sourceStartSample,
                  int numSamples,
                  const float gainToApplyToSource = 1.0f) throw();

    /** Adds samples from an array of floats to one of the channels.

        @param destChannel          the channel within this buffer to add the samples to
        @param destStartSample      the start sample within this buffer's channel
        @param source               the source data to use
        @param numSamples           the number of samples to process
        @param gainToApplyToSource  an optional gain to apply to the source samples before they are
                                    added to this buffer's samples

        @see copyFrom
    */
    void addFrom (const int destChannel,
                  const int destStartSample,
                  const float* source,
                  int numSamples,
                  const float gainToApplyToSource = 1.0f) throw();

    /** Adds samples from an array of floats, applying a gain ramp to them.

        @param destChannel          the channel within this buffer to add the samples to
        @param destStartSample      the start sample within this buffer's channel
        @param source               the source data to use
        @param numSamples           the number of samples to process
        @param startGain            the gain to apply to the first sample (this is multiplied with
                                    the source samples before they are added to this buffer)
        @param endGain              the gain to apply to the final sample. The gain is linearly
                                    interpolated between the first and last samples.
    */
    void addFromWithRamp (const int destChannel,
                          const int destStartSample,
                          const float* source,
                          int numSamples,
                          float startGain,
                          float endGain) throw();

    /** Copies samples from another buffer to this one.

        @param destChannel          the channel within this buffer to copy the samples to
        @param destStartSample      the start sample within this buffer's channel
        @param source               the source buffer to read from
        @param sourceChannel        the channel within the source buffer to read from
        @param sourceStartSample    the offset within the source buffer's channel to start reading samples from
        @param numSamples           the number of samples to process

        @see addFrom
    */
    void copyFrom (const int destChannel,
                   const int destStartSample,
                   const AudioSampleBuffer& source,
                   const int sourceChannel,
                   const int sourceStartSample,
                   int numSamples) throw();

    /** Copies samples from an array of floats into one of the channels.

        @param destChannel          the channel within this buffer to copy the samples to
        @param destStartSample      the start sample within this buffer's channel
        @param source               the source buffer to read from
        @param numSamples           the number of samples to process

        @see addFrom
    */
    void copyFrom (const int destChannel,
                   const int destStartSample,
                   const float* source,
                   int numSamples) throw();

    /** Copies samples from an array of floats into one of the channels, applying a gain to it.

        @param destChannel          the channel within this buffer to copy the samples to
        @param destStartSample      the start sample within this buffer's channel
        @param source               the source buffer to read from
        @param numSamples           the number of samples to process
        @param gain                 the gain to apply

        @see addFrom
    */
    void copyFrom (const int destChannel,
                   const int destStartSample,
                   const float* source,
                   int numSamples,
                   const float gain) throw();

    /** Copies samples from an array of floats into one of the channels, applying a gain ramp.

        @param destChannel          the channel within this buffer to copy the samples to
        @param destStartSample      the start sample within this buffer's channel
        @param source               the source buffer to read from
        @param numSamples           the number of samples to process
        @param startGain            the gain to apply to the first sample (this is multiplied with
                                    the source samples before they are copied to this buffer)
        @param endGain              the gain to apply to the final sample. The gain is linearly
                                    interpolated between the first and last samples.

        @see addFrom
    */
    void copyFromWithRamp (const int destChannel,
                           const int destStartSample,
                           const float* source,
                           int numSamples,
                           float startGain,
                           float endGain) throw();

    /** Finds the highest and lowest sample values in a given range.

        @param channel      the channel to read from
        @param startSample  the start sample within the channel
        @param numSamples   the number of samples to check
        @param minVal       on return, the lowest value that was found
        @param maxVal       on return, the highest value that was found
    */
    void findMinMax (const int channel,
                     const int startSample,
                     int numSamples,
                     float& minVal,
                     float& maxVal) const throw();

    /** Finds the highest absolute sample value within a region of a channel.
    */
    float getMagnitude (const int channel,
                        const int startSample,
                        const int numSamples) const throw();

    /** Finds the highest absolute sample value within a region on all channels.
    */
    float getMagnitude (const int startSample,
                        const int numSamples) const throw();

    /** Returns the root mean squared level for a region of a channel.
    */
    float getRMSLevel (const int channel,
                       const int startSample,
                       const int numSamples) const throw();

    /** Fills a section of the buffer using an AudioReader as its source.

        This will convert the reader's fixed- or floating-point data to
        the buffer's floating-point format, and will try to intelligently
        cope with mismatches between the number of channels in the reader
        and the buffer.

        @see writeToAudioWriter
    */
    void readFromAudioReader (AudioFormatReader* reader,
                              const int startSample,
                              const int numSamples,
                              const int readerStartSample,
                              const bool useReaderLeftChan,
                              const bool useReaderRightChan) throw();

    /** Writes a section of this buffer to an audio writer.

        This saves you having to mess about with channels or floating/fixed
        point conversion.

        @see readFromAudioReader
    */
    void writeToAudioWriter (AudioFormatWriter* writer,
                             const int startSample,
                             const int numSamples) const throw();

    juce_UseDebuggingNewOperator

private:
    int numChannels, size, allocatedBytes;
    float** channels;
    float* allocatedData;
    float* preallocatedChannelSpace [32];
};

#endif   // __JUCE_AUDIOSAMPLEBUFFER_JUCEHEADER__
/********* End of inlined file: juce_AudioSampleBuffer.h *********/

#endif
#ifndef __JUCE_IIRFILTER_JUCEHEADER__

/********* Start of inlined file: juce_IIRFilter.h *********/
#ifndef __JUCE_IIRFILTER_JUCEHEADER__
#define __JUCE_IIRFILTER_JUCEHEADER__

/**
    An IIR filter that can perform low, high, or band-pass filtering on an
    audio signal.

    @see IIRFilterAudioSource
*/
class JUCE_API  IIRFilter
{
public:

    /** Creates a filter.

        Initially the filter is inactive, so will have no effect on samples that
        you process with it. Use the appropriate method to turn it into the type
        of filter needed.
    */
    IIRFilter() throw();

    /** Creates a copy of another filter. */
    IIRFilter (const IIRFilter& other) throw();

    /** Destructor. */
    ~IIRFilter() throw();

    /** Resets the filter's processing pipeline, ready to start a new stream of data.

        Note that this clears the processing state, but the type of filter and
        its coefficients aren't changed. To put a filter into an inactive state, use
        the makeInactive() method.
    */
    void reset() throw();

    /** Performs the filter operation on the given set of samples.
    */
    void processSamples (float* const samples,
                         const int numSamples) throw();

    /** Processes a single sample, without any locking or checking.

        Use this if you need fast processing of a single value, but be aware that
        this isn't thread-safe in the way that processSamples() is.
    */
    float processSingleSampleRaw (const float sample) throw();

    /** Sets the filter up to act as a low-pass filter.
    */
    void makeLowPass (const double sampleRate,
                      const double frequency) throw();

    /** Sets the filter up to act as a high-pass filter.
    */
    void makeHighPass (const double sampleRate,
                       const double frequency) throw();

    /** Sets the filter up to act as a low-pass shelf filter with variable Q and gain.

        The gain is a scale factor that the low frequencies are multiplied by, so values
        greater than 1.0 will boost the low frequencies, values less than 1.0 will
        attenuate them.
    */
    void makeLowShelf (const double sampleRate,
                       const double cutOffFrequency,
                       const double Q,
                       const float gainFactor) throw();

    /** Sets the filter up to act as a high-pass shelf filter with variable Q and gain.

        The gain is a scale factor that the high frequencies are multiplied by, so values
        greater than 1.0 will boost the high frequencies, values less than 1.0 will
        attenuate them.
    */
    void makeHighShelf (const double sampleRate,
                        const double cutOffFrequency,
                        const double Q,
                        const float gainFactor) throw();

    /** Sets the filter up to act as a band pass filter centred around a
        frequency, with a variable Q and gain.

        The gain is a scale factor that the centre frequencies are multiplied by, so
        values greater than 1.0 will boost the centre frequencies, values less than
        1.0 will attenuate them.
    */
    void makeBandPass (const double sampleRate,
                       const double centreFrequency,
                       const double Q,
                       const float gainFactor) throw();

    /** Clears the filter's coefficients so that it becomes inactive.
    */
    void makeInactive() throw();

    /** Makes this filter duplicate the set-up of another one.
    */
    void copyCoefficientsFrom (const IIRFilter& other) throw();

    juce_UseDebuggingNewOperator

protected:
    CriticalSection processLock;

    void setCoefficients (double c1, double c2, double c3,
                          double c4, double c5, double c6) throw();

    bool active;
    float coefficients[6];
    float x1, x2, y1, y2;

    // (use the copyCoefficientsFrom() method instead of this operator)
    const IIRFilter& operator= (const IIRFilter&);
};

#endif   // __JUCE_IIRFILTER_JUCEHEADER__
/********* End of inlined file: juce_IIRFilter.h *********/

#endif
#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__

/********* Start of inlined file: juce_AudioPlayHead.h *********/
#ifndef __JUCE_AUDIOPLAYHEAD_JUCEHEADER__
#define __JUCE_AUDIOPLAYHEAD_JUCEHEADER__

/**
    A subclass of AudioPlayHead can supply information about the position and
    status of a moving play head during audio playback.

    One of these can be supplied to an AudioProcessor object so that it can find
    out about the position of the audio that it is rendering.

    @see AudioProcessor::setPlayHead, AudioProcessor::getPlayHead
*/
class JUCE_API  AudioPlayHead
{
protected:

    AudioPlayHead() {}

public:
    virtual ~AudioPlayHead() {}

    /** Frame rate types. */
    enum FrameRateType
    {
        fps24           = 0,
        fps25           = 1,
        fps2997         = 2,
        fps30           = 3,
        fps2997drop     = 4,
        fps30drop       = 5,
        fpsUnknown      = 99
    };

    /** This structure is filled-in by the AudioPlayHead::getCurrentPosition() method.
    */
    struct CurrentPositionInfo
    {
        /** The tempo in BPM */
        double bpm;

        /** Time signature numerator, e.g. the 3 of a 3/4 time sig */
        int timeSigNumerator;
        /** Time signature denominator, e.g. the 4 of a 3/4 time sig */
        int timeSigDenominator;

        /** The current play position, in seconds from the start of the edit. */
        double timeInSeconds;

        /** For timecode, the position of the start of the edit, in seconds from 00:00:00:00. */
        double editOriginTime;

        /** The current play position in pulses-per-quarter-note.

            This is the number of quarter notes since the edit start.
        */
        double ppqPosition;

        /** The position of the start of the last bar, in pulses-per-quarter-note.

            This is the number of quarter notes from the start of the edit to the
            start of the current bar.

            Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If
            it's not available, the value will be 0.
        */
        double ppqPositionOfLastBarStart;

        /** The video frame rate, if applicable. */
        FrameRateType frameRate;

        /** True if the transport is currently playing. */
        bool isPlaying;

        /** True if the transport is currently recording.

            (When isRecording is true, then isPlaying will also be true).
        */
        bool isRecording;
    };

    /** Fills-in the given structure with details about the transport's
        position at the start of the current processing block.
    */
    virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0;
};

#endif   // __JUCE_AUDIOPLAYHEAD_JUCEHEADER__
/********* End of inlined file: juce_AudioPlayHead.h *********/

#endif
#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__

/********* Start of inlined file: juce_AudioProcessor.h *********/
#ifndef __JUCE_AUDIOPROCESSOR_JUCEHEADER__
#define __JUCE_AUDIOPROCESSOR_JUCEHEADER__

/********* Start of inlined file: juce_AudioProcessorEditor.h *********/
#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__
#define __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__

class AudioProcessor;

/**
    Base class for the component that acts as the GUI for an AudioProcessor.

    Derive your editor component from this class, and create an instance of it
    by overriding the AudioProcessor::createEditor() method.

    @see AudioProcessor, GenericAudioProcessorEditor
*/
class JUCE_API  AudioProcessorEditor  : public Component
{
protected:

    /** Creates an editor for the specified processor.
    */
    AudioProcessorEditor (AudioProcessor* const owner);

public:
    /** Destructor. */
    ~AudioProcessorEditor();

    /** Returns a pointer to the processor that this editor represents. */
    AudioProcessor* getAudioProcessor() const throw()         { return owner; }

private:

    AudioProcessor* const owner;
};

#endif   // __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__
/********* End of inlined file: juce_AudioProcessorEditor.h *********/

/********* Start of inlined file: juce_AudioProcessorListener.h *********/
#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__
#define __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__

class AudioProcessor;

/**
    Base class for listeners that want to know about changes to an AudioProcessor.

    Use AudioProcessor::addListener() to register your listener with an AudioProcessor.

    @see AudioProcessor
*/
class JUCE_API  AudioProcessorListener
{
public:

    /** Destructor. */
    virtual ~AudioProcessorListener() {}

    /** Receives a callback when a parameter is changed.

        IMPORTANT NOTE: this will be called synchronously when a parameter changes, and
        many audio processors will change their parameter during their audio callback.
        This means that not only has your handler code got to be completely thread-safe,
        but it's also got to be VERY fast, and avoid blocking. If you need to handle
        this event on your message thread, use this callback to trigger an AsyncUpdater
        or ChangeBroadcaster which you can respond to on the message thread.
    */
    virtual void audioProcessorParameterChanged (AudioProcessor* processor,
                                                 int parameterIndex,
                                                 float newValue) = 0;

    /** Called to indicate that something else in the plugin has changed, like its
        program, number of parameters, etc.

        IMPORTANT NOTE: this will be called synchronously, and many audio processors will
        call it during their audio callback. This means that not only has your handler code
        got to be completely thread-safe, but it's also got to be VERY fast, and avoid
        blocking. If you need to handle this event on your message thread, use this callback
        to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
        message thread.
    */
    virtual void audioProcessorChanged (AudioProcessor* processor) = 0;

    /** Indicates that a parameter change gesture has started.

        E.g. if the user is dragging a slider, this would be called when they first
        press the mouse button, and audioProcessorParameterChangeGestureEnd would be
        called when they release it.

        IMPORTANT NOTE: this will be called synchronously, and many audio processors will
        call it during their audio callback. This means that not only has your handler code
        got to be completely thread-safe, but it's also got to be VERY fast, and avoid
        blocking. If you need to handle this event on your message thread, use this callback
        to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
        message thread.

        @see audioProcessorParameterChangeGestureEnd
    */
    virtual void audioProcessorParameterChangeGestureBegin (AudioProcessor* processor,
                                                            int parameterIndex);

    /** Indicates that a parameter change gesture has finished.

        E.g. if the user is dragging a slider, this would be called when they release
        the mouse button.

        IMPORTANT NOTE: this will be called synchronously, and many audio processors will
        call it during their audio callback. This means that not only has your handler code
        got to be completely thread-safe, but it's also got to be VERY fast, and avoid
        blocking. If you need to handle this event on your message thread, use this callback
        to trigger an AsyncUpdater or ChangeBroadcaster which you can respond to later on the
        message thread.

        @see audioPluginParameterChangeGestureStart
    */
    virtual void audioProcessorParameterChangeGestureEnd (AudioProcessor* processor,
                                                          int parameterIndex);
};

#endif   // __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__
/********* End of inlined file: juce_AudioProcessorListener.h *********/

/**
    Base class for audio processing filters or plugins.

    This is intended to act as a base class of audio filter that is general enough to
    be wrapped as a VST, AU, RTAS, etc, or used internally.

    It is also used by the plugin hosting code as the wrapper around an instance
    of a loaded plugin.

    Derive your filter class from this base class, and if you're building a plugin,
    you should implement a global function called createPluginFilter() which creates
    and returns a new instance of your subclass.
*/
class JUCE_API  AudioProcessor
{
protected:

    /** Constructor.

        You can also do your initialisation tasks in the initialiseFilterInfo()
        call, which will be made after this object has been created.
    */
    AudioProcessor();

public:
    /** Destructor. */
    virtual ~AudioProcessor();

    /** Returns the name of this processor.
    */
    virtual const String getName() const = 0;

    /** Called before playback starts, to let the filter prepare itself.

        The sample rate is the target sample rate, and will remain constant until
        playback stops.

        The estimatedSamplesPerBlock value is a HINT about the typical number of
        samples that will be processed for each callback, but isn't any kind
        of guarantee. The actual block sizes that the host uses may be different
        each time the callback happens, and may be more or less than this value.
    */
    virtual void prepareToPlay (double sampleRate,
                                int estimatedSamplesPerBlock) = 0;

    /** Called after playback has stopped, to let the filter free up any resources it
        no longer needs.
    */
    virtual void releaseResources() = 0;

    /** Renders the next block.

        When this method is called, the buffer contains a number of channels which is
        at least as great as the maximum number of input and output channels that
        this filter is using. It will be filled with the filter's input data and
        should be replaced with the filter's output.

        So for example if your filter has 2 input channels and 4 output channels, then
        the buffer will contain 4 channels, the first two being filled with the
        input data. Your filter should read these, do its processing, and replace
        the contents of all 4 channels with its output.

        Or if your filter has 5 inputs and 2 outputs, the buffer will have 5 channels,
        all filled with data, and your filter should overwrite the first 2 of these
        with its output. But be VERY careful not to write anything to the last 3
        channels, as these might be mapped to memory that the host assumes is read-only!

        Note that if you have more outputs than inputs, then only those channels that
        correspond to an input channel are guaranteed to contain sensible data - e.g.
        in the case of 2 inputs and 4 outputs, the first two channels contain the input,
        but the last two channels may contain garbage, so you should be careful not to
        let this pass through without being overwritten or cleared.

        Also note that the buffer may have more channels than are strictly necessary,
        but your should only read/write from the ones that your filter is supposed to
        be using.

        The number of samples in these buffers is NOT guaranteed to be the same for every
        callback, and may be more or less than the estimated value given to prepareToPlay().
        Your code must be able to cope with variable-sized blocks, or you're going to get
        clicks and crashes!

        If the filter is receiving a midi input, then the midiMessages array will be filled
        with the midi messages for this block. Each message's timestamp will indicate the
        message's time, as a number of samples from the start of the block.

        Any messages left in the midi buffer when this method has finished are assumed to
        be the filter's midi output. This means that your filter should be careful to
        clear any incoming messages from the array if it doesn't want them to be passed-on.

        Be very careful about what you do in this callback - it's going to be called by
        the audio thread, so any kind of interaction with the UI is absolutely
        out of the question. If you change a parameter in here and need to tell your UI to
        update itself, the best way is probably to inherit from a ChangeBroadcaster, let
        the UI components register as listeners, and then call sendChangeMessage() inside the
        processBlock() method to send out an asynchronous message. You could also use
        the AsyncUpdater class in a similar way.
    */
    virtual void processBlock (AudioSampleBuffer& buffer,
                               MidiBuffer& midiMessages) = 0;

    /** Returns the current AudioPlayHead object that should be used to find
        out the state and position of the playhead.

        You can call this from your processBlock() method, and use the AudioPlayHead
        object to get the details about the time of the start of the block currently
        being processed.

        If the host hasn't supplied a playhead object, this will return 0.
    */
    AudioPlayHead* getPlayHead() const throw()                { return playHead; }

    /** Returns the current sample rate.

        This can be called from your processBlock() method - it's not guaranteed
        to be valid at any other time, and may return 0 if it's unknown.
    */
    double getSampleRate() const throw()                      { return sampleRate; }

    /** Returns the current typical block size that is being used.

        This can be called from your processBlock() method - it's not guaranteed
        to be valid at any other time.

        Remember it's not the ONLY block size that may be used when calling
        processBlock, it's just the normal one. The actual block sizes used may be
        larger or smaller than this, and will vary between successive calls.
    */
    int getBlockSize() const throw()                          { return blockSize; }

    /** Returns the number of input channels that the host will be sending the filter.

        If writing a plugin, your JucePluginCharacteristics.h file should specify the
        number of channels that your filter would prefer to have, and this method lets
        you know how many the host is actually using.

        Note that this method is only valid during or after the prepareToPlay()
        method call. Until that point, the number of channels will be unknown.
    */
    int getNumInputChannels() const throw()                   { return numInputChannels; }

    /** Returns the number of output channels that the host will be sending the filter.

        If writing a plugin, your JucePluginCharacteristics.h file should specify the
        number of channels that your filter would prefer to have, and this method lets
        you know how many the host is actually using.

        Note that this method is only valid during or after the prepareToPlay()
        method call. Until that point, the number of channels will be unknown.
    */
    int getNumOutputChannels() const throw()                  { return numOutputChannels; }

    /** Returns the name of one of the input channels, as returned by the host.

        The host might not supply very useful names for channels, and this might be
        something like "1", "2", "left", "right", etc.
    */
    virtual const String getInputChannelName (const int channelIndex) const = 0;

    /** Returns the name of one of the output channels, as returned by the host.

        The host might not supply very useful names for channels, and this might be
        something like "1", "2", "left", "right", etc.
    */
    virtual const String getOutputChannelName (const int channelIndex) const = 0;

    /** Returns true if the specified channel is part of a stereo pair with its neighbour. */
    virtual bool isInputChannelStereoPair (int index) const = 0;

    /** Returns true if the specified channel is part of a stereo pair with its neighbour. */
    virtual bool isOutputChannelStereoPair (int index) const = 0;

    /** This returns the number of samples delay that the filter imposes on the audio
        passing through it.

        The host will call this to find the latency - the filter itself should set this value
        by calling setLatencySamples() as soon as it can during its initialisation.
    */
    int getLatencySamples() const throw()                             { return latencySamples; }

    /** The filter should call this to set the number of samples delay that it introduces.

        The filter should call this as soon as it can during initialisation, and can call it
        later if the value changes.
    */
    void setLatencySamples (const int newLatency);

    /** Returns true if the processor wants midi messages. */
    virtual bool acceptsMidi() const = 0;

    /** Returns true if the processor produces midi messages. */
    virtual bool producesMidi() const = 0;

    /** This returns a critical section that will automatically be locked while the host
        is calling the processBlock() method.

        Use it from your UI or other threads to lock access to variables that are used
        by the process callback, but obviously be careful not to keep it locked for
        too long, because that could cause stuttering playback. If you need to do something
        that'll take a long time and need the processing to stop while it happens, use the
        suspendProcessing() method instead.

        @see suspendProcessing
    */
    const CriticalSection& getCallbackLock() const throw()              { return callbackLock; }

    /** Enables and disables the processing callback.

        If you need to do something time-consuming on a thread and would like to make sure
        the audio processing callback doesn't happen until you've finished, use this
        to disable the callback and re-enable it again afterwards.

        E.g.
        @code
        void loadNewPatch()
        {
            suspendProcessing (true);

            ..do something that takes ages..

            suspendProcessing (false);
        }
        @endcode

        If the host tries to make an audio callback while processing is suspended, the
        filter will return an empty buffer, but won't block the audio thread like it would
        do if you use the getCallbackLock() critical section to synchronise access.

        If you're going to use this, your processBlock() method must call isSuspended() and
        check whether it's suspended or not. If it is, then it should skip doing any real
        processing, either emitting silence or passing the input through unchanged.

        @see getCallbackLock
    */
    void suspendProcessing (const bool shouldBeSuspended);

    /** Returns true if processing is currently suspended.
        @see suspendProcessing
    */
    bool isSuspended() const throw()                                    { return suspended; }

    /** A plugin can override this to be told when it should reset any playing voices.

        The default implementation does nothing, but a host may call this to tell the
        plugin that it should stop any tails or sounds that have been left running.
    */
    virtual void reset();

    /** Returns true if the processor is being run in an offline mode for rendering.

        If the processor is being run live on realtime signals, this returns false.
        If the mode is unknown, this will assume it's realtime and return false.

        This value may be unreliable until the prepareToPlay() method has been called,
        and could change each time prepareToPlay() is called.

        @see setNonRealtime()
    */
    bool isNonRealtime() const throw()                                  { return nonRealtime; }

    /** Called by the host to tell this processor whether it's being used in a non-realime
        capacity for offline rendering or bouncing.

        Whatever value is passed-in will be
    */
    void setNonRealtime (const bool isNonRealtime) throw();

    /** Creates the filter's UI.

        This can return 0 if you want a UI-less filter, in which case the host may create
        a generic UI that lets the user twiddle the parameters directly.

        If you do want to pass back a component, the component should be created and set to
        the correct size before returning it.

        Remember not to do anything silly like allowing your filter to keep a pointer to
        the component that gets created - it could be deleted later without any warning, which
        would make your pointer into a dangler. Use the getActiveEditor() method instead.

        The correct way to handle the connection between an editor component and its
        filter is to use something like a ChangeBroadcaster so that the editor can
        register itself as a listener, and be told when a change occurs. This lets them
        safely unregister themselves when they are deleted.

        Here are a few things to bear in mind when writing an editor:

        - Initially there won't be an editor, until the user opens one, or they might
          not open one at all. Your filter mustn't rely on it being there.
        - An editor object may be deleted and a replacement one created again at any time.
        - It's safe to assume that an editor will be deleted before its filter.
    */
    virtual AudioProcessorEditor* createEditor() = 0;

    /** Returns the active editor, if there is one.

        Bear in mind this can return 0, even if an editor has previously been
        opened.
    */
    AudioProcessorEditor* getActiveEditor() const throw()              { return activeEditor; }

    /** Returns the active editor, or if there isn't one, it will create one.

        This may call createEditor() internally to create the component.
    */
    AudioProcessorEditor* createEditorIfNeeded();

    /** This must return the correct value immediately after the object has been
        created, and mustn't change the number of parameters later.
    */
    virtual int getNumParameters() = 0;

    /** Returns the name of a particular parameter. */
    virtual const String getParameterName (int parameterIndex) = 0;

    /** Called by the host to find out the value of one of the filter's parameters.

        The host will expect the value returned to be between 0 and 1.0.

        This could be called quite frequently, so try to make your code efficient.
        It's also likely to be called by non-UI threads, so the code in here should
        be thread-aware.
    */
    virtual float getParameter (int parameterIndex) = 0;

    /** Returns the value of a parameter as a text string. */
    virtual const String getParameterText (int parameterIndex) = 0;

    /** The host will call this method to change the value of one of the filter's parameters.

        The host may call this at any time, including during the audio processing
        callback, so the filter has to process this very fast and avoid blocking.

        If you want to set the value of a parameter internally, e.g. from your
        editor component, then don't call this directly - instead, use the
        setParameterNotifyingHost() method, which will also send a message to
        the host telling it about the change. If the message isn't sent, the host
        won't be able to automate your parameters properly.

        The value passed will be between 0 and 1.0.
    */
    virtual void setParameter (int parameterIndex,
                               float newValue) = 0;

    /** Your filter can call this when it needs to change one of its parameters.

        This could happen when the editor or some other internal operation changes
        a parameter. This method will call the setParameter() method to change the
        value, and will then send a message to the host telling it about the change.

        Note that to make sure the host correctly handles automation, you should call
        the beginParameterChangeGesture() and endParameterChangeGesture() methods to
        tell the host when the user has started and stopped changing the parameter.
    */
    void setParameterNotifyingHost (int parameterIndex,
                                    float newValue);

    /** Returns true if the host can automate this parameter.

        By default, this returns true for all parameters.
    */
    virtual bool isParameterAutomatable (int parameterIndex) const;

    /** Should return true if this parameter is a "meta" parameter.

        A meta-parameter is a parameter that changes other params. It is used
        by some hosts (e.g. AudioUnit hosts).

        By default this returns false.
    */
    virtual bool isMetaParameter (int parameterIndex) const;

    /** Sends a signal to the host to tell it that the user is about to start changing this
        parameter.

        This allows the host to know when a parameter is actively being held by the user, and
        it may use this information to help it record automation.

        If you call this, it must be matched by a later call to endParameterChangeGesture().
    */
    void beginParameterChangeGesture (int parameterIndex);

    /** Tells the host that the user has finished changing this parameter.

        This allows the host to know when a parameter is actively being held by the user, and
        it may use this information to help it record automation.

        A call to this method must follow a call to beginParameterChangeGesture().
    */
    void endParameterChangeGesture (int parameterIndex);

    /** The filter can call this when something (apart from a parameter value) has changed.

        It sends a hint to the host that something like the program, number of parameters,
        etc, has changed, and that it should update itself.
    */
    void updateHostDisplay();

    /** Returns the number of preset programs the filter supports.

        The value returned must be valid as soon as this object is created, and
        must not change over its lifetime.

        This value shouldn't be less than 1.
    */
    virtual int getNumPrograms() = 0;

    /** Returns the number of the currently active program.
    */
    virtual int getCurrentProgram() = 0;

    /** Called by the host to change the current program.
    */
    virtual void setCurrentProgram (int index) = 0;

    /** Must return the name of a given program. */
    virtual const String getProgramName (int index) = 0;

    /** Called by the host to rename a program.
    */
    virtual void changeProgramName (int index, const String& newName) = 0;

    /** The host will call this method when it wants to save the filter's internal state.

        This must copy any info about the filter's state into the block of memory provided,
        so that the host can store this and later restore it using setStateInformation().

        Note that there's also a getCurrentProgramStateInformation() method, which only
        stores the current program, not the state of the entire filter.

        See also the helper function copyXmlToBinary() for storing settings as XML.

        @see getCurrentProgramStateInformation
    */
    virtual void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData) = 0;

    /** The host will call this method if it wants to save the state of just the filter's
        current program.

        Unlike getStateInformation, this should only return the current program's state.

        Not all hosts support this, and if you don't implement it, the base class
        method just calls getStateInformation() instead. If you do implement it, be
        sure to also implement getCurrentProgramStateInformation.

        @see getStateInformation, setCurrentProgramStateInformation
    */
    virtual void getCurrentProgramStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);

    /** This must restore the filter's state from a block of data previously created
        using getStateInformation().

        Note that there's also a setCurrentProgramStateInformation() method, which tries
        to restore just the current program, not the state of the entire filter.

        See also the helper function getXmlFromBinary() for loading settings as XML.

        @see setCurrentProgramStateInformation
    */
    virtual void setStateInformation (const void* data, int sizeInBytes) = 0;

    /** The host will call this method if it wants to restore the state of just the filter's
        current program.

        Not all hosts support this, and if you don't implement it, the base class
        method just calls setStateInformation() instead. If you do implement it, be
        sure to also implement getCurrentProgramStateInformation.

        @see setStateInformation, getCurrentProgramStateInformation
    */
    virtual void setCurrentProgramStateInformation (const void* data, int sizeInBytes);

    /** Adds a listener that will be called when an aspect of this processor changes. */
    void addListener (AudioProcessorListener* const newListener) throw();

    /** Removes a previously added listener. */
    void removeListener (AudioProcessorListener* const listenerToRemove) throw();

    /** Not for public use - this is called before deleting an editor component. */
    void editorBeingDeleted (AudioProcessorEditor* const editor) throw();

    /** Not for public use - this is called to initialise the processor. */
    void setPlayHead (AudioPlayHead* const newPlayHead) throw();

    /** Not for public use - this is called to initialise the processor before playing. */
    void setPlayConfigDetails (const int numIns, const int numOuts,
                               const double sampleRate,
                               const int blockSize) throw();

    juce_UseDebuggingNewOperator

protected:

    /** Helper function that just converts an xml element into a binary blob.

        Use this in your filter's getStateInformation() method if you want to
        store its state as xml.

        Then use getXmlFromBinary() to reverse this operation and retrieve the XML
        from a binary blob.
    */
    static void copyXmlToBinary (const XmlElement& xml,
                                 JUCE_NAMESPACE::MemoryBlock& destData);

    /** Retrieves an XML element that was stored as binary with the copyXmlToBinary() method.

        This might return 0 if the data's unsuitable or corrupted. Otherwise it will return
        an XmlElement object that the caller must delete when no longer needed.
    */
    static XmlElement* getXmlFromBinary (const void* data,
                                         const int sizeInBytes);

    /** @internal */
    AudioPlayHead* playHead;

    /** @internal */
    void sendParamChangeMessageToListeners (const int parameterIndex, const float newValue);

private:
    VoidArray listeners;
    AudioProcessorEditor* activeEditor;
    double sampleRate;
    int blockSize, numInputChannels, numOutputChannels, latencySamples;
    bool suspended, nonRealtime;
    CriticalSection callbackLock, listenerLock;

#ifdef JUCE_DEBUG
    BitArray changingParams;
#endif

    AudioProcessor (const AudioProcessor&);
    const AudioProcessor& operator= (const AudioProcessor&);
};

#endif   // __JUCE_AUDIOPROCESSOR_JUCEHEADER__
/********* End of inlined file: juce_AudioProcessor.h *********/

#endif
#ifndef __JUCE_AUDIOPROCESSOREDITOR_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOPROCESSORLISTENER_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__

/********* Start of inlined file: juce_AudioProcessorGraph.h *********/
#ifndef __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__
#define __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__

/********* Start of inlined file: juce_AudioPluginFormatManager.h *********/
#ifndef __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__
#define __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__

/********* Start of inlined file: juce_AudioPluginFormat.h *********/
#ifndef __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__
#define __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_AudioPluginInstance.h *********/
#ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__
#define __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__

/********* Start of inlined file: juce_PluginDescription.h *********/
#ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__
#define __JUCE_PLUGINDESCRIPTION_JUCEHEADER__

/**
    A small class to represent some facts about a particular type of plugin.

    This class is for storing and managing the details about a plugin without
    actually having to load an instance of it.

    A KnownPluginList contains a list of PluginDescription objects.

    @see KnownPluginList
*/
class JUCE_API  PluginDescription
{
public:

    PluginDescription() throw();
    PluginDescription (const PluginDescription& other) throw();
    const PluginDescription& operator= (const PluginDescription& other) throw();
    ~PluginDescription() throw();

    /** The name of the plugin. */
    String name;

    /** The plugin format, e.g. "VST", "AudioUnit", etc.
    */
    String pluginFormatName;

    /** A category, such as "Dynamics", "Reverbs", etc.
    */
    String category;

    /** The manufacturer. */
    String manufacturerName;

    /** The version. This string doesn't have any particular format. */
    String version;

    /** Either the file containing the plugin module, or some other unique way
        of identifying it.

        E.g. for an AU, this would be an ID string that the component manager
        could use to retrieve the plugin. For a VST, it's the file path.
    */
    String fileOrIdentifier;

    /** The last time the plugin file was changed.
        This is handy when scanning for new or changed plugins.
    */
    Time lastFileModTime;

    /** A unique ID for the plugin.

        Note that this might not be unique between formats, e.g. a VST and some
        other format might actually have the same id.

        @see createIdentifierString
    */
    int uid;

    /** True if the plugin identifies itself as a synthesiser. */
    bool isInstrument;

    /** The number of inputs. */
    int numInputChannels;

    /** The number of outputs. */
    int numOutputChannels;

    /** Returns true if the two descriptions refer the the same plugin.

        This isn't quite as simple as them just having the same file (because of
        shell plugins).
    */
    bool isDuplicateOf (const PluginDescription& other) const;

    /** Returns a string that can be saved and used to uniquely identify the
        plugin again.

        This contains less info than the XML encoding, and is independent of the
        plugin's file location, so can be used to store a plugin ID for use
        across different machines.
    */
    const String createIdentifierString() const throw();

    /** Creates an XML object containing these details.

        @see loadFromXml
    */
    XmlElement* createXml() const;

    /** Reloads the info in this structure from an XML record that was previously
        saved with createXML().

        Returns true if the XML was a valid plugin description.
    */
    bool loadFromXml (const XmlElement& xml);

    juce_UseDebuggingNewOperator
};

#endif   // __JUCE_PLUGINDESCRIPTION_JUCEHEADER__
/********* End of inlined file: juce_PluginDescription.h *********/

/**
    Base class for an active instance of a plugin.

    This derives from the AudioProcessor class, and adds some extra functionality
    that helps when wrapping dynamically loaded plugins.

    @see AudioProcessor, AudioPluginFormat
*/
class JUCE_API  AudioPluginInstance   : public AudioProcessor
{
public:

    /** Destructor.

        Make sure that you delete any UI components that belong to this plugin before
        deleting the plugin.
    */
    virtual ~AudioPluginInstance();

    /** Fills-in the appropriate parts of this plugin description object.
    */
    virtual void fillInPluginDescription (PluginDescription& description) const = 0;

    juce_UseDebuggingNewOperator

protected:
    AudioPluginInstance();

    AudioPluginInstance (const AudioPluginInstance&);
    const AudioPluginInstance& operator= (const AudioPluginInstance&);
};

#endif   // __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__
/********* End of inlined file: juce_AudioPluginInstance.h *********/

class PluginDescription;

/**
    The base class for a type of plugin format, such as VST, AudioUnit, LADSPA, etc.

    Use the static getNumFormats() and getFormat() calls to find the types
    of format that are available.
*/
class JUCE_API  AudioPluginFormat
{
public:

    /** Destructor. */
    virtual ~AudioPluginFormat();

    /** Returns the format name.

        E.g. "VST", "AudioUnit", etc.
    */
    virtual const String getName() const = 0;

    /** This tries to create descriptions for all the plugin types available in
        a binary module file.

        The file will be some kind of DLL or bundle.

        Normally there will only be one type returned, but some plugins
        (e.g. VST shells) can use a single DLL to create a set of different plugin
        subtypes, so in that case, each subtype is returned as a separate object.
    */
    virtual void findAllTypesForFile (OwnedArray <PluginDescription>& results,
                                      const String& fileOrIdentifier) = 0;

    /** Tries to recreate a type from a previously generated PluginDescription.

        @see PluginDescription::createInstance
    */
    virtual AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc) = 0;

    /** Should do a quick check to see if this file or directory might be a plugin of
        this format.

        This is for searching for potential files, so it shouldn't actually try to
        load the plugin or do anything time-consuming.
    */
    virtual bool fileMightContainThisPluginType (const String& fileOrIdentifier) = 0;

    /** Returns a readable version of the name of the plugin that this identifier refers to.
    */
    virtual const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier) = 0;

    /** Checks whether this plugin could possibly be loaded.

        It doesn't actually need to load it, just to check whether the file or component
        still exists.
    */
    virtual bool doesPluginStillExist (const PluginDescription& desc) = 0;

    /** Searches a suggested set of directories for any plugins in this format.

        The path might be ignored, e.g. by AUs, which are found by the OS rather
        than manually.
    */
    virtual const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch,
                                                     const bool recursive) = 0;

    /** Returns the typical places to look for this kind of plugin.

        Note that if this returns no paths, it means that the format can't be scanned-for
        (i.e. it's an internal format that doesn't live in files)
    */
    virtual const FileSearchPath getDefaultLocationsToSearch() = 0;

    juce_UseDebuggingNewOperator

protected:
    AudioPluginFormat() throw();

    AudioPluginFormat (const AudioPluginFormat&);
    const AudioPluginFormat& operator= (const AudioPluginFormat&);
};

#endif   // __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__
/********* End of inlined file: juce_AudioPluginFormat.h *********/

/**
    This maintains a list of known AudioPluginFormats.

    @see AudioPluginFormat
*/
class JUCE_API  AudioPluginFormatManager  : public DeletedAtShutdown
{
public:

    AudioPluginFormatManager() throw();

    /** Destructor. */
    ~AudioPluginFormatManager() throw();

    juce_DeclareSingleton_SingleThreaded (AudioPluginFormatManager, false);

    /** Adds any formats that it knows about, e.g. VST.
    */
    void addDefaultFormats();

    /** Returns the number of types of format that are available.

        Use getFormat() to get one of them.
    */
    int getNumFormats() throw();

    /** Returns one of the available formats.

        @see getNumFormats
    */
    AudioPluginFormat* getFormat (const int index) throw();

    /** Adds a format to the list.

        The object passed in will be owned and deleted by the manager.
    */
    void addFormat (AudioPluginFormat* const format) throw();

    /** Tries to load the type for this description, by trying all the formats
        that this manager knows about.

        The caller is responsible for deleting the object that is returned.

        If it can't load the plugin, it returns 0 and leaves a message in the
        errorMessage string.
    */
    AudioPluginInstance* createPluginInstance (const PluginDescription& description,
                                               String& errorMessage) const;

    /** Checks that the file or component for this plugin actually still exists.

        (This won't try to load the plugin)
    */
    bool doesPluginStillExist (const PluginDescription& description) const;

    juce_UseDebuggingNewOperator

private:
    OwnedArray <AudioPluginFormat> formats;

    AudioPluginFormatManager (const AudioPluginFormatManager&);
    const AudioPluginFormatManager& operator= (const AudioPluginFormatManager&);
};

#endif   // __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__
/********* End of inlined file: juce_AudioPluginFormatManager.h *********/

/********* Start of inlined file: juce_KnownPluginList.h *********/
#ifndef __JUCE_KNOWNPLUGINLIST_JUCEHEADER__
#define __JUCE_KNOWNPLUGINLIST_JUCEHEADER__

/********* Start of inlined file: juce_PopupMenu.h *********/
#ifndef __JUCE_POPUPMENU_JUCEHEADER__
#define __JUCE_POPUPMENU_JUCEHEADER__

/********* Start of inlined file: juce_PopupMenuCustomComponent.h *********/
#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__
#define __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__

/** A user-defined copmonent that can appear inside one of the rows of a popup menu.

    @see PopupMenu::addCustomItem
*/
class JUCE_API  PopupMenuCustomComponent  : public Component
{
public:
    /** Destructor. */
    ~PopupMenuCustomComponent();

    /** Chooses the size that this component would like to have.

        Note that the size which this method returns isn't necessarily the one that
        the menu will give it, as it will be stretched to fit the other items in
        the menu.
    */
    virtual void getIdealSize (int& idealWidth,
                               int& idealHeight) = 0;

    /** Dismisses the menu indicating that this item has been chosen.

        This will cause the menu to exit from its modal state, returning
        this item's id as the result.
    */
    void triggerMenuItem();

    /** Returns true if this item should be highlighted because the mouse is
        over it.

        You can call this method in your paint() method to find out whether
        to draw a highlight.
    */
    bool isItemHighlighted() const throw()                   { return isHighlighted; }

protected:
    /** Constructor.

        If isTriggeredAutomatically is true, then the menu will automatically detect
        a click on this component and use that to trigger it. If it's false, then it's
        up to your class to manually trigger the item if it wants to.
    */
    PopupMenuCustomComponent (const bool isTriggeredAutomatically = true);

private:
    friend class MenuItemInfo;
    friend class MenuItemComponent;
    friend class PopupMenuWindow;
    int refCount_;
    bool isHighlighted, isTriggeredAutomatically;

    PopupMenuCustomComponent (const PopupMenuCustomComponent&);
    const PopupMenuCustomComponent& operator= (const PopupMenuCustomComponent&);
};

#endif   // __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_PopupMenuCustomComponent.h *********/

/** Creates and displays a popup-menu.

    To show a popup-menu, you create one of these, add some items to it, then
    call its show() method, which returns the id of the item the user selects.

    E.g. @code
    void MyWidget::mouseDown (const MouseEvent& e)
    {
        PopupMenu m;
        m.addItem (1, "item 1");
        m.addItem (2, "item 2");

        const int result = m.show();

        if (result == 0)
        {
            // user dismissed the menu without picking anything
        }
        else if (result == 1)
        {
            // user picked item 1
        }
        else if (result == 2)
        {
            // user picked item 2
        }
    }
    @endcode

    Submenus are easy too: @code

    void MyWidget::mouseDown (const MouseEvent& e)
    {
        PopupMenu subMenu;
        subMenu.addItem (1, "item 1");
        subMenu.addItem (2, "item 2");

        PopupMenu mainMenu;
        mainMenu.addItem (3, "item 3");
        mainMenu.addSubMenu ("other choices", subMenu);

        const int result = m.show();

        ...etc
    }
    @endcode
*/
class JUCE_API  PopupMenu
{
public:

    /** Creates an empty popup menu. */
    PopupMenu() throw();

    /** Creates a copy of another menu. */
    PopupMenu (const PopupMenu& other) throw();

    /** Destructor. */
    ~PopupMenu() throw();

    /** Copies this menu from another one. */
    const PopupMenu& operator= (const PopupMenu& other) throw();

    /** Resets the menu, removing all its items. */
    void clear() throw();

    /** Appends a new text item for this menu to show.

        @param itemResultId     the number that will be returned from the show() method
                                if the user picks this item. The value should never be
                                zero, because that's used to indicate that the user didn't
                                select anything.
        @param itemText         the text to show.
        @param isActive         if false, the item will be shown 'greyed-out' and can't be
                                picked
        @param isTicked         if true, the item will be shown with a tick next to it
        @param iconToUse        if this is non-zero, it should be an image that will be
                                displayed to the left of the item. This method will take its
                                own copy of the image passed-in, so there's no need to keep
                                it hanging around.

        @see addSeparator, addColouredItem, addCustomItem, addSubMenu
    */
    void addItem (const int itemResultId,
                  const String& itemText,
                  const bool isActive = true,
                  const bool isTicked = false,
                  const Image* const iconToUse = 0) throw();

    /** Adds an item that represents one of the commands in a command manager object.

        @param commandManager       the manager to use to trigger the command and get information
                                    about it
        @param commandID            the ID of the command
        @param displayName          if this is non-empty, then this string will be used instead of
                                    the command's registered name
    */
    void addCommandItem (ApplicationCommandManager* commandManager,
                         const int commandID,
                         const String& displayName = String::empty) throw();

    /** Appends a text item with a special colour.

        This is the same as addItem(), but specifies a colour to use for the
        text, which will override the default colours that are used by the
        current look-and-feel. See addItem() for a description of the parameters.
    */
    void addColouredItem (const int itemResultId,
                          const String& itemText,
                          const Colour& itemTextColour,
                          const bool isActive = true,
                          const bool isTicked = false,
                          const Image* const iconToUse = 0) throw();

    /** Appends a custom menu item.

        This will add a user-defined component to use as a menu item. The component
        passed in will be deleted by this menu when it's no longer needed.

        @see PopupMenuCustomComponent
    */
    void addCustomItem (const int itemResultId,
                        PopupMenuCustomComponent* const customComponent) throw();

    /** Appends a custom menu item that can't be used to trigger a result.

        This will add a user-defined component to use as a menu item. Unlike the
        addCustomItem() method that takes a PopupMenuCustomComponent, this version
        can't trigger a result from it, so doesn't take a menu ID. It also doesn't
        delete the component when it's finished, so it's the caller's responsibility
        to manage the component that is passed-in.

        if triggerMenuItemAutomaticallyWhenClicked is true, the menu itself will handle
        detection of a mouse-click on your component, and use that to trigger the
        menu ID specified in itemResultId. If this is false, the menu item can't
        be triggered, so itemResultId is not used.

        @see PopupMenuCustomComponent
    */
    void addCustomItem (const int itemResultId,
                        Component* customComponent,
                        int idealWidth, int idealHeight,
                        const bool triggerMenuItemAutomaticallyWhenClicked) throw();

    /** Appends a sub-menu.

        If the menu that's passed in is empty, it will appear as an inactive item.
    */
    void addSubMenu (const String& subMenuName,
                     const PopupMenu& subMenu,
                     const bool isActive = true,
                     Image* const iconToUse = 0,
                     const bool isTicked = false) throw();

    /** Appends a separator to the menu, to help break it up into sections.

        The menu class is smart enough not to display separators at the top or bottom
        of the menu, and it will replace mutliple adjacent separators with a single
        one, so your code can be quite free and easy about adding these, and it'll
        always look ok.
    */
    void addSeparator() throw();

    /** Adds a non-clickable text item to the menu.

        This is a bold-font items which can be used as a header to separate the items
        into named groups.
    */
    void addSectionHeader (const String& title) throw();

    /** Returns the number of items that the menu currently contains.

        (This doesn't count separators).
    */
    int getNumItems() const throw();

    /** Returns true if the menu contains a command item that triggers the given command. */
    bool containsCommandItem (const int commandID) const throw();

    /** Returns true if the menu contains any items that can be used. */
    bool containsAnyActiveItems() const throw();

    /** Displays the menu and waits for the user to pick something.

        This will display the menu modally, and return the ID of the item that the
        user picks. If they click somewhere off the menu to get rid of it without
        choosing anything, this will return 0.

        The current location of the mouse will be used as the position to show the
        menu - to explicitly set the menu's position, use showAt() instead. Depending
        on where this point is on the screen, the menu will appear above, below or
        to the side of the point.

        @param itemIdThatMustBeVisible  if you set this to the ID of one of the menu items,
                                        then when the menu first appears, it will make sure
                                        that this item is visible. So if the menu has too many
                                        items to fit on the screen, it will be scrolled to a
                                        position where this item is visible.
        @param minimumWidth             a minimum width for the menu, in pixels. It may be wider
                                        than this if some items are too long to fit.
        @param maximumNumColumns        if there are too many items to fit on-screen in a single
                                        vertical column, the menu may be laid out as a series of
                                        columns - this is the maximum number allowed. To use the
                                        default value for this (probably about 7), you can pass
                                        in zero.
        @param standardItemHeight       if this is non-zero, it will be used as the standard
                                        height for menu items (apart from custom items)
        @see showAt
    */
    int show (const int itemIdThatMustBeVisible = 0,
              const int minimumWidth = 0,
              const int maximumNumColumns = 0,
              const int standardItemHeight = 0);

    /** Displays the menu at a specific location.

        This is the same as show(), but uses a specific location (in global screen
        co-ordinates) rather than the current mouse position.

        Note that the co-ordinates don't specify the top-left of the menu - they
        indicate a point of interest, and the menu will position itself nearby to
        this point, trying to keep it fully on-screen.

        @see show()
    */
    int showAt (const int screenX,
                const int screenY,
                const int itemIdThatMustBeVisible = 0,
                const int minimumWidth = 0,
                const int maximumNumColumns = 0,
                const int standardItemHeight = 0);

    /** Displays the menu as if it's attached to a component such as a button.

        This is similar to showAt(), but will position it next to the given component, e.g.
        so that the menu's edge is aligned with that of the component. This is intended for
        things like buttons that trigger a pop-up menu.
    */
    int showAt (Component* componentToAttachTo,
                const int itemIdThatMustBeVisible = 0,
                const int minimumWidth = 0,
                const int maximumNumColumns = 0,
                const int standardItemHeight = 0);

    /** Closes any menus that are currently open.

        This might be useful if you have a situation where your window is being closed
        by some means other than a user action, and you'd like to make sure that menus
        aren't left hanging around.
    */
    static void JUCE_CALLTYPE dismissAllActiveMenus() throw();

    /** Specifies a look-and-feel for the menu and any sub-menus that it has.

        This can be called before show() if you need a customised menu. Be careful
        not to delete the LookAndFeel object before the menu has been deleted.
    */
    void setLookAndFeel (LookAndFeel* const newLookAndFeel) throw();

    /** A set of colour IDs to use to change the colour of various aspects of the menu.

        These constants can be used either via the LookAndFeel::setColour()
        method for the look and feel that is set for this menu with setLookAndFeel()

        @see setLookAndFeel, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId             = 0x1000700,  /**< The colour to fill the menu's background with. */
        textColourId                   = 0x1000600,  /**< The colour for normal menu item text, (unless the
                                                          colour is specified when the item is added). */
        headerTextColourId             = 0x1000601,  /**< The colour for section header item text (see the
                                                          addSectionHeader() method). */
        highlightedBackgroundColourId  = 0x1000900,  /**< The colour to fill the background of the currently
                                                          highlighted menu item. */
        highlightedTextColourId        = 0x1000800,  /**< The colour to use for the text of the currently
                                                          highlighted item. */
    };

    /**
        Allows you to iterate through the items in a pop-up menu, and examine
        their properties.

        To use this, just create one and repeatedly call its next() method. When this
        returns true, all the member variables of the iterator are filled-out with
        information describing the menu item. When it returns false, the end of the
        list has been reached.
    */
    class JUCE_API  MenuItemIterator
    {
    public:

        /** Creates an iterator that will scan through the items in the specified
            menu.

            Be careful not to add any items to a menu while it is being iterated,
            or things could get out of step.
        */
        MenuItemIterator (const PopupMenu& menu) throw();

        /** Destructor. */
        ~MenuItemIterator() throw();

        /** Returns true if there is another item, and sets up all this object's
            member variables to reflect that item's properties.
        */
        bool next() throw();

        String itemName;
        const PopupMenu* subMenu;
        int itemId;
        bool isSeparator;
        bool isTicked;
        bool isEnabled;
        bool isCustomComponent;
        bool isSectionHeader;
        const Colour* customColour;
        const Image* customImage;
        ApplicationCommandManager* commandManager;

        juce_UseDebuggingNewOperator

    private:
        const PopupMenu& menu;
        int index;

        MenuItemIterator (const MenuItemIterator&);
        const MenuItemIterator& operator= (const MenuItemIterator&);
    };

    juce_UseDebuggingNewOperator

private:
    friend class PopupMenuWindow;
    friend class MenuItemIterator;
    VoidArray items;
    LookAndFeel* lookAndFeel;
    bool separatorPending;

    void addSeparatorIfPending();

    int showMenu (const int x, const int y, const int w, const int h,
                  const int itemIdThatMustBeVisible,
                  const int minimumWidth,
                  const int maximumNumColumns,
                  const int standardItemHeight,
                  const bool alignToRectangle,
                  Component* const componentAttachedTo) throw();

    friend class MenuBarComponent;
    Component* createMenuComponent (const int x, const int y, const int w, const int h,
                                    const int itemIdThatMustBeVisible,
                                    const int minimumWidth,
                                    const int maximumNumColumns,
                                    const int standardItemHeight,
                                    const bool alignToRectangle,
                                    Component* menuBarComponent,
                                    ApplicationCommandManager** managerOfChosenCommand,
                                    Component* const componentAttachedTo) throw();
};

#endif   // __JUCE_POPUPMENU_JUCEHEADER__
/********* End of inlined file: juce_PopupMenu.h *********/

/**
    Manages a list of plugin types.

    This can be easily edited, saved and loaded, and used to create instances of
    the plugin types in it.

    @see PluginListComponent
*/
class JUCE_API  KnownPluginList   : public ChangeBroadcaster
{
public:

    /** Creates an empty list.
    */
    KnownPluginList();

    /** Destructor. */
    ~KnownPluginList();

    /** Clears the list. */
    void clear();

    /** Returns the number of types currently in the list.
        @see getType
    */
    int getNumTypes() const throw()                                 { return types.size(); }

    /** Returns one of the types.
        @see getNumTypes
    */
    PluginDescription* getType (const int index) const throw()      { return types [index]; }

    /** Looks for a type in the list which comes from this file.
    */
    PluginDescription* getTypeForFile (const String& fileOrIdentifier) const throw();

    /** Looks for a type in the list which matches a plugin type ID.

        The identifierString parameter must have been created by
        PluginDescription::createIdentifierString().
    */
    PluginDescription* getTypeForIdentifierString (const String& identifierString) const throw();

    /** Adds a type manually from its description. */
    bool addType (const PluginDescription& type);

    /** Removes a type. */
    void removeType (const int index) throw();

    /** Looks for all types that can be loaded from a given file, and adds them
        to the list.

        If dontRescanIfAlreadyInList is true, then the file will only be loaded and
        re-tested if it's not already in the list, or if the file's modification
        time has changed since the list was created. If dontRescanIfAlreadyInList is
        false, the file will always be reloaded and tested.

        Returns true if any new types were added, and all the types found in this
        file (even if it was already known and hasn't been re-scanned) get returned
        in the array.
    */
    bool scanAndAddFile (const String& possiblePluginFileOrIdentifier,
                         const bool dontRescanIfAlreadyInList,
                         OwnedArray <PluginDescription>& typesFound,
                         AudioPluginFormat& formatToUse);

    /** Returns true if the specified file is already known about and if it
        hasn't been modified since our entry was created.
    */
    bool isListingUpToDate (const String& possiblePluginFileOrIdentifier) const throw();

    /** Scans and adds a bunch of files that might have been dragged-and-dropped.

        If any types are found in the files, their descriptions are returned in the array.
    */
    void scanAndAddDragAndDroppedFiles (const StringArray& filenames,
                                        OwnedArray <PluginDescription>& typesFound);

    /** Sort methods used to change the order of the plugins in the list.
    */
    enum SortMethod
    {
        defaultOrder = 0,
        sortAlphabetically,
        sortByCategory,
        sortByManufacturer,
        sortByFileSystemLocation
    };

    /** Adds all the plugin types to a popup menu so that the user can select one.

        Depending on the sort method, it may add sub-menus for categories,
        manufacturers, etc.

        Use getIndexChosenByMenu() to find out the type that was chosen.
    */
    void addToMenu (PopupMenu& menu,
                    const SortMethod sortMethod) const;

    /** Converts a menu item index that has been chosen into its index in this list.

        Returns -1 if it's not an ID that was used.

        @see addToMenu
    */
    int getIndexChosenByMenu (const int menuResultCode) const;

    /** Sorts the list. */
    void sort (const SortMethod method);

    /** Creates some XML that can be used to store the state of this list.
    */
    XmlElement* createXml() const;

    /** Recreates the state of this list from its stored XML format.
    */
    void recreateFromXml (const XmlElement& xml);

    juce_UseDebuggingNewOperator

private:
    OwnedArray <PluginDescription> types;

    KnownPluginList (const KnownPluginList&);
    const KnownPluginList& operator= (const KnownPluginList&);
};

#endif   // __JUCE_KNOWNPLUGINLIST_JUCEHEADER__
/********* End of inlined file: juce_KnownPluginList.h *********/

/**
    A type of AudioProcessor which plays back a graph of other AudioProcessors.

    Use one of these objects if you want to wire-up a set of AudioProcessors
    and play back the result.

    Processors can be added to the graph as "nodes" using addNode(), and once
    added, you can connect any of their input or output channels to other
    nodes using addConnection().

    To play back a graph through an audio device, you might want to use an
    AudioProcessorPlayer object.
*/
class JUCE_API  AudioProcessorGraph   : public AudioProcessor,
                                        public AsyncUpdater
{
public:

    /** Creates an empty graph.
    */
    AudioProcessorGraph();

    /** Destructor.

        Any processor objects that have been added to the graph will also be deleted.
    */
    ~AudioProcessorGraph();

    /** Represents one of the nodes, or processors, in an AudioProcessorGraph.

        To create a node, call AudioProcessorGraph::addNode().
    */
    class JUCE_API  Node   : public ReferenceCountedObject
    {
    public:
        /** Destructor.
        */
        ~Node();

        /** The ID number assigned to this node.

            This is assigned by the graph that owns it, and can't be changed.
        */
        const uint32 id;

        /** The actual processor object that this node represents.
        */
        AudioProcessor* const processor;

        /** A set of user-definable properties that are associated with this node.

            This can be used to attach values to the node for whatever purpose seems
            useful. For example, you might store an x and y position if your application
            is displaying the nodes on-screen.
        */
        PropertySet properties;

        /** A convenient typedef for referring to a pointer to a node object.
        */
        typedef ReferenceCountedObjectPtr <Node> Ptr;

        juce_UseDebuggingNewOperator

    private:
        friend class AudioProcessorGraph;

        bool isPrepared;

        Node (const uint32 id, AudioProcessor* const processor) throw();

        void prepare (const double sampleRate, const int blockSize, AudioProcessorGraph* const graph);
        void unprepare();

        Node (const Node&);
        const Node& operator= (const Node&);
    };

    /** Represents a connection between two channels of two nodes in an AudioProcessorGraph.

        To create a connection, use AudioProcessorGraph::addConnection().
    */
    struct JUCE_API  Connection
    {
    public:

        /** The ID number of the node which is the input source for this connection.
            @see AudioProcessorGraph::getNodeForId
        */
        uint32 sourceNodeId;

        /** The index of the output channel of the source node from which this
            connection takes its data.

            If this value is the special number AudioProcessorGraph::midiChannelIndex, then
            it is referring to the source node's midi output. Otherwise, it is the zero-based
            index of an audio output channel in the source node.
        */
        int sourceChannelIndex;

        /** The ID number of the node which is the destination for this connection.
            @see AudioProcessorGraph::getNodeForId
        */
        uint32 destNodeId;

        /** The index of the input channel of the destination node to which this
            connection delivers its data.

            If this value is the special number AudioProcessorGraph::midiChannelIndex, then
            it is referring to the destination node's midi input. Otherwise, it is the zero-based
            index of an audio input channel in the destination node.
        */
        int destChannelIndex;

        juce_UseDebuggingNewOperator

    private:
    };

    /** Deletes all nodes and connections from this graph.

        Any processor objects in the graph will be deleted.
    */
    void clear();

    /** Returns the number of nodes in the graph. */
    int getNumNodes() const throw()                                 { return nodes.size(); }

    /** Returns a pointer to one of the nodes in the graph.

        This will return 0 if the index is out of range.
        @see getNodeForId
    */
    Node* getNode (const int index) const throw()                   { return nodes [index]; }

    /** Searches the graph for a node with the given ID number and returns it.

        If no such node was found, this returns 0.
        @see getNode
    */
    Node* getNodeForId (const uint32 nodeId) const throw();

    /** Adds a node to the graph.

        This creates a new node in the graph, for the specified processor. Once you have
        added a processor to the graph, the graph owns it and will delete it later when
        it is no longer needed.

        The optional nodeId parameter lets you specify an ID to use for the node, but
        if the value is already in use, this new node will overwrite the old one.

        If this succeeds, it returns a pointer to the newly-created node.
    */
    Node* addNode (AudioProcessor* const newProcessor,
                   uint32 nodeId = 0);

    /** Deletes a node within the graph which has the specified ID.

        This will also delete any connections that are attached to this node.
    */
    bool removeNode (const uint32 nodeId);

    /** Returns the number of connections in the graph. */
    int getNumConnections() const throw()                               { return connections.size(); }

    /** Returns a pointer to one of the connections in the graph. */
    const Connection* getConnection (const int index) const throw()     { return connections [index]; }

    /** Searches for a connection between some specified channels.

        If no such connection is found, this returns 0.
    */
    const Connection* getConnectionBetween (const uint32 sourceNodeId,
                                            const int sourceChannelIndex,
                                            const uint32 destNodeId,
                                            const int destChannelIndex) const throw();

    /** Returns true if there is a connection between any of the channels of
        two specified nodes.
    */
    bool isConnected (const uint32 possibleSourceNodeId,
                      const uint32 possibleDestNodeId) const throw();

    /** Returns true if it would be legal to connect the specified points.
    */
    bool canConnect (const uint32 sourceNodeId, const int sourceChannelIndex,
                     const uint32 destNodeId, const int destChannelIndex) const throw();

    /** Attempts to connect two specified channels of two nodes.

        If this isn't allowed (e.g. because you're trying to connect a midi channel
        to an audio one or other such nonsense), then it'll return false.
    */
    bool addConnection (const uint32 sourceNodeId, const int sourceChannelIndex,
                        const uint32 destNodeId, const int destChannelIndex);

    /** Deletes the connection with the specified index.

        Returns true if a connection was actually deleted.
    */
    void removeConnection (const int index);

    /** Deletes any connection between two specified points.

        Returns true if a connection was actually deleted.
    */
    bool removeConnection (const uint32 sourceNodeId, const int sourceChannelIndex,
                           const uint32 destNodeId, const int destChannelIndex);

    /** Removes all connections from the specified node.
    */
    bool disconnectNode (const uint32 nodeId);

    /** Performs a sanity checks of all the connections.

        This might be useful if some of the processors are doing things like changing
        their channel counts, which could render some connections obsolete.
    */
    bool removeIllegalConnections();

    /** A special number that represents the midi channel of a node.

        This is used as a channel index value if you want to refer to the midi input
        or output instead of an audio channel.
    */
    static const int midiChannelIndex;

    /** A special type of AudioProcessor that can live inside an AudioProcessorGraph
        in order to use the audio that comes into and out of the graph itself.

        If you create an AudioGraphIOProcessor in "input" mode, it will act as a
        node in the graph which delivers the audio that is coming into the parent
        graph. This allows you to stream the data to other nodes and process the
        incoming audio.

        Likewise, one of these in "output" mode can be sent data which it will add to
        the sum of data being sent to the graph's output.

        @see AudioProcessorGraph
    */
    class JUCE_API  AudioGraphIOProcessor     : public AudioPluginInstance
    {
    public:
        /** Specifies the mode in which this processor will operate.
        */
        enum IODeviceType
        {
            audioInputNode,     /**< In this mode, the processor has output channels
                                     representing all the audio input channels that are
                                     coming into its parent audio graph. */
            audioOutputNode,    /**< In this mode, the processor has input channels
                                     representing all the audio output channels that are
                                     going out of its parent audio graph. */
            midiInputNode,      /**< In this mode, the processor has a midi output which
                                     delivers the same midi data that is arriving at its
                                     parent graph. */
            midiOutputNode      /**< In this mode, the processor has a midi input and
                                     any data sent to it will be passed out of the parent
                                     graph. */
        };

        /** Returns the mode of this processor. */
        IODeviceType getType() const throw()                        { return type; }

        /** Returns the parent graph to which this processor belongs, or 0 if it
            hasn't yet been added to one. */
        AudioProcessorGraph* getParentGraph() const throw()         { return graph; }

        /** True if this is an audio or midi input. */
        bool isInput() const throw();
        /** True if this is an audio or midi output. */
        bool isOutput() const throw();

        AudioGraphIOProcessor (const IODeviceType type);
        ~AudioGraphIOProcessor();

        const String getName() const;
        void fillInPluginDescription (PluginDescription& d) const;

        void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock);
        void releaseResources();
        void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);

        const String getInputChannelName (const int channelIndex) const;
        const String getOutputChannelName (const int channelIndex) const;
        bool isInputChannelStereoPair (int index) const;
        bool isOutputChannelStereoPair (int index) const;
        bool acceptsMidi() const;
        bool producesMidi() const;

        AudioProcessorEditor* createEditor();

        int getNumParameters();
        const String getParameterName (int);
        float getParameter (int);
        const String getParameterText (int);
        void setParameter (int, float);

        int getNumPrograms();
        int getCurrentProgram();
        void setCurrentProgram (int);
        const String getProgramName (int);
        void changeProgramName (int, const String&);

        void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);
        void setStateInformation (const void* data, int sizeInBytes);

        /** @internal */
        void setParentGraph (AudioProcessorGraph* const graph) throw();

        juce_UseDebuggingNewOperator

    private:
        const IODeviceType type;
        AudioProcessorGraph* graph;

        AudioGraphIOProcessor (const AudioGraphIOProcessor&);
        const AudioGraphIOProcessor& operator= (const AudioGraphIOProcessor&);
    };

    // AudioProcessor methods:

    const String getName() const;

    void prepareToPlay (double sampleRate, int estimatedSamplesPerBlock);
    void releaseResources();
    void processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages);

    const String getInputChannelName (const int channelIndex) const;
    const String getOutputChannelName (const int channelIndex) const;
    bool isInputChannelStereoPair (int index) const;
    bool isOutputChannelStereoPair (int index) const;

    bool acceptsMidi() const;
    bool producesMidi() const;

    AudioProcessorEditor* createEditor()            { return 0; }

    int getNumParameters()                          { return 0; }
    const String getParameterName (int)             { return String::empty; }
    float getParameter (int)                        { return 0; }
    const String getParameterText (int)             { return String::empty; }
    void setParameter (int, float)                  { }

    int getNumPrograms()                            { return 0; }
    int getCurrentProgram()                         { return 0; }
    void setCurrentProgram (int)                    { }
    const String getProgramName (int)               { return String::empty; }
    void changeProgramName (int, const String&)     { }

    void getStateInformation (JUCE_NAMESPACE::MemoryBlock& destData);
    void setStateInformation (const void* data, int sizeInBytes);

    /** @internal */
    void handleAsyncUpdate();

    juce_UseDebuggingNewOperator

private:
    ReferenceCountedArray <Node> nodes;
    OwnedArray <Connection> connections;
    int lastNodeId;
    AudioSampleBuffer renderingBuffers;
    OwnedArray <MidiBuffer> midiBuffers;

    CriticalSection renderLock;
    VoidArray renderingOps;

    friend class AudioGraphIOProcessor;
    AudioSampleBuffer* currentAudioInputBuffer;
    AudioSampleBuffer currentAudioOutputBuffer;
    MidiBuffer* currentMidiInputBuffer;
    MidiBuffer currentMidiOutputBuffer;

    void clearRenderingSequence();
    void buildRenderingSequence();

    bool isAnInputTo (const uint32 possibleInputId,
                      const uint32 possibleDestinationId,
                      const int recursionCheck) const throw();

    AudioProcessorGraph (const AudioProcessorGraph&);
    const AudioProcessorGraph& operator= (const AudioProcessorGraph&);
};

#endif   // __JUCE_AUDIOPROCESSORGRAPH_JUCEHEADER__
/********* End of inlined file: juce_AudioProcessorGraph.h *********/

#endif
#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__

/********* Start of inlined file: juce_AudioProcessorPlayer.h *********/
#ifndef __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__
#define __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__

/********* Start of inlined file: juce_AudioIODevice.h *********/
#ifndef __JUCE_AUDIOIODEVICE_JUCEHEADER__
#define __JUCE_AUDIOIODEVICE_JUCEHEADER__

class AudioIODevice;

/**
    One of these is passed to an AudioIODevice object to stream the audio data
    in and out.

    The AudioIODevice will repeatedly call this class's audioDeviceIOCallback()
    method on its own high-priority audio thread, when it needs to send or receive
    the next block of data.

    @see AudioIODevice, AudioDeviceManager
*/
class JUCE_API  AudioIODeviceCallback
{
public:
    /** Destructor. */
    virtual ~AudioIODeviceCallback()  {}

    /** Processes a block of incoming and outgoing audio data.

        The subclass's implementation should use the incoming audio for whatever
        purposes it needs to, and must fill all the output channels with the next
        block of output data before returning.

        The channel data is arranged with the same array indices as the channel name
        array returned by AudioIODevice::getOutputChannelNames(), but those channels
        that aren't specified in AudioIODevice::open() will have a null pointer for their
        associated channel, so remember to check for this.

        @param inputChannelData     a set of arrays containing the audio data for each
                                    incoming channel - this data is valid until the function
                                    returns. There will be one channel of data for each input
                                    channel that was enabled when the audio device was opened
                                    (see AudioIODevice::open())
        @param numInputChannels     the number of pointers to channel data in the
                                    inputChannelData array.
        @param outputChannelData    a set of arrays which need to be filled with the data
                                    that should be sent to each outgoing channel of the device.
                                    There will be one channel of data for each output channel
                                    that was enabled when the audio device was opened (see
                                    AudioIODevice::open())
                                    The initial contents of the array is undefined, so the
                                    callback function must fill all the channels with zeros if
                                    its output is silence. Failing to do this could cause quite
                                    an unpleasant noise!
        @param numOutputChannels    the number of pointers to channel data in the
                                    outputChannelData array.
        @param numSamples           the number of samples in each channel of the input and
                                    output arrays. The number of samples will depend on the
                                    audio device's buffer size and will usually remain constant,
                                    although this isn't guaranteed, so make sure your code can
                                    cope with reasonable changes in the buffer size from one
                                    callback to the next.
    */
    virtual void audioDeviceIOCallback (const float** inputChannelData,
                                        int numInputChannels,
                                        float** outputChannelData,
                                        int numOutputChannels,
                                        int numSamples) = 0;

    /** Called to indicate that the device is about to start calling back.

        This will be called just before the audio callbacks begin, either when this
        callback has just been added to an audio device, or after the device has been
        restarted because of a sample-rate or block-size change.

        You can use this opportunity to find out the sample rate and block size
        that the device is going to use by calling the AudioIODevice::getCurrentSampleRate()
        and AudioIODevice::getCurrentBufferSizeSamples() on the supplied pointer.

        @param device       the audio IO device that will be used to drive the callback.
                            Note that if you're going to store this this pointer, it is
                            only valid until the next time that audioDeviceStopped is called.
    */
    virtual void audioDeviceAboutToStart (AudioIODevice* device) = 0;

    /** Called to indicate that the device has stopped.
    */
    virtual void audioDeviceStopped() = 0;
};

/**
    Base class for an audio device with synchronised input and output channels.

    Subclasses of this are used to implement different protocols such as DirectSound,
    ASIO, CoreAudio, etc.

    To create one of these, you'll need to use the AudioIODeviceType class - see the
    documentation for that class for more info.

    For an easier way of managing audio devices and their settings, have a look at the
    AudioDeviceManager class.

    @see AudioIODeviceType, AudioDeviceManager
*/
class JUCE_API  AudioIODevice
{
public:
    /** Destructor. */
    virtual ~AudioIODevice();

    /** Returns the device's name, (as set in the constructor). */
    const String& getName() const throw()                           { return name; }

    /** Returns the type of the device.

        E.g. "CoreAudio", "ASIO", etc. - this comes from the AudioIODeviceType that created it.
    */
    const String& getTypeName() const throw()                       { return typeName; }

    /** Returns the names of all the available output channels on this device.
        To find out which of these are currently in use, call getActiveOutputChannels().
    */
    virtual const StringArray getOutputChannelNames() = 0;

    /** Returns the names of all the available input channels on this device.
        To find out which of these are currently in use, call getActiveInputChannels().
    */
    virtual const StringArray getInputChannelNames() = 0;

    /** Returns the number of sample-rates this device supports.

        To find out which rates are available on this device, use this method to
        find out how many there are, and getSampleRate() to get the rates.

        @see getSampleRate
    */
    virtual int getNumSampleRates() = 0;

    /** Returns one of the sample-rates this device supports.

        To find out which rates are available on this device, use getNumSampleRates() to
        find out how many there are, and getSampleRate() to get the individual rates.

        The sample rate is set by the open() method.

        (Note that for DirectSound some rates might not work, depending on combinations
        of i/o channels that are being opened).

        @see getNumSampleRates
    */
    virtual double getSampleRate (int index) = 0;

    /** Returns the number of sizes of buffer that are available.

        @see getBufferSizeSamples, getDefaultBufferSize
    */
    virtual int getNumBufferSizesAvailable() = 0;

    /** Returns one of the possible buffer-sizes.

        @param index    the index of the buffer-size to use, from 0 to getNumBufferSizesAvailable() - 1
        @returns a number of samples
        @see getNumBufferSizesAvailable, getDefaultBufferSize
    */
    virtual int getBufferSizeSamples (int index) = 0;

    /** Returns the default buffer-size to use.

        @returns a number of samples
        @see getNumBufferSizesAvailable, getBufferSizeSamples
    */
    virtual int getDefaultBufferSize() = 0;

    /** Tries to open the device ready to play.

        @param inputChannels        a BitArray in which a set bit indicates that the corresponding
                                    input channel should be enabled
        @param outputChannels       a BitArray in which a set bit indicates that the corresponding
                                    output channel should be enabled
        @param sampleRate           the sample rate to try to use - to find out which rates are
                                    available, see getNumSampleRates() and getSampleRate()
        @param bufferSizeSamples    the size of i/o buffer to use - to find out the available buffer
                                    sizes, see getNumBufferSizesAvailable() and getBufferSizeSamples()
        @returns    an error description if there's a problem, or an empty string if it succeeds in
                    opening the device
        @see close
    */
    virtual const String open (const BitArray& inputChannels,
                               const BitArray& outputChannels,
                               double sampleRate,
                               int bufferSizeSamples) = 0;

    /** Closes and releases the device if it's open. */
    virtual void close() = 0;

    /** Returns true if the device is still open.

        A device might spontaneously close itself if something goes wrong, so this checks if
        it's still open.
    */
    virtual bool isOpen() = 0;

    /** Starts the device actually playing.

        This must be called after the device has been opened.

        @param callback     the callback to use for streaming the data.
        @see AudioIODeviceCallback, open
    */
    virtual void start (AudioIODeviceCallback* callback) = 0;

    /** Stops the device playing.

        Once a device has been started, this will stop it. Any pending calls to the
        callback class will be flushed before this method returns.
    */
    virtual void stop() = 0;

    /** Returns true if the device is still calling back.

        The device might mysteriously stop, so this checks whether it's
        still playing.
    */
    virtual bool isPlaying() = 0;

    /** Returns the last error that happened if anything went wrong. */
    virtual const String getLastError() = 0;

    /** Returns the buffer size that the device is currently using.

        If the device isn't actually open, this value doesn't really mean much.
    */
    virtual int getCurrentBufferSizeSamples() = 0;

    /** Returns the sample rate that the device is currently using.

        If the device isn't actually open, this value doesn't really mean much.
    */
    virtual double getCurrentSampleRate() = 0;

    /** Returns the device's current physical bit-depth.

        If the device isn't actually open, this value doesn't really mean much.
    */
    virtual int getCurrentBitDepth() = 0;

    /** Returns a mask showing which of the available output channels are currently
        enabled.
        @see getOutputChannelNames
    */
    virtual const BitArray getActiveOutputChannels() const = 0;

    /** Returns a mask showing which of the available input channels are currently
        enabled.
        @see getInputChannelNames
    */
    virtual const BitArray getActiveInputChannels() const = 0;

    /** Returns the device's output latency.

        This is the delay in samples between a callback getting a block of data, and
        that data actually getting played.
    */
    virtual int getOutputLatencyInSamples() = 0;

    /** Returns the device's input latency.

        This is the delay in samples between some audio actually arriving at the soundcard,
        and the callback getting passed this block of data.
    */
    virtual int getInputLatencyInSamples() = 0;

    /** True if this device can show a pop-up control panel for editing its settings.

        This is generally just true of ASIO devices. If true, you can call showControlPanel()
        to display it.
    */
    virtual bool hasControlPanel() const;

    /** Shows a device-specific control panel if there is one.

        This should only be called for devices which return true from hasControlPanel().
    */
    virtual bool showControlPanel();

protected:
    /** Creates a device, setting its name and type member variables. */
    AudioIODevice (const String& deviceName,
                   const String& typeName);

    /** @internal */
    String name, typeName;
};

#endif   // __JUCE_AUDIOIODEVICE_JUCEHEADER__
/********* End of inlined file: juce_AudioIODevice.h *********/

/**
    An AudioIODeviceCallback object which streams audio through an AudioProcessor.

    To use one of these, just make it the callback used by your AudioIODevice, and
    give it a processor to use by calling setProcessor().

    It's also a MidiInputCallback, so you can connect it to both an audio and midi
    input to send both streams through the processor.

    @see AudioProcessor, AudioProcessorGraph
*/
class JUCE_API  AudioProcessorPlayer    : public AudioIODeviceCallback,
                                          public MidiInputCallback
{
public:

    /**
    */
    AudioProcessorPlayer();

    /** Destructor. */
    virtual ~AudioProcessorPlayer();

    /** Sets the processor that should be played.

        The processor that is passed in will not be deleted or owned by this object.
        To stop anything playing, pass in 0 to this method.
    */
    void setProcessor (AudioProcessor* const processorToPlay);

    /** Returns the current audio processor that is being played.
    */
    AudioProcessor* getCurrentProcessor() const throw()             { return processor; }

    /** Returns a midi message collector that you can pass midi messages to if you
        want them to be injected into the midi stream that is being sent to the
        processor.
    */
    MidiMessageCollector& getMidiMessageCollector() throw()         { return messageCollector; }

    /** @internal */
    void audioDeviceIOCallback (const float** inputChannelData,
                                int totalNumInputChannels,
                                float** outputChannelData,
                                int totalNumOutputChannels,
                                int numSamples);
    /** @internal */
    void audioDeviceAboutToStart (AudioIODevice* device);
    /** @internal */
    void audioDeviceStopped();
    /** @internal */
    void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message);

    juce_UseDebuggingNewOperator

private:
    AudioProcessor* processor;
    CriticalSection lock;
    double sampleRate;
    int blockSize;
    bool isPrepared;

    int numInputChans, numOutputChans;
    float* channels [128];
    AudioSampleBuffer tempBuffer;

    MidiBuffer incomingMidi;
    MidiMessageCollector messageCollector;

    AudioProcessorPlayer (const AudioProcessorPlayer&);
    const AudioProcessorPlayer& operator= (const AudioProcessorPlayer&);
};

#endif   // __JUCE_AUDIOPROCESSORPLAYER_JUCEHEADER__
/********* End of inlined file: juce_AudioProcessorPlayer.h *********/

#endif
#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__

/********* Start of inlined file: juce_GenericAudioProcessorEditor.h *********/
#ifndef __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__
#define __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__

/********* Start of inlined file: juce_PropertyPanel.h *********/
#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__
#define __JUCE_PROPERTYPANEL_JUCEHEADER__

/********* Start of inlined file: juce_PropertyComponent.h *********/
#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__
#define __JUCE_PROPERTYCOMPONENT_JUCEHEADER__

class EditableProperty;

/**
    A base class for a component that goes in a PropertyPanel and displays one of
    an item's properties.

    Subclasses of this are used to display a property in various forms, e.g. a
    ChoicePropertyComponent shows its value as a combo box; a SliderPropertyComponent
    shows its value as a slider; a TextPropertyComponent as a text box, etc.

    A subclass must implement the refresh() method which will be called to tell the
    component to update itself, and is also responsible for calling this it when the
    item that it refers to is changed.

    @see PropertyPanel, TextPropertyComponent, SliderPropertyComponent,
         ChoicePropertyComponent, ButtonPropertyComponent, BooleanPropertyComponent
*/
class JUCE_API  PropertyComponent  : public Component
{
public:

    /** Creates a PropertyComponent.

        @param propertyName     the name is stored as this component's name, and is
                                used as the name displayed next to this component in
                                a property panel
        @param preferredHeight  the height that the component should be given - some
                                items may need to be larger than a normal row height.
                                This value can also be set if a subclass changes the
                                preferredHeight member variable.
    */
    PropertyComponent (const String& propertyName,
                       const int preferredHeight = 25);

    /** Destructor. */
    ~PropertyComponent();

    /** Returns this item's preferred height.

        This value is specified either in the constructor or by a subclass changing the
        preferredHeight member variable.
    */
    int getPreferredHeight() const throw()                  { return preferredHeight; }

    /** Updates the property component if the item it refers to has changed.

        A subclass must implement this method, and other objects may call it to
        force it to refresh itself.

        The subclass should be economical in the amount of work is done, so for
        example it should check whether it really needs to do a repaint rather than
        just doing one every time this method is called, as it may be called when
        the value being displayed hasn't actually changed.
    */
    virtual void refresh() = 0;

    /** The default paint method fills the background and draws a label for the
        item's name.

        @see LookAndFeel::drawPropertyComponentBackground(), LookAndFeel::drawPropertyComponentLabel()
    */
    void paint (Graphics& g);

    /** The default resize method positions any child component to the right of this
        one, based on the look and feel's default label size.
    */
    void resized();

    /** By default, this just repaints the component. */
    void enablementChanged();

    juce_UseDebuggingNewOperator

protected:
    /** Used by the PropertyPanel to determine how high this component needs to be.

        A subclass can update this value in its constructor but shouldn't alter it later
        as changes won't necessarily be picked up.
    */
    int preferredHeight;
};

#endif   // __JUCE_PROPERTYCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_PropertyComponent.h *********/

/********* Start of inlined file: juce_Viewport.h *********/
#ifndef __JUCE_VIEWPORT_JUCEHEADER__
#define __JUCE_VIEWPORT_JUCEHEADER__

/********* Start of inlined file: juce_ScrollBar.h *********/
#ifndef __JUCE_SCROLLBAR_JUCEHEADER__
#define __JUCE_SCROLLBAR_JUCEHEADER__

/********* Start of inlined file: juce_Button.h *********/
#ifndef __JUCE_BUTTON_JUCEHEADER__
#define __JUCE_BUTTON_JUCEHEADER__

/********* Start of inlined file: juce_TooltipWindow.h *********/
#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__
#define __JUCE_TOOLTIPWINDOW_JUCEHEADER__

/********* Start of inlined file: juce_TooltipClient.h *********/
#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__
#define __JUCE_TOOLTIPCLIENT_JUCEHEADER__

/**
    Components that want to use pop-up tooltips should implement this interface.

    A TooltipWindow will wait for the mouse to hover over a component that
    implements the TooltipClient interface, and when it finds one, it will display
    the tooltip returned by its getTooltip() method.

    @see TooltipWindow, SettableTooltipClient
*/
class JUCE_API  TooltipClient
{
public:
    /** Destructor. */
    virtual ~TooltipClient()  {}

    /** Returns the string that this object wants to show as its tooltip. */
    virtual const String getTooltip() = 0;
};

/**
    An implementation of TooltipClient that stores the tooltip string and a method
    for changing it.

    This makes it easy to add a tooltip to a custom component, by simply adding this
    as a base class and calling setTooltip().

    Many of the Juce widgets already use this as a base class to implement their
    tooltips.

    @see TooltipClient, TooltipWindow
*/
class JUCE_API  SettableTooltipClient   : public TooltipClient
{
public:

    /** Destructor. */
    virtual ~SettableTooltipClient()                                {}

    virtual void setTooltip (const String& newTooltip)              { tooltipString = newTooltip; }

    virtual const String getTooltip()                               { return tooltipString; }

    juce_UseDebuggingNewOperator

protected:
    String tooltipString;
};

#endif   // __JUCE_TOOLTIPCLIENT_JUCEHEADER__
/********* End of inlined file: juce_TooltipClient.h *********/

/**
    A window that displays a pop-up tooltip when the mouse hovers over another component.

    To enable tooltips in your app, just create a single instance of a TooltipWindow
    object.

    The TooltipWindow object will then stay invisible, waiting until the mouse
    hovers for the specified length of time - it will then see if it's currently
    over a component which implements the TooltipClient interface, and if so,
    it will make itself visible to show the tooltip in the appropriate place.

    @see TooltipClient, SettableTooltipClient
*/
class JUCE_API  TooltipWindow  : public Component,
                                 private Timer
{
public:

    /** Creates a tooltip window.

        Make sure your app only creates one instance of this class, otherwise you'll
        get multiple overlaid tooltips appearing. The window will initially be invisible
        and will make itself visible when it needs to display a tip.

        To change the style of tooltips, see the LookAndFeel class for its tooltip
        methods.

        @param parentComponent  if set to 0, the TooltipWindow will appear on the desktop,
                                otherwise the tooltip will be added to the given parent
                                component.
        @param millisecondsBeforeTipAppears     the time for which the mouse has to stay still
                                                before a tooltip will be shown

        @see TooltipClient, LookAndFeel::drawTooltip, LookAndFeel::getTooltipSize
    */
    TooltipWindow (Component* parentComponent = 0,
                   const int millisecondsBeforeTipAppears = 700);

    /** Destructor. */
    ~TooltipWindow();

    /** Changes the time before the tip appears.
        This lets you change the value that was set in the constructor.
    */
    void setMillisecondsBeforeTipAppears (const int newTimeMs = 700) throw();

    /** A set of colour IDs to use to change the colour of various aspects of the tooltip.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId      = 0x1001b00,    /**< The colour to fill the background with. */
        textColourId            = 0x1001c00,    /**< The colour to use for the text. */
        outlineColourId         = 0x1001c10     /**< The colour to use to draw an outline around the tooltip. */
    };

    juce_UseDebuggingNewOperator

private:

    int millisecondsBeforeTipAppears;
    int mouseX, mouseY, mouseClicks;
    unsigned int lastCompChangeTime, lastHideTime;
    Component* lastComponentUnderMouse;
    bool changedCompsSinceShown;
    String tipShowing, lastTipUnderMouse;

    void paint (Graphics& g);
    void mouseEnter (const MouseEvent& e);
    void timerCallback();

    static const String getTipFor (Component* const c);
    void showFor (Component* const c, const String& tip);
    void hide();

    TooltipWindow (const TooltipWindow&);
    const TooltipWindow& operator= (const TooltipWindow&);
};

#endif   // __JUCE_TOOLTIPWINDOW_JUCEHEADER__
/********* End of inlined file: juce_TooltipWindow.h *********/

class Button;

/**
    Used to receive callbacks when a button is clicked.

    @see Button::addButtonListener, Button::removeButtonListener
*/
class JUCE_API  ButtonListener
{
public:
    /** Destructor. */
    virtual ~ButtonListener()                               {}

    /** Called when the button is clicked. */
    virtual void buttonClicked (Button* button) = 0;

    /** Called when the button's state changes. */
    virtual void buttonStateChanged (Button*)               {}
};

/**
    A base class for buttons.

    This contains all the logic for button behaviours such as enabling/disabling,
    responding to shortcut keystrokes, auto-repeating when held down, toggle-buttons
    and radio groups, etc.

    @see TextButton, DrawableButton, ToggleButton
*/
class JUCE_API  Button  : public Component,
                          public SettableTooltipClient,
                          public ApplicationCommandManagerListener,
                          private KeyListener
{
protected:

    /** Creates a button.

        @param buttonName           the text to put in the button (the component's name is also
                                    initially set to this string, but these can be changed later
                                    using the setName() and setButtonText() methods)
    */
    Button (const String& buttonName);

public:
    /** Destructor. */
    virtual ~Button();

    /** Changes the button's text.

        @see getButtonText
    */
    void setButtonText (const String& newText) throw();

    /** Returns the text displayed in the button.

        @see setButtonText
    */
    const String getButtonText() const throw()                  { return text; }

    /** Returns true if the button is currently being held down by the mouse.

        @see isOver
    */
    bool isDown() const throw();

    /** Returns true if the mouse is currently over the button.

        This will be also be true if the mouse is being held down.

        @see isDown
    */
    bool isOver() const throw();

    /** A button has an on/off state associated with it, and this changes that.

        By default buttons are 'off' and for simple buttons that you click to perform
        an action you won't change this. Toggle buttons, however will want to
        change their state when turned on or off.

        @param shouldBeOn               whether to set the button's toggle state to be on or
                                        off. If it's a member of a button group, this will
                                        always try to turn it on, and to turn off any other
                                        buttons in the group
        @param sendChangeNotification   if true, a callback will be made to clicked(); if false
                                        the button will be repainted but no notification will
                                        be sent
        @see getToggleState, setRadioGroupId
    */
    void setToggleState (const bool shouldBeOn,
                         const bool sendChangeNotification);

    /** Returns true if the button in 'on'.

        By default buttons are 'off' and for simple buttons that you click to perform
        an action you won't change this. Toggle buttons, however will want to
        change their state when turned on or off.

        @see setToggleState
    */
    bool getToggleState() const throw()                         { return isOn; }

    /** This tells the button to automatically flip the toggle state when
        the button is clicked.

        If set to true, then before the clicked() callback occurs, the toggle-state
        of the button is flipped.
    */
    void setClickingTogglesState (const bool shouldToggle) throw();

    /** Returns true if this button is set to be an automatic toggle-button.

        This returns the last value that was passed to setClickingTogglesState().
    */
    bool getClickingTogglesState() const throw();

    /** Enables the button to act as a member of a mutually-exclusive group
        of 'radio buttons'.

        If the group ID is set to a non-zero number, then this button will
        act as part of a group of buttons with the same ID, only one of
        which can be 'on' at the same time. Note that when it's part of
        a group, clicking a toggle-button that's 'on' won't turn it off.

        To find other buttons with the same ID, this button will search through
        its sibling components for ToggleButtons, so all the buttons for a
        particular group must be placed inside the same parent component.

        Set the group ID back to zero if you want it to act as a normal toggle
        button again.

        @see getRadioGroupId
    */
    void setRadioGroupId (const int newGroupId);

    /** Returns the ID of the group to which this button belongs.

        (See setRadioGroupId() for an explanation of this).
    */
    int getRadioGroupId() const throw()                         { return radioGroupId; }

    /** Registers a listener to receive events when this button's state changes.

        If the listener is already registered, this will not register it again.

        @see removeButtonListener
    */
    void addButtonListener (ButtonListener* const newListener) throw();

    /** Removes a previously-registered button listener

        @see addButtonListener
    */
    void removeButtonListener (ButtonListener* const listener) throw();

    /** Causes the button to act as if it's been clicked.

        This will asynchronously make the button draw itself going down and up, and
        will then call back the clicked() method as if mouse was clicked on it.

        @see clicked
    */
    virtual void triggerClick();

    /** Sets a command ID for this button to automatically invoke when it's clicked.

        When the button is pressed, it will use the given manager to trigger the
        command ID.

        Obviously be careful that the ApplicationCommandManager doesn't get deleted
        before this button is. To disable the command triggering, call this method and
        pass 0 for the parameters.

        If generateTooltip is true, then the button's tooltip will be automatically
        generated based on the name of this command and its current shortcut key.

        @see addShortcut, getCommandID
    */
    void setCommandToTrigger (ApplicationCommandManager* commandManagerToUse,
                              const int commandID,
                              const bool generateTooltip);

    /** Returns the command ID that was set by setCommandToTrigger().
    */
    int getCommandID() const throw()                { return commandID; }

    /** Assigns a shortcut key to trigger the button.

        The button registers itself with its top-level parent component for keypresses.

        Note that a different way of linking buttons to keypresses is by using the
        setKeyPressToTrigger() method to invoke a command - the difference being that
        setting a shortcut allows the button to be temporarily linked to a keypress
        only while it's on-screen.

        @see clearShortcuts
    */
    void addShortcut (const KeyPress& key);

    /** Removes all key shortcuts that had been set for this button.

        @see addShortcut
    */
    void clearShortcuts();

    /** Returns true if the given keypress is a shortcut for this button.

        @see addShortcut
    */
    bool isRegisteredForShortcut (const KeyPress& key) const throw();

    /** Sets an auto-repeat speed for the button when it is held down.

        (Auto-repeat is disabled by default).

        @param initialDelayInMillisecs      how long to wait after the mouse is pressed before
                                            triggering the next click. If this is zero, auto-repeat
                                            is disabled
        @param repeatDelayInMillisecs       the frequently subsequent repeated clicks should be
                                            triggered
        @param minimumDelayInMillisecs      if this is greater than 0, the auto-repeat speed will
                                            get faster, the longer the button is held down, up to the
                                            minimum interval specified here
    */
    void setRepeatSpeed (const int initialDelayInMillisecs,
                         const int repeatDelayInMillisecs,
                         const int minimumDelayInMillisecs = -1) throw();

    /** Sets whether the button click should happen when the mouse is pressed or released.

        By default the button is only considered to have been clicked when the mouse is
        released, but setting this to true will make it call the clicked() method as soon
        as the button is pressed.

        This is useful if the button is being used to show a pop-up menu, as it allows
        the click to be used as a drag onto the menu.
    */
    void setTriggeredOnMouseDown (const bool isTriggeredOnMouseDown) throw();

    /** Returns the number of milliseconds since the last time the button
        went into the 'down' state.
    */
    uint32 getMillisecondsSinceButtonDown() const throw();

    /** (overridden from Component to do special stuff). */
    void setVisible (bool shouldBeVisible);

    /** Sets the tooltip for this button.

        @see TooltipClient, TooltipWindow
    */
    void setTooltip (const String& newTooltip);

    // (implementation of the TooltipClient method)
    const String getTooltip();

    /** A combination of these flags are used by setConnectedEdges().
    */
    enum ConnectedEdgeFlags
    {
        ConnectedOnLeft = 1,
        ConnectedOnRight = 2,
        ConnectedOnTop = 4,
        ConnectedOnBottom = 8
    };

    /** Hints about which edges of the button might be connected to adjoining buttons.

        The value passed in is a bitwise combination of any of the values in the
        ConnectedEdgeFlags enum.

        E.g. if you are placing two buttons adjacent to each other, you could use this to
        indicate which edges are touching, and the LookAndFeel might choose to drawn them
        without rounded corners on the edges that connect. It's only a hint, so the
        LookAndFeel can choose to ignore it if it's not relevent for this type of
        button.
    */
    void setConnectedEdges (const int connectedEdgeFlags) throw();

    /** Returns the set of flags passed into setConnectedEdges(). */
    int getConnectedEdgeFlags() const throw()                   { return connectedEdgeFlags; }

    /** Indicates whether the button adjoins another one on its left edge.
        @see setConnectedEdges
    */
    bool isConnectedOnLeft() const throw()                      { return (connectedEdgeFlags & ConnectedOnLeft) != 0; }

    /** Indicates whether the button adjoins another one on its right edge.
        @see setConnectedEdges
    */
    bool isConnectedOnRight() const throw()                     { return (connectedEdgeFlags & ConnectedOnRight) != 0; }

    /** Indicates whether the button adjoins another one on its top edge.
        @see setConnectedEdges
    */
    bool isConnectedOnTop() const throw()                       { return (connectedEdgeFlags & ConnectedOnTop) != 0; }

    /** Indicates whether the button adjoins another one on its bottom edge.
        @see setConnectedEdges
    */
    bool isConnectedOnBottom() const throw()                    { return (connectedEdgeFlags & ConnectedOnBottom) != 0; }

    /** Used by setState(). */
    enum ButtonState
    {
        buttonNormal,
        buttonOver,
        buttonDown
    };

    /** Can be used to force the button into a particular state.

        This only changes the button's appearance, it won't trigger a click, or stop any mouse-clicks
        from happening.

        The state that you set here will only last until it is automatically changed when the mouse
        enters or exits the button, or the mouse-button is pressed or released.
    */
    void setState (const ButtonState newState);

    juce_UseDebuggingNewOperator

protected:

    /** This method is called when the button has been clicked.

        Subclasses can override this to perform whatever they actions they need
        to do.

        Alternatively, a ButtonListener can be added to the button, and these listeners
        will be called when the click occurs.

        @see triggerClick
    */
    virtual void clicked();

    /** This method is called when the button has been clicked.

        By default it just calls clicked(), but you might want to override it to handle
        things like clicking when a modifier key is pressed, etc.

        @see ModifierKeys
    */
    virtual void clicked (const ModifierKeys& modifiers);

    /** Subclasses should override this to actually paint the button's contents.

        It's better to use this than the paint method, because it gives you information
        about the over/down state of the button.

        @param g                    the graphics context to use
        @param isMouseOverButton    true if the button is either in the 'over' or
                                    'down' state
        @param isButtonDown         true if the button should be drawn in the 'down' position
    */
    virtual void paintButton (Graphics& g,
                              bool isMouseOverButton,
                              bool isButtonDown) = 0;

    /** Called when the button's up/down/over state changes.

        Subclasses can override this if they need to do something special when the button
        goes up or down.

        @see isDown, isOver
    */
    virtual void buttonStateChanged();

    /** @internal */
    virtual void internalClickCallback (const ModifierKeys& modifiers);
    /** @internal */
    void handleCommandMessage (int commandId);
    /** @internal */
    void mouseEnter (const MouseEvent& e);
    /** @internal */
    void mouseExit (const MouseEvent& e);
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    void mouseUp (const MouseEvent& e);
    /** @internal */
    bool keyPressed (const KeyPress& key);
    /** @internal */
    bool keyPressed (const KeyPress& key, Component* originatingComponent);
    /** @internal */
    bool keyStateChanged (const bool isKeyDown, Component* originatingComponent);
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void parentHierarchyChanged();
    /** @internal */
    void focusGained (FocusChangeType cause);
    /** @internal */
    void focusLost (FocusChangeType cause);
    /** @internal */
    void enablementChanged();
    /** @internal */
    void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo&);
    /** @internal */
    void applicationCommandListChanged();

private:

    Array <KeyPress> shortcuts;
    Component* keySource;
    String text;
    SortedSet <void*> buttonListeners;

    friend class InternalButtonRepeatTimer;
    Timer* repeatTimer;
    uint32 buttonPressTime, lastTimeCallbackTime;
    ApplicationCommandManager* commandManagerToUse;
    int autoRepeatDelay, autoRepeatSpeed, autoRepeatMinimumDelay;
    int radioGroupId, commandID, connectedEdgeFlags;
    ButtonState buttonState;

    bool isOn : 1;
    bool clickTogglesState : 1;
    bool needsToRelease : 1;
    bool needsRepainting : 1;
    bool isKeyDown : 1;
    bool triggerOnMouseDown : 1;
    bool generateTooltip : 1;

    void repeatTimerCallback() throw();
    Timer& getRepeatTimer() throw();

    ButtonState updateState (const MouseEvent* const e) throw();
    bool isShortcutPressed() const throw();
    void turnOffOtherButtonsInGroup (const bool sendChangeNotification);

    void flashButtonState() throw();
    void sendClickMessage (const ModifierKeys& modifiers);
    void sendStateMessage();

    Button (const Button&);
    const Button& operator= (const Button&);
};

#endif   // __JUCE_BUTTON_JUCEHEADER__
/********* End of inlined file: juce_Button.h *********/

class ScrollBar;

/**
    A class for receiving events from a ScrollBar.

    You can register a ScrollBarListener with a ScrollBar using the ScrollBar::addListener()
    method, and it will be called when the bar's position changes.

    @see ScrollBar::addListener, ScrollBar::removeListener
*/
class JUCE_API  ScrollBarListener
{
public:
    /** Destructor. */
    virtual ~ScrollBarListener() {}

    /** Called when a ScrollBar is moved.

        @param scrollBarThatHasMoved    the bar that has moved
        @param newRangeStart            the new range start of this bar
    */
    virtual void scrollBarMoved (ScrollBar* scrollBarThatHasMoved,
                                 const double newRangeStart) = 0;
};

/**
    A scrollbar component.

    To use a scrollbar, set up its total range using the setRangeLimits() method - this
    sets the range of values it can represent. Then you can use setCurrentRange() to
    change the position and size of the scrollbar's 'thumb'.

    Registering a ScrollBarListener with the scrollbar will allow you to find out when
    the user moves it, and you can use the getCurrentRangeStart() to find out where
    they moved it to.

    The scrollbar will adjust its own visibility according to whether its thumb size
    allows it to actually be scrolled.

    For most purposes, it's probably easier to use a ViewportContainer or ListBox
    instead of handling a scrollbar directly.

    @see ScrollBarListener
*/
class JUCE_API  ScrollBar  : public Component,
                             public AsyncUpdater,
                             private Timer
{
public:

    /** Creates a Scrollbar.

        @param isVertical           whether it should be a vertical or horizontal bar
        @param buttonsAreVisible    whether to show the up/down or left/right buttons
    */
    ScrollBar (const bool isVertical,
               const bool buttonsAreVisible = true);

    /** Destructor. */
    ~ScrollBar();

    /** Returns true if the scrollbar is vertical, false if it's horizontal. */
    bool isVertical() const throw()                                 { return vertical; }

    /** Changes the scrollbar's direction.

        You'll also need to resize the bar appropriately - this just changes its internal
        layout.

        @param shouldBeVertical     true makes it vertical; false makes it horizontal.
    */
    void setOrientation (const bool shouldBeVertical) throw();

    /** Shows or hides the scrollbar's buttons. */
    void setButtonVisibility (const bool buttonsAreVisible);

    /** Tells the scrollbar whether to make itself invisible when not needed.

        The default behaviour is for a scrollbar to become invisible when the thumb
        fills the whole of its range (i.e. when it can't be moved). Setting this
        value to false forces the bar to always be visible.
    */
    void setAutoHide (const bool shouldHideWhenFullRange);

    /** Sets the minimum and maximum values that the bar will move between.

        The bar's thumb will always be constrained so that the top of the thumb
        will be >= minimum, and the bottom of the thumb <= maximum.

        @see setCurrentRange
    */
    void setRangeLimits (const double minimum,
                         const double maximum) throw();

    /** Returns the lower value that the thumb can be set to.

        This is the value set by setRangeLimits().
    */
    double getMinimumRangeLimit() const throw()                     { return minimum; }

    /** Returns the upper value that the thumb can be set to.

        This is the value set by setRangeLimits().
    */
    double getMaximumRangeLimit() const throw()                     { return maximum; }

    /** Changes the position of the scrollbar's 'thumb'.

        This sets both the position and size of the thumb - to just set the position without
        changing the size, you can use setCurrentRangeStart().

        If this method call actually changes the scrollbar's position, it will trigger an
        asynchronous call to ScrollBarListener::scrollBarMoved() for all the listeners that
        are registered.

        @param newStart     the top (or left) of the thumb, in the range
                            getMinimumRangeLimit() <= newStart <= getMaximumRangeLimit(). If the
                            value is beyond these limits, it will be clipped.
        @param newSize      the size of the thumb, such that
                            getMinimumRangeLimit() <= newStart + newSize <= getMaximumRangeLimit(). If the
                            size is beyond these limits, it will be clipped.
        @see setCurrentRangeStart, getCurrentRangeStart, getCurrentRangeSize
    */
    void setCurrentRange (double newStart,
                          double newSize) throw();

    /** Moves the bar's thumb position.

        This will move the thumb position without changing the thumb size. Note
        that the maximum thumb start position is (getMaximumRangeLimit() - getCurrentRangeSize()).

        If this method call actually changes the scrollbar's position, it will trigger an
        asynchronous call to ScrollBarListener::scrollBarMoved() for all the listeners that
        are registered.

        @see setCurrentRange
    */
    void setCurrentRangeStart (double newStart) throw();

    /** Returns the position of the top of the thumb.

        @see setCurrentRangeStart
    */
    double getCurrentRangeStart() const throw()                     { return rangeStart; }

    /** Returns the current size of the thumb.

        @see setCurrentRange
    */
    double getCurrentRangeSize() const throw()                      { return rangeSize; }

    /** Sets the amount by which the up and down buttons will move the bar.

        The value here is in terms of the total range, and is added or subtracted
        from the thumb position when the user clicks an up/down (or left/right) button.
    */
    void setSingleStepSize (const double newSingleStepSize) throw();

    /** Moves the scrollbar by a number of single-steps.

        This will move the bar by a multiple of its single-step interval (as
        specified using the setSingleStepSize() method).

        A positive value here will move the bar down or to the right, a negative
        value moves it up or to the left.
    */
    void moveScrollbarInSteps (const int howManySteps) throw();

    /** Moves the scroll bar up or down in pages.

        This will move the bar by a multiple of its current thumb size, effectively
        doing a page-up or down.

        A positive value here will move the bar down or to the right, a negative
        value moves it up or to the left.
    */
    void moveScrollbarInPages (const int howManyPages) throw();

    /** Scrolls to the top (or left).

        This is the same as calling setCurrentRangeStart (getMinimumRangeLimit());
    */
    void scrollToTop() throw();

    /** Scrolls to the bottom (or right).

        This is the same as calling setCurrentRangeStart (getMaximumRangeLimit() - getCurrentRangeSize());
    */
    void scrollToBottom() throw();

    /** Changes the delay before the up and down buttons autorepeat when they are held
        down.

        For an explanation of what the parameters are for, see Button::setRepeatSpeed().

        @see Button::setRepeatSpeed
    */
    void setButtonRepeatSpeed (const int initialDelayInMillisecs,
                               const int repeatDelayInMillisecs,
                               const int minimumDelayInMillisecs = -1) throw();

    /** A set of colour IDs to use to change the colour of various aspects of the component.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId          = 0x1000300,    /**< The background colour of the scrollbar. */
        thumbColourId               = 0x1000400,    /**< A base colour to use for the thumb. The look and feel will probably use variations on this colour. */
        trackColourId               = 0x1000401     /**< A base colour to use for the slot area of the bar. The look and feel will probably use variations on this colour. */
    };

    /** Registers a listener that will be called when the scrollbar is moved. */
    void addListener (ScrollBarListener* const listener) throw();

    /** Deregisters a previously-registered listener. */
    void removeListener (ScrollBarListener* const listener) throw();

    /** @internal */
    bool keyPressed (const KeyPress& key);
    /** @internal */
    void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
    /** @internal */
    void lookAndFeelChanged();
    /** @internal */
    void handleAsyncUpdate();
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    void mouseUp   (const MouseEvent& e);
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();

    juce_UseDebuggingNewOperator

private:

    double minimum, maximum;
    double rangeStart, rangeSize;
    double singleStepSize, dragStartRange;
    int thumbAreaStart, thumbAreaSize, thumbStart, thumbSize;
    int dragStartMousePos, lastMousePos;
    int initialDelayInMillisecs, repeatDelayInMillisecs, minimumDelayInMillisecs;
    bool vertical, isDraggingThumb, alwaysVisible;
    Button* upButton;
    Button* downButton;
    SortedSet <void*> listeners;

    void updateThumbPosition() throw();
    void timerCallback();

    ScrollBar (const ScrollBar&);
    const ScrollBar& operator= (const ScrollBar&);
};

#endif   // __JUCE_SCROLLBAR_JUCEHEADER__
/********* End of inlined file: juce_ScrollBar.h *********/

/**
    A Viewport is used to contain a larger child component, and allows the child
    to be automatically scrolled around.

    To use a Viewport, just create one and set the component that goes inside it
    using the setViewedComponent() method. When the child component changes size,
    the Viewport will adjust its scrollbars accordingly.

    A subclass of the viewport can be created which will receive calls to its
    visibleAreaChanged() method when the subcomponent changes position or size.

*/
class JUCE_API  Viewport  : public Component,
                            private ComponentListener,
                            private ScrollBarListener
{
public:

    /** Creates a Viewport.

        The viewport is initially empty - use the setViewedComponent() method to
        add a child component for it to manage.
    */
    Viewport (const String& componentName = String::empty);

    /** Destructor. */
    ~Viewport();

    /** Sets the component that this viewport will contain and scroll around.

        This will add the given component to this Viewport and position it at
        (0, 0).

        (Don't add or remove any child components directly using the normal
        Component::addChildComponent() methods).

        @param newViewedComponent       the component to add to this viewport (this pointer
                                        may be null). The component passed in will be deleted
                                        by the Viewport when it's no longer needed
        @see getViewedComponent
    */
    void setViewedComponent (Component* const newViewedComponent);

    /** Returns the component that's currently being used inside the Viewport.

        @see setViewedComponent
    */
    Component* getViewedComponent() const throw()                   { return contentComp; }

    /** Changes the position of the viewed component.

        The inner component will be moved so that the pixel at the top left of
        the viewport will be the pixel at position (xPixelsOffset, yPixelsOffset)
        within the inner component.

        This will update the scrollbars and might cause a call to visibleAreaChanged().

        @see getViewPositionX, getViewPositionY, setViewPositionProportionately
    */
    void setViewPosition (const int xPixelsOffset,
                          const int yPixelsOffset);

    /** Changes the view position as a proportion of the distance it can move.

        The values here are from 0.0 to 1.0 - where (0, 0) would put the
        visible area in the top-left, and (1, 1) would put it as far down and
        to the right as it's possible to go whilst keeping the child component
        on-screen.
    */
    void setViewPositionProportionately (const double proportionX,
                                         const double proportionY);

    /** Returns the position within the child component of the top-left of its visible area.
        @see getViewWidth, setViewPosition
    */
    int getViewPositionX() const throw()                    { return lastVX; }

    /** Returns the position within the child component of the top-left of its visible area.
        @see getViewHeight, setViewPosition
    */
    int getViewPositionY() const throw()                    { return lastVY; }

    /** Returns the width of the visible area of the child component.

        This may be less than the width of this Viewport if there's a vertical scrollbar
        or if the child component is itself smaller.
    */
    int getViewWidth() const throw()                        { return lastVW; }

    /** Returns the height of the visible area of the child component.

        This may be less than the height of this Viewport if there's a horizontal scrollbar
        or if the child component is itself smaller.
    */
    int getViewHeight() const throw()                       { return lastVH; }

    /** Returns the width available within this component for the contents.

        This will be the width of the viewport component minus the width of a
        vertical scrollbar (if visible).
    */
    int getMaximumVisibleWidth() const throw();

    /** Returns the height available within this component for the contents.

        This will be the height of the viewport component minus the space taken up
        by a horizontal scrollbar (if visible).
    */
    int getMaximumVisibleHeight() const throw();

    /** Callback method that is called when the visible area changes.

        This will be called when the visible area is moved either be scrolling or
        by calls to setViewPosition(), etc.
    */
    virtual void visibleAreaChanged (int visibleX, int visibleY,
                                     int visibleW, int visibleH);

    /** Turns scrollbars on or off.

        If set to false, the scrollbars won't ever appear. When true (the default)
        they will appear only when needed.
    */
    void setScrollBarsShown (const bool showVerticalScrollbarIfNeeded,
                             const bool showHorizontalScrollbarIfNeeded);

    /** True if the vertical scrollbar is enabled.
        @see setScrollBarsShown
    */
    bool isVerticalScrollBarShown() const throw()               { return showVScrollbar; }

    /** True if the horizontal scrollbar is enabled.
        @see setScrollBarsShown
    */
    bool isHorizontalScrollBarShown() const throw()             { return showHScrollbar; }

    /** Changes the width of the scrollbars.

        If this isn't specified, the default width from the LookAndFeel class will be used.

        @see LookAndFeel::getDefaultScrollbarWidth
    */
    void setScrollBarThickness (const int thickness);

    /** Returns the thickness of the scrollbars.

        @see setScrollBarThickness
    */
    int getScrollBarThickness() const throw();

    /** Changes the distance that a single-step click on a scrollbar button
        will move the viewport.
    */
    void setSingleStepSizes (const int stepX, const int stepY);

    /** Shows or hides the buttons on any scrollbars that are used.

        @see ScrollBar::setButtonVisibility
    */
    void setScrollBarButtonVisibility (const bool buttonsVisible);

    /** Returns a pointer to the scrollbar component being used.

        Handy if you need to customise the bar somehow.
    */
    ScrollBar* getVerticalScrollBar() const throw()             { return verticalScrollBar; }

    /** Returns a pointer to the scrollbar component being used.

        Handy if you need to customise the bar somehow.
    */
    ScrollBar* getHorizontalScrollBar() const throw()           { return horizontalScrollBar; }

    juce_UseDebuggingNewOperator

    /** @internal */
    void resized();
    /** @internal */
    void scrollBarMoved (ScrollBar* scrollBarThatHasMoved, const double newRangeStart);
    /** @internal */
    void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
    /** @internal */
    bool keyPressed (const KeyPress& key);
    /** @internal */
    void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized);
    /** @internal */
    bool useMouseWheelMoveIfNeeded (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);

private:
    Component* contentComp;
    int lastVX, lastVY, lastVW, lastVH;
    int scrollBarThickness;
    int singleStepX, singleStepY;
    bool showHScrollbar, showVScrollbar;
    Component* contentHolder;
    ScrollBar* verticalScrollBar;
    ScrollBar* horizontalScrollBar;

    void updateVisibleRegion();
    Viewport (const Viewport&);
    const Viewport& operator= (const Viewport&);
};

#endif   // __JUCE_VIEWPORT_JUCEHEADER__
/********* End of inlined file: juce_Viewport.h *********/

/**
    A panel that holds a list of PropertyComponent objects.

    This panel displays a list of PropertyComponents, and allows them to be organised
    into collapsible sections.

    To use, simply create one of these and add your properties to it with addProperties()
    or addSection().

    @see PropertyComponent
*/
class JUCE_API  PropertyPanel  : public Component
{
public:

    /** Creates an empty property panel. */
    PropertyPanel();

    /** Destructor. */
    ~PropertyPanel();

    /** Deletes all property components from the panel.
    */
    void clear();

    /** Adds a set of properties to the panel.

        The components in the list will be owned by this object and will be automatically
        deleted later on when no longer needed.

        These properties are added without them being inside a named section. If you
        want them to be kept together in a collapsible section, use addSection() instead.
    */
    void addProperties (const Array <PropertyComponent*>& newPropertyComponents);

    /** Adds a set of properties to the panel.

        These properties are added at the bottom of the list, under a section heading with
        a plus/minus button that allows it to be opened and closed.

        The components in the list will be owned by this object and will be automatically
        deleted later on when no longer needed.

        To add properies without them being in a section, use addProperties().
    */
    void addSection (const String& sectionTitle,
                     const Array <PropertyComponent*>& newPropertyComponents,
                     const bool shouldSectionInitiallyBeOpen = true);

    /** Calls the refresh() method of all PropertyComponents in the panel */
    void refreshAll() const;

    /** Returns a list of all the names of sections in the panel.

        These are the sections that have been added with addSection().
    */
    const StringArray getSectionNames() const;

    /** Returns true if the section at this index is currently open.

        The index is from 0 up to the number of items returned by getSectionNames().
    */
    bool isSectionOpen (const int sectionIndex) const;

    /** Opens or closes one of the sections.

        The index is from 0 up to the number of items returned by getSectionNames().
    */
    void setSectionOpen (const int sectionIndex, const bool shouldBeOpen);

    /** Enables or disables one of the sections.

        The index is from 0 up to the number of items returned by getSectionNames().
    */
    void setSectionEnabled (const int sectionIndex, const bool shouldBeEnabled);

    /** Saves the current state of open/closed sections so it can be restored later.

        The caller is responsible for deleting the object that is returned.

        To restore this state, use restoreOpennessState().

        @see restoreOpennessState
    */
    XmlElement* getOpennessState() const;

    /** Restores a previously saved arrangement of open/closed sections.

        This will try to restore a snapshot of the panel's state that was created by
        the getOpennessState() method. If any of the sections named in the original
        XML aren't present, they will be ignored.

        @see getOpennessState
    */
    void restoreOpennessState (const XmlElement& newState);

    /** Sets a message to be displayed when there are no properties in the panel.

        The default message is "nothing selected".
    */
    void setMessageWhenEmpty (const String& newMessage);

    /** Returns the message that is displayed when there are no properties.
        @see setMessageWhenEmpty
    */
    const String& getMessageWhenEmpty() const throw();

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();

    juce_UseDebuggingNewOperator

private:
    Viewport* viewport;
    Component* propertyHolderComponent;
    String messageWhenEmpty;

    void updatePropHolderLayout() const;
    void updatePropHolderLayout (const int width) const;
};

#endif   // __JUCE_PROPERTYPANEL_JUCEHEADER__
/********* End of inlined file: juce_PropertyPanel.h *********/

/**
    A type of UI component that displays the parameters of an AudioProcessor as
    a simple list of sliders.

    This can be used for showing an editor for a processor that doesn't supply
    its own custom editor.

    @see AudioProcessor
*/
class JUCE_API  GenericAudioProcessorEditor      : public AudioProcessorEditor
{
public:

    GenericAudioProcessorEditor (AudioProcessor* const owner);
    ~GenericAudioProcessorEditor();

    void paint (Graphics& g);
    void resized();

    juce_UseDebuggingNewOperator

private:
    PropertyPanel* panel;
};

#endif   // __JUCE_GENERICAUDIOPROCESSOREDITOR_JUCEHEADER__
/********* End of inlined file: juce_GenericAudioProcessorEditor.h *********/

#endif
#ifndef __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_AudioFormatReaderSource.h *********/
#ifndef __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__
#define __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_PositionableAudioSource.h *********/
#ifndef __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__
#define __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_AudioSource.h *********/
#ifndef __JUCE_AUDIOSOURCE_JUCEHEADER__
#define __JUCE_AUDIOSOURCE_JUCEHEADER__

/**
    Used by AudioSource::getNextAudioBlock().
*/
struct JUCE_API  AudioSourceChannelInfo
{
    /** The destination buffer to fill with audio data.

        When the AudioSource::getNextAudioBlock() method is called, the active section
        of this buffer should be filled with whatever output the source produces.

        Only the samples specified by the startSample and numSamples members of this structure
        should be affected by the call.

        The contents of the buffer when it is passed to the the AudioSource::getNextAudioBlock()
        method can be treated as the input if the source is performing some kind of filter operation,
        but should be cleared if this is not the case - the clearActiveBufferRegion() is
        a handy way of doing this.

        The number of channels in the buffer could be anything, so the AudioSource
        must cope with this in whatever way is appropriate for its function.
    */
    AudioSampleBuffer* buffer;

    /** The first sample in the buffer from which the callback is expected
        to write data. */
    int startSample;

    /** The number of samples in the buffer which the callback is expected to
        fill with data. */
    int numSamples;

    /** Convenient method to clear the buffer if the source is not producing any data. */
    void clearActiveBufferRegion() const
    {
        if (buffer != 0)
            buffer->clear (startSample, numSamples);
    }
};

/**
    Base class for objects that can produce a continuous stream of audio.

    @see AudioFormatReaderSource, ResamplingAudioSource
*/
class JUCE_API  AudioSource
{
protected:

    /** Creates an AudioSource. */
    AudioSource() throw()       {}

public:
    /** Destructor. */
    virtual ~AudioSource()      {}

    /** Tells the source to prepare for playing.

        The source can use this opportunity to initialise anything it needs to.

        Note that this method could be called more than once in succession without
        a matching call to releaseResources(), so make sure your code is robust and
        can handle that kind of situation.

        @param samplesPerBlockExpected  the number of samples that the source
                                        will be expected to supply each time its
                                        getNextAudioBlock() method is called. This
                                        number may vary slightly, because it will be dependent
                                        on audio hardware callbacks, and these aren't
                                        guaranteed to always use a constant block size, so
                                        the source should be able to cope with small variations.
        @param sampleRate               the sample rate that the output will be used at - this
                                        is needed by sources such as tone generators.
        @see releaseResources, getNextAudioBlock
    */
    virtual void prepareToPlay (int samplesPerBlockExpected,
                                double sampleRate) = 0;

    /** Allows the source to release anything it no longer needs after playback has stopped.

        This will be called when the source is no longer going to have its getNextAudioBlock()
        method called, so it should release any spare memory, etc. that it might have
        allocated during the prepareToPlay() call.

        Note that there's no guarantee that prepareToPlay() will actually have been called before
        releaseResources(), and it may be called more than once in succession, so make sure your
        code is robust and doesn't make any assumptions about when it will be called.

        @see prepareToPlay, getNextAudioBlock
    */
    virtual void releaseResources() = 0;

    /** Called repeatedly to fetch subsequent blocks of audio data.

        After calling the prepareToPlay() method, this callback will be made each
        time the audio playback hardware (or whatever other destination the audio
        data is going to) needs another block of data.

        It will generally be called on a high-priority system thread, or possibly even
        an interrupt, so be careful not to do too much work here, as that will cause
        audio glitches!

        @see AudioSourceChannelInfo, prepareToPlay, releaseResources
    */
    virtual void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) = 0;
};

#endif   // __JUCE_AUDIOSOURCE_JUCEHEADER__
/********* End of inlined file: juce_AudioSource.h *********/

/**
    A type of AudioSource which can be repositioned.

    The basic AudioSource just streams continuously with no idea of a current
    time or length, so the PositionableAudioSource is used for a finite stream
    that has a current read position.

    @see AudioSource, AudioTransportSource
*/
class JUCE_API  PositionableAudioSource  : public AudioSource
{
protected:

    /** Creates the PositionableAudioSource. */
    PositionableAudioSource() throw()   {}

public:
    /** Destructor */
    ~PositionableAudioSource()          {}

    /** Tells the stream to move to a new position.

        Calling this indicates that the next call to AudioSource::getNextAudioBlock()
        should return samples from this position.

        Note that this may be called on a different thread to getNextAudioBlock(),
        so the subclass should make sure it's synchronised.
    */
    virtual void setNextReadPosition (int newPosition) = 0;

    /** Returns the position from which the next block will be returned.

        @see setNextReadPosition
    */
    virtual int getNextReadPosition() const = 0;

    /** Returns the total length of the stream (in samples). */
    virtual int getTotalLength() const = 0;

    /** Returns true if this source is actually playing in a loop. */
    virtual bool isLooping() const = 0;
};

#endif   // __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__
/********* End of inlined file: juce_PositionableAudioSource.h *********/

/********* Start of inlined file: juce_AudioFormatReader.h *********/
#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__
#define __JUCE_AUDIOFORMATREADER_JUCEHEADER__

class AudioFormat;

/**
    Reads samples from an audio file stream.

    A subclass that reads a specific type of audio format will be created by
    an AudioFormat object.

    @see AudioFormat, AudioFormatWriter
*/
class JUCE_API  AudioFormatReader
{
protected:

    /** Creates an AudioFormatReader object.

        @param sourceStream     the stream to read from - this will be deleted
                                by this object when it is no longer needed. (Some
                                specialised readers might not use this parameter and
                                can leave it as 0).
        @param formatName       the description that will be returned by the getFormatName()
                                method
    */
    AudioFormatReader (InputStream* const sourceStream,
                       const String& formatName);

public:
    /** Destructor. */
    virtual ~AudioFormatReader();

    /** Returns a description of what type of format this is.

        E.g. "AIFF"
    */
    const String getFormatName() const throw()      { return formatName; }

    /** Reads samples from the stream.

        @param destSamples          an array of buffers into which the sample data for each
                                    channel will be written.
                                    If the format is fixed-point, each channel will be written
                                    as an array of 32-bit signed integers using the full
                                    range -0x80000000 to 0x7fffffff, regardless of the source's
                                    bit-depth. If it is a floating-point format, you should cast
                                    the resulting array to a (float**) to get the values (in the
                                    range -1.0 to 1.0 or beyond)
                                    If the format is stereo, then destSamples[0] is the left channel
                                    data, and destSamples[1] is the right channel.
                                    The numDestChannels parameter indicates how many pointers this array
                                    contains, but some of these pointers can be null if you don't want to
                                    read data for some of the channels
        @param numDestChannels      the number of array elements in the destChannels array
        @param startSampleInSource  the position in the audio file or stream at which the samples
                                    should be read, as a number of samples from the start of the
                                    stream. It's ok for this to be beyond the start or end of the
                                    available data - any samples that are out-of-range will be returned
                                    as zeros.
        @param numSamplesToRead     the number of samples to read. If this is greater than the number
                                    of samples that the file or stream contains. the result will be padded
                                    with zeros
        @param fillLeftoverChannelsWithCopies   if true, this indicates that if there's no source data available
                                    for some of the channels that you pass in, then they should be filled with
                                    copies of valid source channels.
                                    E.g. if you're reading a mono file and you pass 2 channels to this method, then
                                    if fillLeftoverChannelsWithCopies is true, both destination channels will be filled
                                    with the same data from the file's single channel. If fillLeftoverChannelsWithCopies
                                    was false, then only the first channel would be filled with the file's contents, and
                                    the second would be cleared. If there are many channels, e.g. you try to read 4 channels
                                    from a stereo file, then the last 3 would all end up with copies of the same data.
        @returns                    true if the operation succeeded, false if there was an error. Note
                                    that reading sections of data beyond the extent of the stream isn't an
                                    error - the reader should just return zeros for these regions
        @see readMaxLevels
    */
    bool read (int** destSamples,
               int numDestChannels,
               int64 startSampleInSource,
               int numSamplesToRead,
               const bool fillLeftoverChannelsWithCopies);

    /** Finds the highest and lowest sample levels from a section of the audio stream.

        This will read a block of samples from the stream, and measure the
        highest and lowest sample levels from the channels in that section, returning
        these as normalised floating-point levels.

        @param startSample          the offset into the audio stream to start reading from. It's
                                    ok for this to be beyond the start or end of the stream.
        @param numSamples           how many samples to read
        @param lowestLeft           on return, this is the lowest absolute sample from the left channel
        @param highestLeft          on return, this is the highest absolute sample from the left channel
        @param lowestRight          on return, this is the lowest absolute sample from the right
                                    channel (if there is one)
        @param highestRight         on return, this is the highest absolute sample from the right
                                    channel (if there is one)
        @see read
    */
    virtual void readMaxLevels (int64 startSample,
                                int64 numSamples,
                                float& lowestLeft,
                                float& highestLeft,
                                float& lowestRight,
                                float& highestRight);

    /** Scans the source looking for a sample whose magnitude is in a specified range.

        This will read from the source, either forwards or backwards between two sample
        positions, until it finds a sample whose magnitude lies between two specified levels.

        If it finds a suitable sample, it returns its position; if not, it will return -1.

        There's also a minimumConsecutiveSamples setting to help avoid spikes or zero-crossing
        points when you're searching for a continuous range of samples

        @param startSample              the first sample to look at
        @param numSamplesToSearch       the number of samples to scan. If this value is negative,
                                        the search will go backwards
        @param magnitudeRangeMinimum    the lowest magnitude (inclusive) that is considered a hit, from 0 to 1.0
        @param magnitudeRangeMaximum    the highest magnitude (inclusive) that is considered a hit, from 0 to 1.0
        @param minimumConsecutiveSamples    if this is > 0, the method will only look for a sequence
                                            of this many consecutive samples, all of which lie
                                            within the target range. When it finds such a sequence,
                                            it returns the position of the first in-range sample
                                            it found (i.e. the earliest one if scanning forwards, the
                                            latest one if scanning backwards)
    */
    int64 searchForLevel (int64 startSample,
                          int64 numSamplesToSearch,
                          const double magnitudeRangeMinimum,
                          const double magnitudeRangeMaximum,
                          const int minimumConsecutiveSamples);

    /** The sample-rate of the stream. */
    double sampleRate;

    /** The number of bits per sample, e.g. 16, 24, 32. */
    unsigned int bitsPerSample;

    /** The total number of samples in the audio stream. */
    int64 lengthInSamples;

    /** The total number of channels in the audio stream. */
    unsigned int numChannels;

    /** Indicates whether the data is floating-point or fixed. */
    bool usesFloatingPointData;

    /** A set of metadata values that the reader has pulled out of the stream.

        Exactly what these values are depends on the format, so you can
        check out the format implementation code to see what kind of stuff
        they understand.
    */
    StringPairArray metadataValues;

    /** The input stream, for use by subclasses. */
    InputStream* input;

    /** Subclasses must implement this method to perform the low-level read operation.

        Callers should use read() instead of calling this directly.

        @param destSamples  the array of destination buffers to fill. Some of these
                            pointers may be null
        @param numDestChannels  the number of items in the destSamples array. This
                            value is guaranteed not to be greater than the number of
                            channels that this reader object contains
        @param startOffsetInDestBuffer      the number of samples from the start of the
                            dest data at which to begin writing
        @param startSampleInFile    the number of samples into the source data at which
                            to begin reading. This value is guaranteed to be >= 0.
        @param numSamples   the number of samples to read
    */
    virtual bool readSamples (int** destSamples,
                              int numDestChannels,
                              int startOffsetInDestBuffer,
                              int64 startSampleInFile,
                              int numSamples) = 0;

    juce_UseDebuggingNewOperator

private:
    String formatName;

    AudioFormatReader (const AudioFormatReader&);
    const AudioFormatReader& operator= (const AudioFormatReader&);
};

#endif   // __JUCE_AUDIOFORMATREADER_JUCEHEADER__
/********* End of inlined file: juce_AudioFormatReader.h *********/

/**
    A type of AudioSource that will read from an AudioFormatReader.

    @see PositionableAudioSource, AudioTransportSource, BufferingAudioSource
*/
class JUCE_API  AudioFormatReaderSource  : public PositionableAudioSource
{
public:

    /** Creates an AudioFormatReaderSource for a given reader.

        @param sourceReader                     the reader to use as the data source
        @param deleteReaderWhenThisIsDeleted    if true, the reader passed-in will be deleted
                                                when this object is deleted; if false it will be
                                                left up to the caller to manage its lifetime
    */
    AudioFormatReaderSource (AudioFormatReader* const sourceReader,
                             const bool deleteReaderWhenThisIsDeleted);

    /** Destructor. */
    ~AudioFormatReaderSource();

    /** Toggles loop-mode.

        If set to true, it will continuously loop the input source. If false,
        it will just emit silence after the source has finished.

        @see isLooping
    */
    void setLooping (const bool shouldLoop) throw();

    /** Returns whether loop-mode is turned on or not. */
    bool isLooping() const                                      { return looping; }

    /** Returns the reader that's being used. */
    AudioFormatReader* getAudioFormatReader() const throw()     { return reader; }

    /** Implementation of the AudioSource method. */
    void prepareToPlay (int samplesPerBlockExpected, double sampleRate);

    /** Implementation of the AudioSource method. */
    void releaseResources();

    /** Implementation of the AudioSource method. */
    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);

    /** Implements the PositionableAudioSource method. */
    void setNextReadPosition (int newPosition);

    /** Implements the PositionableAudioSource method. */
    int getNextReadPosition() const;

    /** Implements the PositionableAudioSource method. */
    int getTotalLength() const;

    juce_UseDebuggingNewOperator

private:
    AudioFormatReader* reader;
    bool deleteReader;

    int volatile nextPlayPos;
    bool volatile looping;

    void readBufferSection (int start, int length, AudioSampleBuffer& buffer, int startSample);

    AudioFormatReaderSource (const AudioFormatReaderSource&);
    const AudioFormatReaderSource& operator= (const AudioFormatReaderSource&);
};

#endif   // __JUCE_AUDIOFORMATREADERSOURCE_JUCEHEADER__
/********* End of inlined file: juce_AudioFormatReaderSource.h *********/

#endif
#ifndef __JUCE_AUDIOSOURCE_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__

/********* Start of inlined file: juce_AudioSourcePlayer.h *********/
#ifndef __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__
#define __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__

/**
    Wrapper class to continuously stream audio from an audio source to an
    AudioIODevice.

    This object acts as an AudioIODeviceCallback, so can be attached to an
    output device, and will stream audio from an AudioSource.
*/
class JUCE_API  AudioSourcePlayer  : public AudioIODeviceCallback
{
public:

    /** Creates an empty AudioSourcePlayer. */
    AudioSourcePlayer();

    /** Destructor.

        Make sure this object isn't still being used by an AudioIODevice before
        deleting it!
    */
    virtual ~AudioSourcePlayer();

    /** Changes the current audio source to play from.

        If the source passed in is already being used, this method will do nothing.
        If the source is not null, its prepareToPlay() method will be called
        before it starts being used for playback.

        If there's another source currently playing, its releaseResources() method
        will be called after it has been swapped for the new one.

        @param newSource                the new source to use - this will NOT be deleted
                                        by this object when no longer needed, so it's the
                                        caller's responsibility to manage it.
    */
    void setSource (AudioSource* newSource);

    /** Returns the source that's playing.

        May return 0 if there's no source.
    */
    AudioSource* getCurrentSource() const throw()       { return source; }

    /** Sets a gain to apply to the audio data. */
    void setGain (const float newGain) throw();

    /** Implementation of the AudioIODeviceCallback method. */
    void audioDeviceIOCallback (const float** inputChannelData,
                                int totalNumInputChannels,
                                float** outputChannelData,
                                int totalNumOutputChannels,
                                int numSamples);

    /** Implementation of the AudioIODeviceCallback method. */
    void audioDeviceAboutToStart (AudioIODevice* device);

    /** Implementation of the AudioIODeviceCallback method. */
    void audioDeviceStopped();

    juce_UseDebuggingNewOperator

private:

    CriticalSection readLock;
    AudioSource* source;
    double sampleRate;
    int bufferSize;
    float* channels [128];
    float* outputChans [128];
    const float* inputChans [128];
    AudioSampleBuffer tempBuffer;
    float lastGain, gain;

    AudioSourcePlayer (const AudioSourcePlayer&);
    const AudioSourcePlayer& operator= (const AudioSourcePlayer&);
};

#endif   // __JUCE_AUDIOSOURCEPLAYER_JUCEHEADER__
/********* End of inlined file: juce_AudioSourcePlayer.h *********/

#endif
#ifndef __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_AudioTransportSource.h *********/
#ifndef __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__
#define __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_BufferingAudioSource.h *********/
#ifndef __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__
#define __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__

/**
    An AudioSource which takes another source as input, and buffers it using a thread.

    Create this as a wrapper around another thread, and it will read-ahead with
    a background thread to smooth out playback. You can either create one of these
    directly, or use it indirectly using an AudioTransportSource.

    @see PositionableAudioSource, AudioTransportSource
*/
class JUCE_API  BufferingAudioSource  : public PositionableAudioSource
{
public:

    /** Creates a BufferingAudioSource.

        @param source                   the input source to read from
        @param deleteSourceWhenDeleted  if true, then the input source object will
                                        be deleted when this object is deleted
        @param numberOfSamplesToBuffer  the size of buffer to use for reading ahead
    */
    BufferingAudioSource (PositionableAudioSource* source,
                          const bool deleteSourceWhenDeleted,
                          int numberOfSamplesToBuffer);

    /** Destructor.

        The input source may be deleted depending on whether the deleteSourceWhenDeleted
        flag was set in the constructor.
    */
    ~BufferingAudioSource();

    /** Implementation of the AudioSource method. */
    void prepareToPlay (int samplesPerBlockExpected, double sampleRate);

    /** Implementation of the AudioSource method. */
    void releaseResources();

    /** Implementation of the AudioSource method. */
    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);

    /** Implements the PositionableAudioSource method. */
    void setNextReadPosition (int newPosition);

    /** Implements the PositionableAudioSource method. */
    int getNextReadPosition() const;

    /** Implements the PositionableAudioSource method. */
    int getTotalLength() const                  { return source->getTotalLength(); }

    /** Implements the PositionableAudioSource method. */
    bool isLooping() const                      { return source->isLooping(); }

    juce_UseDebuggingNewOperator

private:

    PositionableAudioSource* source;
    bool deleteSourceWhenDeleted;
    int numberOfSamplesToBuffer;
    AudioSampleBuffer buffer;
    CriticalSection bufferStartPosLock;
    int volatile bufferValidStart, bufferValidEnd, nextPlayPos;
    bool wasSourceLooping;
    double volatile sampleRate;

    friend class SharedBufferingAudioSourceThread;
    bool readNextBufferChunk();
    void readBufferSection (int start, int length, int bufferOffset);

    BufferingAudioSource (const BufferingAudioSource&);
    const BufferingAudioSource& operator= (const BufferingAudioSource&);
};

#endif   // __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__
/********* End of inlined file: juce_BufferingAudioSource.h *********/

/********* Start of inlined file: juce_ResamplingAudioSource.h *********/
#ifndef __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__
#define __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__

/**
    A type of AudioSource that takes an input source and changes its sample rate.

    @see AudioSource
*/
class JUCE_API  ResamplingAudioSource  : public AudioSource
{
public:

    /** Creates a ResamplingAudioSource for a given input source.

        @param inputSource              the input source to read from
        @param deleteInputWhenDeleted   if true, the input source will be deleted when
                                        this object is deleted
    */
    ResamplingAudioSource (AudioSource* const inputSource,
                           const bool deleteInputWhenDeleted);

    /** Destructor. */
    ~ResamplingAudioSource();

    /** Changes the resampling ratio.

        (This value can be changed at any time, even while the source is running).

        @param samplesInPerOutputSample     if set to 1.0, the input is passed through; higher
                                            values will speed it up; lower values will slow it
                                            down. The ratio must be greater than 0
    */
    void setResamplingRatio (const double samplesInPerOutputSample);

    /** Returns the current resampling ratio.

        This is the value that was set by setResamplingRatio().
    */
    double getResamplingRatio() const throw()                   { return ratio; }

    void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
    void releaseResources();
    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);

    juce_UseDebuggingNewOperator

private:
    AudioSource* const input;
    const bool deleteInputWhenDeleted;
    double ratio, lastRatio;
    AudioSampleBuffer buffer;
    int bufferPos, sampsInBuffer;
    double subSampleOffset;
    double coefficients[6];
    CriticalSection ratioLock;

    void setFilterCoefficients (double c1, double c2, double c3, double c4, double c5, double c6);
    void createLowPass (const double proportionalRate);

    struct FilterState
    {
        double x1, x2, y1, y2;
    };

    FilterState filterStates[2];
    void resetFilters();

    void applyFilter (float* samples, int num, FilterState& fs);

    ResamplingAudioSource (const ResamplingAudioSource&);
    const ResamplingAudioSource& operator= (const ResamplingAudioSource&);
};

#endif   // __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__
/********* End of inlined file: juce_ResamplingAudioSource.h *********/

/**
    An AudioSource that takes a PositionableAudioSource and allows it to be
    played, stopped, started, etc.

    This can also be told use a buffer and background thread to read ahead, and
    if can correct for different sample-rates.

    You may want to use one of these along with an AudioSourcePlayer and AudioIODevice
    to control playback of an audio file.

    @see AudioSource, AudioSourcePlayer
*/
class JUCE_API  AudioTransportSource  : public PositionableAudioSource,
                                        public ChangeBroadcaster
{
public:

    /** Creates an AudioTransportSource.

        After creating one of these, use the setSource() method to select an input source.
    */
    AudioTransportSource();

    /** Destructor. */
    ~AudioTransportSource();

    /** Sets the reader that is being used as the input source.

        This will stop playback, reset the position to 0 and change to the new reader.

        The source passed in will not be deleted by this object, so must be managed by
        the caller.

        @param newSource                        the new input source to use. This may be zero
        @param readAheadBufferSize              a size of buffer to use for reading ahead. If this
                                                is zero, no reading ahead will be done; if it's
                                                greater than zero, a BufferingAudioSource will be used
                                                to do the reading-ahead
        @param sourceSampleRateToCorrectFor     if this is non-zero, it specifies the sample
                                                rate of the source, and playback will be sample-rate
                                                adjusted to maintain playback at the correct pitch. If
                                                this is 0, no sample-rate adjustment will be performed
    */
    void setSource (PositionableAudioSource* const newSource,
                    int readAheadBufferSize = 0,
                    double sourceSampleRateToCorrectFor = 0.0);

    /** Changes the current playback position in the source stream.

        The next time the getNextAudioBlock() method is called, this
        is the time from which it'll read data.

        @see getPosition
    */
    void setPosition (double newPosition);

    /** Returns the position that the next data block will be read from

        This is a time in seconds.
    */
    double getCurrentPosition() const;

    /** Returns true if the player has stopped because its input stream ran out of data.
    */
    bool hasStreamFinished() const throw()              { return inputStreamEOF; }

    /** Starts playing (if a source has been selected).

        If it starts playing, this will send a message to any ChangeListeners
        that are registered with this object.
    */
    void start();

    /** Stops playing.

        If it's actually playing, this will send a message to any ChangeListeners
        that are registered with this object.
    */
    void stop();

    /** Returns true if it's currently playing. */
    bool isPlaying() const throw()      { return playing; }

    /** Changes the gain to apply to the output.

        @param newGain  a factor by which to multiply the outgoing samples,
                        so 1.0 = 0dB, 0.5 = -6dB, 2.0 = 6dB, etc.
    */
    void setGain (const float newGain) throw();

    /** Returns the current gain setting.

        @see setGain
    */
    float getGain() const throw()       { return gain; }

    /** Implementation of the AudioSource method. */
    void prepareToPlay (int samplesPerBlockExpected, double sampleRate);

    /** Implementation of the AudioSource method. */
    void releaseResources();

    /** Implementation of the AudioSource method. */
    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);

    /** Implements the PositionableAudioSource method. */
    void setNextReadPosition (int newPosition);

    /** Implements the PositionableAudioSource method. */
    int getNextReadPosition() const;

    /** Implements the PositionableAudioSource method. */
    int getTotalLength() const;

    /** Implements the PositionableAudioSource method. */
    bool isLooping() const;

    juce_UseDebuggingNewOperator

private:
    PositionableAudioSource* source;
    ResamplingAudioSource* resamplerSource;
    BufferingAudioSource* bufferingSource;
    PositionableAudioSource* positionableSource;
    AudioSource* masterSource;

    CriticalSection callbackLock;
    float volatile gain, lastGain;
    bool volatile playing, stopped;
    double sampleRate, sourceSampleRate;
    int blockSize, readAheadBufferSize;
    bool isPrepared, inputStreamEOF;

    AudioTransportSource (const AudioTransportSource&);
    const AudioTransportSource& operator= (const AudioTransportSource&);
};

#endif   // __JUCE_AUDIOTRANSPORTSOURCE_JUCEHEADER__
/********* End of inlined file: juce_AudioTransportSource.h *********/

#endif
#ifndef __JUCE_BUFFERINGAUDIOSOURCE_JUCEHEADER__

#endif
#ifndef __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_ChannelRemappingAudioSource.h *********/
#ifndef __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__
#define __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__

/**
    An AudioSource that takes the audio from another source, and re-maps its
    input and output channels to a different arrangement.

    You can use this to increase or decrease the number of channels that an
    audio source uses, or to re-order those channels.

    Call the reset() method before using it to set up a default mapping, and then
    the setInputChannelMapping() and setOutputChannelMapping() methods to
    create an appropriate mapping, otherwise no channels will be connected and
    it'll produce silence.

    @see AudioSource
*/
class ChannelRemappingAudioSource  : public AudioSource
{
public:

    /** Creates a remapping source that will pass on audio from the given input.

        @param source       the input source to use. Make sure that this doesn't
                            get deleted before the ChannelRemappingAudioSource object
        @param deleteSourceWhenDeleted  if true, the input source will be deleted
                            when this object is deleted, if false, the caller is
                            responsible for its deletion
    */
    ChannelRemappingAudioSource (AudioSource* const source,
                                 const bool deleteSourceWhenDeleted);

    /** Destructor. */
    ~ChannelRemappingAudioSource();

    /** Specifies a number of channels that this audio source must produce from its
        getNextAudioBlock() callback.
    */
    void setNumberOfChannelsToProduce (const int requiredNumberOfChannels) throw();

    /** Clears any mapped channels.

        After this, no channels are mapped, so this object will produce silence. Create
        some mappings with setInputChannelMapping() and setOutputChannelMapping().
    */
    void clearAllMappings() throw();

    /** Creates an input channel mapping.

        When the getNextAudioBlock() method is called, the data in channel sourceChannelIndex of the incoming
        data will be sent to destChannelIndex of our input source.

        @param destChannelIndex     the index of an input channel in our input audio source (i.e. the
                                    source specified when this object was created).
        @param sourceChannelIndex   the index of the input channel in the incoming audio data buffer
                                    during our getNextAudioBlock() callback
    */
    void setInputChannelMapping (const int destChannelIndex,
                                 const int sourceChannelIndex) throw();

    /** Creates an output channel mapping.

        When the getNextAudioBlock() method is called, the data returned in channel sourceChannelIndex by
        our input audio source will be copied to channel destChannelIndex of the final buffer.

        @param sourceChannelIndex   the index of an output channel coming from our input audio source
                                    (i.e. the source specified when this object was created).
        @param destChannelIndex     the index of the output channel in the incoming audio data buffer
                                    during our getNextAudioBlock() callback
    */
    void setOutputChannelMapping (const int sourceChannelIndex,
                                  const int destChannelIndex) throw();

    /** Returns the channel from our input that will be sent to channel inputChannelIndex of
        our input audio source.
    */
    int getRemappedInputChannel (const int inputChannelIndex) const throw();

    /** Returns the output channel to which channel outputChannelIndex of our input audio
        source will be sent to.
    */
    int getRemappedOutputChannel (const int outputChannelIndex) const throw();

    /** Returns an XML object to encapsulate the state of the mappings.

        @see restoreFromXml
    */
    XmlElement* createXml() const throw();

    /** Restores the mappings from an XML object created by createXML().

        @see createXml
    */
    void restoreFromXml (const XmlElement& e) throw();

    void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
    void releaseResources();
    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);

    juce_UseDebuggingNewOperator

private:
    int requiredNumberOfChannels;
    Array <int> remappedInputs, remappedOutputs;

    AudioSource* const source;
    const bool deleteSourceWhenDeleted;

    AudioSampleBuffer buffer;
    AudioSourceChannelInfo remappedInfo;

    CriticalSection lock;

    ChannelRemappingAudioSource (const ChannelRemappingAudioSource&);
    const ChannelRemappingAudioSource& operator= (const ChannelRemappingAudioSource&);
};

#endif   // __JUCE_CHANNELREMAPPINGAUDIOSOURCE_JUCEHEADER__
/********* End of inlined file: juce_ChannelRemappingAudioSource.h *********/

#endif
#ifndef __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_IIRFilterAudioSource.h *********/
#ifndef __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__
#define __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__

/**
    An AudioSource that performs an IIR filter on another source.
*/
class JUCE_API  IIRFilterAudioSource  : public AudioSource
{
public:

    /** Creates a IIRFilterAudioSource for a given input source.

        @param inputSource              the input source to read from
        @param deleteInputWhenDeleted   if true, the input source will be deleted when
                                        this object is deleted
    */
    IIRFilterAudioSource (AudioSource* const inputSource,
                          const bool deleteInputWhenDeleted);

    /** Destructor. */
    ~IIRFilterAudioSource();

    /** Changes the filter to use the same parameters as the one being passed in.
    */
    void setFilterParameters (const IIRFilter& newSettings);

    void prepareToPlay (int samplesPerBlockExpected, double sampleRate);
    void releaseResources();
    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);

    juce_UseDebuggingNewOperator

private:

    AudioSource* const input;
    const bool deleteInputWhenDeleted;
    OwnedArray <IIRFilter> iirFilters;

    IIRFilterAudioSource (const IIRFilterAudioSource&);
    const IIRFilterAudioSource& operator= (const IIRFilterAudioSource&);
};

#endif   // __JUCE_IIRFILTERAUDIOSOURCE_JUCEHEADER__
/********* End of inlined file: juce_IIRFilterAudioSource.h *********/

#endif
#ifndef __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_MixerAudioSource.h *********/
#ifndef __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__
#define __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__

/**
    An AudioSource that mixes together the output of a set of other AudioSources.

    Input sources can be added and removed while the mixer is running as long as their
    prepareToPlay() and releaseResources() methods are called before and after adding
    them to the mixer.
*/
class JUCE_API  MixerAudioSource  : public AudioSource
{
public:

    /** Creates a MixerAudioSource.
    */
    MixerAudioSource();

    /** Destructor. */
    ~MixerAudioSource();

    /** Adds an input source to the mixer.

        If the mixer is running you'll need to make sure that the input source
        is ready to play by calling its prepareToPlay() method before adding it.
        If the mixer is stopped, then its input sources will be automatically
        prepared when the mixer's prepareToPlay() method is called.

        @param newInput             the source to add to the mixer
        @param deleteWhenRemoved    if true, then this source will be deleted when
                                    the mixer is deleted or when removeAllInputs() is
                                    called (unless the source is previously removed
                                    with the removeInputSource method)
    */
    void addInputSource (AudioSource* newInput,
                         const bool deleteWhenRemoved);

    /** Removes an input source.

        If the mixer is running, this will remove the source but not call its
        releaseResources() method, so the caller might want to do this manually.

        @param input            the source to remove
        @param deleteSource     whether to delete this source after it's been removed
    */
    void removeInputSource (AudioSource* input,
                            const bool deleteSource);

    /** Removes all the input sources.

        If the mixer is running, this will remove the sources but not call their
        releaseResources() method, so the caller might want to do this manually.

        Any sources which were added with the deleteWhenRemoved flag set will be
        deleted by this method.
    */
    void removeAllInputs();

    /** Implementation of the AudioSource method.

        This will call prepareToPlay() on all its input sources.
    */
    void prepareToPlay (int samplesPerBlockExpected, double sampleRate);

    /** Implementation of the AudioSource method.

        This will call releaseResources() on all its input sources.
    */
    void releaseResources();

    /** Implementation of the AudioSource method. */
    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);

    juce_UseDebuggingNewOperator

private:

    VoidArray inputs;
    BitArray inputsToDelete;
    CriticalSection lock;
    AudioSampleBuffer tempBuffer;
    double currentSampleRate;
    int bufferSizeExpected;

    MixerAudioSource (const MixerAudioSource&);
    const MixerAudioSource& operator= (const MixerAudioSource&);
};

#endif   // __JUCE_MIXERAUDIOSOURCE_JUCEHEADER__
/********* End of inlined file: juce_MixerAudioSource.h *********/

#endif
#ifndef __JUCE_POSITIONABLEAUDIOSOURCE_JUCEHEADER__

#endif
#ifndef __JUCE_RESAMPLINGAUDIOSOURCE_JUCEHEADER__

#endif
#ifndef __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__

/********* Start of inlined file: juce_ToneGeneratorAudioSource.h *********/
#ifndef __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__
#define __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__

/**
    A simple AudioSource that generates a sine wave.

*/
class JUCE_API  ToneGeneratorAudioSource  : public AudioSource
{
public:

    /** Creates a ToneGeneratorAudioSource. */
    ToneGeneratorAudioSource();

    /** Destructor. */
    ~ToneGeneratorAudioSource();

    /** Sets the signal's amplitude. */
    void setAmplitude (const float newAmplitude);

    /** Sets the signal's frequency. */
    void setFrequency (const double newFrequencyHz);

    /** Implementation of the AudioSource method. */
    void prepareToPlay (int samplesPerBlockExpected, double sampleRate);

    /** Implementation of the AudioSource method. */
    void releaseResources();

    /** Implementation of the AudioSource method. */
    void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill);

    juce_UseDebuggingNewOperator

private:

    double frequency, sampleRate;
    double currentPhase, phasePerSample;
    float amplitude;

    ToneGeneratorAudioSource (const ToneGeneratorAudioSource&);
    const ToneGeneratorAudioSource& operator= (const ToneGeneratorAudioSource&);
};

#endif   // __JUCE_TONEGENERATORAUDIOSOURCE_JUCEHEADER__
/********* End of inlined file: juce_ToneGeneratorAudioSource.h *********/

#endif
#ifndef __JUCE_AUDIOIODEVICE_JUCEHEADER__

#endif
#ifndef __JUCE_MIDIINPUT_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__

/********* Start of inlined file: juce_AudioDeviceManager.h *********/
#ifndef __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__
#define __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__

/********* Start of inlined file: juce_AudioIODeviceType.h *********/
#ifndef __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__
#define __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__

class AudioDeviceManager;
class Component;

/**
    Represents a type of audio driver, such as DirectSound, ASIO, CoreAudio, etc.

    To get a list of available audio driver types, use the createDeviceTypes()
    method. Each of the objects returned can then be used to list the available
    devices of that type. E.g.
    @code
    OwnedArray <AudioIODeviceType> types;
    AudioIODeviceType::createDeviceTypes (types);

    for (int i = 0; i < types.size(); ++i)
    {
        String typeName (types[i]->getTypeName());  // This will be things like "DirectSound", "CoreAudio", etc.

        types[i]->scanForDevices();                 // This must be called before getting the list of devices

        StringArray deviceNames (types[i]->getDeviceNames());  // This will now return a list of available devices of this type

        for (int j = 0; j < deviceNames.size(); ++j)
        {
            AudioIODevice* device = types[i]->createDevice (deviceNames [j]);

            ...
        }
    }
    @endcode

    For an easier way of managing audio devices and their settings, have a look at the
    AudioDeviceManager class.

    @see AudioIODevice, AudioDeviceManager
*/
class JUCE_API  AudioIODeviceType
{
public:

    /** Returns the name of this type of driver that this object manages.

        This will be something like "DirectSound", "ASIO", "CoreAudio", "ALSA", etc.
    */
    const String& getTypeName() const throw()                       { return typeName; }

    /** Refreshes the object's cached list of known devices.

        This must be called at least once before calling getDeviceNames() or any of
        the other device creation methods.
    */
    virtual void scanForDevices() = 0;

    /** Returns the list of available devices of this type.

        The scanForDevices() method must have been called to create this list.

        @param wantInputNames     only really used by DirectSound where devices are split up
                                  into inputs and outputs, this indicates whether to use
                                  the input or output name to refer to a pair of devices.
    */
    virtual const StringArray getDeviceNames (const bool wantInputNames = false) const = 0;

    /** Returns the name of the default device.

        This will be one of the names from the getDeviceNames() list.

        @param forInput     if true, this means that a default input device should be
                            returned; if false, it should return the default output
    */
    virtual int getDefaultDeviceIndex (const bool forInput) const = 0;

    /** Returns the index of a given device in the list of device names.
        If asInput is true, it shows the index in the inputs list, otherwise it
        looks for it in the outputs list.
    */
    virtual int getIndexOfDevice (AudioIODevice* device, const bool asInput) const = 0;

    /** Returns true if two different devices can be used for the input and output.
    */
    virtual bool hasSeparateInputsAndOutputs() const = 0;

    /** Creates one of the devices of this type.

        The deviceName must be one of the strings returned by getDeviceNames(), and
        scanForDevices() must have been called before this method is used.
    */
    virtual AudioIODevice* createDevice (const String& outputDeviceName,
                                         const String& inputDeviceName) = 0;

    struct DeviceSetupDetails
    {
        AudioDeviceManager* manager;
        int minNumInputChannels, maxNumInputChannels;
        int minNumOutputChannels, maxNumOutputChannels;
        bool useStereoPairs;
    };

    /** Destructor. */
    virtual ~AudioIODeviceType();

protected:
    AudioIODeviceType (const tchar* const typeName);

private:
    String typeName;

    AudioIODeviceType (const AudioIODeviceType&);
    const AudioIODeviceType& operator= (const AudioIODeviceType&);
};

#endif   // __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__
/********* End of inlined file: juce_AudioIODeviceType.h *********/

/********* Start of inlined file: juce_MidiOutput.h *********/
#ifndef __JUCE_MIDIOUTPUT_JUCEHEADER__
#define __JUCE_MIDIOUTPUT_JUCEHEADER__

/**
    Represents a midi output device.

    To create one of these, use the static getDevices() method to find out what
    outputs are available, then use the openDevice() method to try to open one.

    @see MidiInput
*/
class JUCE_API  MidiOutput  : private Thread
{
public:

    /** Returns a list of the available midi output devices.

        You can open one of the devices by passing its index into the
        openDevice() method.

        @see getDefaultDeviceIndex, openDevice
    */
    static const StringArray getDevices();

    /** Returns the index of the default midi output device to use.

        This refers to the index in the list returned by getDevices().
    */
    static int getDefaultDeviceIndex();

    /** Tries to open one of the midi output devices.

        This will return a MidiOutput object if it manages to open it. You can then
        send messages to this device, and delete it when no longer needed.

        If the device can't be opened, this will return a null pointer.

        @param deviceIndex  the index of a device from the list returned by getDevices()
        @see getDevices
    */
    static MidiOutput* openDevice (int deviceIndex);

#if JUCE_LINUX || DOXYGEN
    /** LINUX ONLY - This will try to create a new midi output device.

        This will attempt to create a new midi output device that other apps can connect
        to and use as their midi input.

        Returns 0 if a device can't be created.

        @param deviceName   the name to use for the new device
    */
    static MidiOutput* createNewDevice (const String& deviceName);
#endif

    /** Destructor. */
    virtual ~MidiOutput();

    /** Makes this device output a midi message.

        @see MidiMessage
    */
    virtual void sendMessageNow (const MidiMessage& message);

    /** Sends a midi reset to the device. */
    virtual void reset();

    /** Returns the current volume setting for this device.  */
    virtual bool getVolume (float& leftVol,
                            float& rightVol);

    /** Changes the overall volume for this device.  */
    virtual void setVolume (float leftVol,
                            float rightVol);

    /** This lets you supply a block of messages that will be sent out at some point
        in the future.

        The MidiOutput class has an internal thread that can send out timestamped
        messages - this appends a set of messages to its internal buffer, ready for
        sending.

        This will only work if you've already started the thread with startBackgroundThread().

        A time is supplied, at which the block of messages should be sent. This time uses
        the same time base as Time::getMillisecondCounter(), and must be in the future.

        The samplesPerSecondForBuffer parameter indicates the number of samples per second
        used by the MidiBuffer. Each event in a MidiBuffer has a sample position, and the
        samplesPerSecondForBuffer value is needed to convert this sample position to a
        real time.
    */
    virtual void sendBlockOfMessages (const MidiBuffer& buffer,
                                      const double millisecondCounterToStartAt,
                                      double samplesPerSecondForBuffer) throw();

    /** Gets rid of any midi messages that had been added by sendBlockOfMessages().
    */
    virtual void clearAllPendingMessages() throw();

    /** Starts up a background thread so that the device can send blocks of data.

        Call this to get the device ready, before using sendBlockOfMessages().
    */
    virtual void startBackgroundThread() throw();

    /** Stops the background thread, and clears any pending midi events.

        @see startBackgroundThread
    */
    virtual void stopBackgroundThread() throw();

    juce_UseDebuggingNewOperator

protected:
    void* internal;

    struct PendingMessage
    {
        PendingMessage (const uint8* const data, const int len, const double sampleNumber) throw();

        MidiMessage message;
        PendingMessage* next;

        juce_UseDebuggingNewOperator
    };

    CriticalSection lock;
    PendingMessage* firstMessage;

    MidiOutput() throw();
    MidiOutput (const MidiOutput&);

    void run();
};

#endif   // __JUCE_MIDIOUTPUT_JUCEHEADER__
/********* End of inlined file: juce_MidiOutput.h *********/

/********* Start of inlined file: juce_ComboBox.h *********/
#ifndef __JUCE_COMBOBOX_JUCEHEADER__
#define __JUCE_COMBOBOX_JUCEHEADER__

/********* Start of inlined file: juce_Label.h *********/
#ifndef __JUCE_LABEL_JUCEHEADER__
#define __JUCE_LABEL_JUCEHEADER__

/********* Start of inlined file: juce_ComponentDeletionWatcher.h *********/
#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__
#define __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__

/**
    Object for monitoring a component, and later testing whether it's still valid.

    Slightly obscure, this one, but it's used internally for making sure that
    after some callbacks, a component hasn't been deleted. It's more reliable than
    just using isValidComponent(), which can provide false-positives if a new
    component is created at the same memory location as an old one.
*/
class JUCE_API  ComponentDeletionWatcher
{
public:

    /** Creates a watcher for a given component.

        The component must be valid at the time it's passed in.
    */
    ComponentDeletionWatcher (const Component* const componentToWatch) throw();

    /** Destructor. */
    ~ComponentDeletionWatcher() throw();

    /** Returns true if the component has been deleted since the time that this
        object was created.
    */
    bool hasBeenDeleted() const throw();

    /** Returns the component that's being watched, or null if it has been deleted. */
    const Component* getComponent() const throw();

    juce_UseDebuggingNewOperator

private:
    const Component* const componentToWatch;
    const uint32 componentUID;

    ComponentDeletionWatcher (const ComponentDeletionWatcher&);
    const ComponentDeletionWatcher& operator= (const ComponentDeletionWatcher&);
};

#endif   // __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__
/********* End of inlined file: juce_ComponentDeletionWatcher.h *********/

/********* Start of inlined file: juce_TextEditor.h *********/
#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__
#define __JUCE_TEXTEDITOR_JUCEHEADER__

/********* Start of inlined file: juce_UndoManager.h *********/
#ifndef __JUCE_UNDOMANAGER_JUCEHEADER__
#define __JUCE_UNDOMANAGER_JUCEHEADER__

/********* Start of inlined file: juce_UndoableAction.h *********/
#ifndef __JUCE_UNDOABLEACTION_JUCEHEADER__
#define __JUCE_UNDOABLEACTION_JUCEHEADER__

/**
    Used by the UndoManager class to store an action which can be done
    and undone.

    @see UndoManager
*/
class JUCE_API  UndoableAction
{
protected:
    /** Creates an action. */
    UndoableAction() throw()    {}

public:
    /** Destructor. */
    virtual ~UndoableAction()   {}

    /** Overridden by a subclass to perform the action.

        This method is called by the UndoManager, and shouldn't be used directly by
        applications.

        Be careful not to make any calls in a perform() method that could call
        recursively back into the UndoManager::perform() method

        @returns    true if the action could be performed.
        @see UndoManager::perform
    */
    virtual bool perform() = 0;

    /** Overridden by a subclass to undo the action.

        This method is called by the UndoManager, and shouldn't be used directly by
        applications.

        Be careful not to make any calls in an undo() method that could call
        recursively back into the UndoManager::perform() method

        @returns    true if the action could be undone without any errors.
        @see UndoManager::perform
    */
    virtual bool undo() = 0;

    /** Returns a value to indicate how much memory this object takes up.

        Because the UndoManager keeps a list of UndoableActions, this is used
        to work out how much space each one will take up, so that the UndoManager
        can work out how many to keep.

        The default value returned here is 10 - units are arbitrary and
        don't have to be accurate.

        @see UndoManager::getNumberOfUnitsTakenUpByStoredCommands,
             UndoManager::setMaxNumberOfStoredUnits
    */
    virtual int getSizeInUnits()    { return 10; }
};

#endif   // __JUCE_UNDOABLEACTION_JUCEHEADER__
/********* End of inlined file: juce_UndoableAction.h *********/

/**
    Manages a list of undo/redo commands.

    An UndoManager object keeps a list of past actions and can use these actions
    to move backwards and forwards through an undo history.

    To use it, create subclasses of UndoableAction which perform all the
    actions you need, then when you need to actually perform an action, create one
    and pass it to the UndoManager's perform() method.

    The manager also uses the concept of 'transactions' to group the actions
    together - all actions performed between calls to beginNewTransaction() are
    grouped together and are all undone/redone as a group.

    The UndoManager is a ChangeBroadcaster, so listeners can register to be told
    when actions are performed or undone.

    @see UndoableAction
*/
class JUCE_API  UndoManager  : public ChangeBroadcaster
{
public:

    /** Creates an UndoManager.

        @param maxNumberOfUnitsToKeep       each UndoableAction object returns a value
                                            to indicate how much storage it takes up
                                            (UndoableAction::getSizeInUnits()), so this
                                            lets you specify the maximum total number of
                                            units that the undomanager is allowed to
                                            keep in memory before letting the older actions
                                            drop off the end of the list.
        @param minimumTransactionsToKeep    this specifies the minimum number of transactions
                                            that will be kept, even if this involves exceeding
                                            the amount of space specified in maxNumberOfUnitsToKeep
    */
    UndoManager (const int maxNumberOfUnitsToKeep = 30000,
                 const int minimumTransactionsToKeep = 30);

    /** Destructor. */
    ~UndoManager();

    /** Deletes all stored actions in the list. */
    void clearUndoHistory();

    /** Returns the current amount of space to use for storing UndoableAction objects.

        @see setMaxNumberOfStoredUnits
    */
    int getNumberOfUnitsTakenUpByStoredCommands() const;

    /** Sets the amount of space that can be used for storing UndoableAction objects.

        @param maxNumberOfUnitsToKeep       each UndoableAction object returns a value
                                            to indicate how much storage it takes up
                                            (UndoableAction::getSizeInUnits()), so this
                                            lets you specify the maximum total number of
                                            units that the undomanager is allowed to
                                            keep in memory before letting the older actions
                                            drop off the end of the list.
        @param minimumTransactionsToKeep    this specifies the minimum number of transactions
                                            that will be kept, even if this involves exceeding
                                            the amount of space specified in maxNumberOfUnitsToKeep
        @see getNumberOfUnitsTakenUpByStoredCommands
    */
    void setMaxNumberOfStoredUnits (const int maxNumberOfUnitsToKeep,
                                    const int minimumTransactionsToKeep);

    /** Performs an action and adds it to the undo history list.

        @param action   the action to perform - this will be deleted by the UndoManager
                        when no longer needed
        @param actionName   if this string is non-empty, the current transaction will be
                            given this name; if it's empty, the current transaction name will
                            be left unchanged. See setCurrentTransactionName()
        @returns true if the command succeeds - see UndoableAction::perform
        @see beginNewTransaction
    */
    bool perform (UndoableAction* const action,
                  const String& actionName = String::empty);

    /** Starts a new group of actions that together will be treated as a single transaction.

        All actions that are passed to the perform() method between calls to this
        method are grouped together and undone/redone together by a single call to
        undo() or redo().

        @param actionName   a description of the transaction that is about to be
                            performed
    */
    void beginNewTransaction (const String& actionName = String::empty);

    /** Changes the name stored for the current transaction.

        Each transaction is given a name when the beginNewTransaction() method is
        called, but this can be used to change that name without starting a new
        transaction.
    */
    void setCurrentTransactionName (const String& newName);

    /** Returns true if there's at least one action in the list to undo.

        @see getUndoDescription, undo, canRedo
    */
    bool canUndo() const;

    /** Returns the description of the transaction that would be next to get undone.

        The description returned is the one that was passed into beginNewTransaction
        before the set of actions was performed.

        @see undo
    */
    const String getUndoDescription() const;

    /** Tries to roll-back the last transaction.

        @returns    true if the transaction can be undone, and false if it fails, or
                    if there aren't any transactions to undo
    */
    bool undo();

    /** Tries to roll-back any actions that were added to the current transaction.

        This will perform an undo() only if there are some actions in the undo list
        that were added after the last call to beginNewTransaction().

        This is useful because it lets you call beginNewTransaction(), then
        perform an operation which may or may not actually perform some actions, and
        then call this method to get rid of any actions that might have been done
        without it rolling back the previous transaction if nothing was actually
        done.

        @returns true if any actions were undone.
    */
    bool undoCurrentTransactionOnly();

    /** Returns a list of the UndoableAction objects that have been performed during the
        transaction that is currently open.

        Effectively, this is the list of actions that would be undone if undoCurrentTransactionOnly()
        were to be called now.

        The first item in the list is the earliest action performed.
    */
    void getActionsInCurrentTransaction (Array <const UndoableAction*>& actionsFound) const;

    /** Returns true if there's at least one action in the list to redo.

        @see getRedoDescription, redo, canUndo
    */
    bool canRedo() const;

    /** Returns the description of the transaction that would be next to get redone.

        The description returned is the one that was passed into beginNewTransaction
        before the set of actions was performed.

        @see redo
    */
    const String getRedoDescription() const;

    /** Tries to redo the last transaction that was undone.

        @returns    true if the transaction can be redone, and false if it fails, or
                    if there aren't any transactions to redo
    */
    bool redo();

    juce_UseDebuggingNewOperator

private:

    OwnedArray <OwnedArray <UndoableAction> > transactions;
    StringArray transactionNames;
    String currentTransactionName;
    int totalUnitsStored, maxNumUnitsToKeep, minimumTransactionsToKeep, nextIndex;
    bool newTransaction, reentrancyCheck;

    // disallow copy constructor
    UndoManager (const UndoManager&);
    const UndoManager& operator= (const UndoManager&);
};

#endif   // __JUCE_UNDOMANAGER_JUCEHEADER__
/********* End of inlined file: juce_UndoManager.h *********/

class TextEditor;
class TextHolderComponent;

/**
    Receives callbacks from a TextEditor component when it changes.

    @see TextEditor::addListener
*/
class JUCE_API  TextEditorListener
{
public:
    /** Destructor. */
    virtual ~TextEditorListener()  {}

    /** Called when the user changes the text in some way. */
    virtual void textEditorTextChanged (TextEditor& editor) = 0;

    /** Called when the user presses the return key. */
    virtual void textEditorReturnKeyPressed (TextEditor& editor) = 0;

    /** Called when the user presses the escape key. */
    virtual void textEditorEscapeKeyPressed (TextEditor& editor) = 0;

    /** Called when the text editor loses focus. */
    virtual void textEditorFocusLost (TextEditor& editor) = 0;
};

/**
    A component containing text that can be edited.

    A TextEditor can either be in single- or multi-line mode, and supports mixed
    fonts and colours.

    @see TextEditorListener, Label
*/
class JUCE_API  TextEditor  : public Component,
                              public SettableTooltipClient
{
public:

    /** Creates a new, empty text editor.

        @param componentName        the name to pass to the component for it to use as its name
        @param passwordCharacter    if this is not zero, this character will be used as a replacement
                                    for all characters that are drawn on screen - e.g. to create
                                    a password-style textbox containing circular blobs instead of text,
                                    you could set this value to 0x25cf, which is the unicode character
                                    for a black splodge (not all fonts include this, though), or 0x2022,
                                    which is a bullet (probably the best choice for linux).
    */
    TextEditor (const String& componentName = String::empty,
                const tchar passwordCharacter = 0);

    /** Destructor. */
    virtual ~TextEditor();

    /** Puts the editor into either multi- or single-line mode.

        By default, the editor will be in single-line mode, so use this if you need a multi-line
        editor.

        See also the setReturnKeyStartsNewLine() method, which will also need to be turned
        on if you want a multi-line editor with line-breaks.

        @see isMultiLine, setReturnKeyStartsNewLine
    */
    void setMultiLine (const bool shouldBeMultiLine,
                       const bool shouldWordWrap = true);

    /** Returns true if the editor is in multi-line mode.
    */
    bool isMultiLine() const throw();

    /** Changes the behaviour of the return key.

        If set to true, the return key will insert a new-line into the text; if false
        it will trigger a call to the TextEditorListener::textEditorReturnKeyPressed()
        method. By default this is set to false, and when true it will only insert
        new-lines when in multi-line mode (see setMultiLine()).
    */
    void setReturnKeyStartsNewLine (const bool shouldStartNewLine);

    /** Returns the value set by setReturnKeyStartsNewLine().

        See setReturnKeyStartsNewLine() for more info.
    */
    bool getReturnKeyStartsNewLine() const throw()                  { return returnKeyStartsNewLine; }

    /** Indicates whether the tab key should be accepted and used to input a tab character,
        or whether it gets ignored.

        By default the tab key is ignored, so that it can be used to switch keyboard focus
        between components.
    */
    void setTabKeyUsedAsCharacter (const bool shouldTabKeyBeUsed) throw();

    /** Returns true if the tab key is being used for input.
        @see setTabKeyUsedAsCharacter
    */
    bool isTabKeyUsedAsCharacter() const throw()                    { return tabKeyUsed; }

    /** Changes the editor to read-only mode.

        By default, the text editor is not read-only. If you're making it read-only, you
        might also want to call setCaretVisible (false) to get rid of the caret.

        The text can still be highlighted and copied when in read-only mode.

        @see isReadOnly, setCaretVisible
    */
    void setReadOnly (const bool shouldBeReadOnly);

    /** Returns true if the editor is in read-only mode.
    */
    bool isReadOnly() const throw();

    /** Makes the caret visible or invisible.

        By default the caret is visible.

        @see setCaretColour, setCaretPosition
    */
    void setCaretVisible (const bool shouldBeVisible) throw();

    /** Returns true if the caret is enabled.
        @see setCaretVisible
    */
    bool isCaretVisible() const throw()                             { return caretVisible; }

    /** Enables/disables a vertical scrollbar.

        (This only applies when in multi-line mode). When the text gets too long to fit
        in the component, a scrollbar can appear to allow it to be scrolled. Even when
        this is enabled, the scrollbar will be hidden unless it's needed.

        By default the scrollbar is enabled.
    */
    void setScrollbarsShown (bool shouldBeEnabled) throw();

    /** Returns true if scrollbars are enabled.
        @see setScrollbarsShown
    */
    bool areScrollbarsShown() const throw()                         { return scrollbarVisible; }

    /** Changes the password character used to disguise the text.

        @param passwordCharacter    if this is not zero, this character will be used as a replacement
                                    for all characters that are drawn on screen - e.g. to create
                                    a password-style textbox containing circular blobs instead of text,
                                    you could set this value to 0x25cf, which is the unicode character
                                    for a black splodge (not all fonts include this, though), or 0x2022,
                                    which is a bullet (probably the best choice for linux).
    */
    void setPasswordCharacter (const tchar passwordCharacter) throw();

    /** Returns the current password character.
        @see setPasswordCharacter
l    */
    tchar getPasswordCharacter() const throw()                      { return passwordCharacter; }

    /** Allows a right-click menu to appear for the editor.

        (This defaults to being enabled).

        If enabled, right-clicking (or command-clicking on the Mac) will pop up a menu
        of options such as cut/copy/paste, undo/redo, etc.
    */
    void setPopupMenuEnabled (const bool menuEnabled) throw();

    /** Returns true if the right-click menu is enabled.
        @see setPopupMenuEnabled
    */
    bool isPopupMenuEnabled() const throw()                         { return popupMenuEnabled; }

    /** Returns true if a popup-menu is currently being displayed.
    */
    bool isPopupMenuCurrentlyActive() const throw()                 { return menuActive; }

    /** A set of colour IDs to use to change the colour of various aspects of the editor.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId       = 0x1000200, /**< The colour to use for the text component's background - this can be
                                                   transparent if necessary. */

        textColourId             = 0x1000201, /**< The colour that will be used when text is added to the editor. Note
                                                   that because the editor can contain multiple colours, calling this
                                                   method won't change the colour of existing text - to do that, call
                                                   applyFontToAllText() after calling this method.*/

        highlightColourId        = 0x1000202, /**< The colour with which to fill the background of highlighted sections of
                                                   the text - this can be transparent if you don't want to show any
                                                   highlighting.*/

        highlightedTextColourId  = 0x1000203, /**< The colour with which to draw the text in highlighted sections. */

        caretColourId            = 0x1000204, /**< The colour with which to draw the caret. */

        outlineColourId          = 0x1000205, /**< If this is non-transparent, it will be used to draw a box around
                                                   the edge of the component. */

        focusedOutlineColourId   = 0x1000206, /**< If this is non-transparent, it will be used to draw a box around
                                                   the edge of the component when it has focus. */

        shadowColourId           = 0x1000207, /**< If this is non-transparent, it'll be used to draw an inner shadow
                                                   around the edge of the editor. */
    };

    /** Sets the font to use for newly added text.

        This will change the font that will be used next time any text is added or entered
        into the editor. It won't change the font of any existing text - to do that, use
        applyFontToAllText() instead.

        @see applyFontToAllText
    */
    void setFont (const Font& newFont) throw();

    /** Applies a font to all the text in the editor.

        This will also set the current font to use for any new text that's added.

        @see setFont
    */
    void applyFontToAllText (const Font& newFont);

    /** Returns the font that's currently being used for new text.

        @see setFont
    */
    const Font getFont() const throw();

    /** If set to true, focusing on the editor will highlight all its text.

        (Set to false by default).

        This is useful for boxes where you expect the user to re-enter all the
        text when they focus on the component, rather than editing what's already there.
    */
    void setSelectAllWhenFocused (const bool b) throw();

    /** Sets limits on the characters that can be entered.

        @param maxTextLength        if this is > 0, it sets a maximum length limit; if 0, no
                                    limit is set
        @param allowedCharacters    if this is non-empty, then only characters that occur in
                                    this string are allowed to be entered into the editor.
    */
    void setInputRestrictions (const int maxTextLength,
                               const String& allowedCharacters = String::empty) throw();

    /** When the text editor is empty, it can be set to display a message.

        This is handy for things like telling the user what to type in the box - the
        string is only displayed, it's not taken to actually be the contents of
        the editor.
    */
    void setTextToShowWhenEmpty (const String& text, const Colour& colourToUse) throw();

    /** Changes the size of the scrollbars that are used.

        Handy if you need smaller scrollbars for a small text box.
    */
    void setScrollBarThickness (const int newThicknessPixels);

    /** Shows or hides the buttons on any scrollbars that are used.

        @see ScrollBar::setButtonVisibility
    */
    void setScrollBarButtonVisibility (const bool buttonsVisible);

    /** Registers a listener to be told when things happen to the text.

        @see removeListener
    */
    void addListener (TextEditorListener* const newListener) throw();

    /** Deregisters a listener.

        @see addListener
    */
    void removeListener (TextEditorListener* const listenerToRemove) throw();

    /** Returns the entire contents of the editor. */
    const String getText() const throw();

    /** Returns a section of the contents of the editor. */
    const String getTextSubstring (const int startCharacter, const int endCharacter) const throw();

    /** Returns true if there are no characters in the editor.

        This is more efficient than calling getText().isEmpty().
    */
    bool isEmpty() const throw();

    /** Sets the entire content of the editor.

        This will clear the editor and insert the given text (using the current text colour
        and font). You can set the current text colour using
        @code setColour (TextEditor::textColourId, ...);
        @endcode

        @param newText                  the text to add
        @param sendTextChangeMessage    if true, this will cause a change message to
                                        be sent to all the listeners.
        @see insertText
    */
    void setText (const String& newText,
                  const bool sendTextChangeMessage = true);

    /** Inserts some text at the current cursor position.

        If a section of the text is highlighted, it will be replaced by
        this string, otherwise it will be inserted.

        To delete a section of text, you can use setHighlightedRegion() to
        highlight it, and call insertTextAtCursor (String::empty).

        @see setCaretPosition, getCaretPosition, setHighlightedRegion
    */
    void insertTextAtCursor (String textToInsert);

    /** Deletes all the text from the editor. */
    void clear();

    /** Deletes the currently selected region, and puts it on the clipboard.

        @see copy, paste, SystemClipboard
    */
    void cut();

    /** Copies any currently selected region to the clipboard.

        @see cut, paste, SystemClipboard
    */
    void copy();

    /** Pastes the contents of the clipboard into the editor at the cursor position.

        @see cut, copy, SystemClipboard
    */
    void paste();

    /** Moves the caret to be in front of a given character.

        @see getCaretPosition
    */
    void setCaretPosition (const int newIndex) throw();

    /** Returns the current index of the caret.

        @see setCaretPosition
    */
    int getCaretPosition() const throw();

    /** Attempts to scroll the text editor so that the caret ends up at
        a specified position.

        This won't affect the caret's position within the text, it tries to scroll
        the entire editor vertically and horizontally so that the caret is sitting
        at the given position (relative to the top-left of this component).

        Depending on the amount of text available, it might not be possible to
        scroll far enough for the caret to reach this exact position, but it
        will go as far as it can in that direction.
    */
    void scrollEditorToPositionCaret (const int desiredCaretX,
                                      const int desiredCaretY) throw();

    /** Get the graphical position of the caret.

        The rectangle returned is relative to the component's top-left corner.
        @see scrollEditorToPositionCaret
    */
    const Rectangle getCaretRectangle() throw();

    /** Selects a section of the text.
    */
    void setHighlightedRegion (int startIndex,
                               int numberOfCharactersToHighlight) throw();

    /** Returns the first character that is selected.

        If nothing is selected, this will still return a character index, but getHighlightedRegionLength()
        will return 0.

        @see setHighlightedRegion, getHighlightedRegionLength
    */
    int getHighlightedRegionStart() const throw()                       { return selectionStart; }

    /** Returns the number of characters that are selected.

        @see setHighlightedRegion, getHighlightedRegionStart
    */
    int getHighlightedRegionLength() const throw()                      { return jmax (0, selectionEnd - selectionStart); }

    /** Returns the section of text that is currently selected. */
    const String getHighlightedText() const throw();

    /** Finds the index of the character at a given position.

        The co-ordinates are relative to the component's top-left.
    */
    int getTextIndexAt (const int x, const int y) throw();

    /** Counts the number of characters in the text.

        This is quicker than getting the text as a string if you just need to know
        the length.
    */
    int getTotalNumChars() throw();

    /** Returns the total width of the text, as it is currently laid-out.

        This may be larger than the size of the TextEditor, and can change when
        the TextEditor is resized or the text changes.
    */
    int getTextWidth() const throw();

    /** Returns the maximum height of the text, as it is currently laid-out.

        This may be larger than the size of the TextEditor, and can change when
        the TextEditor is resized or the text changes.
    */
    int getTextHeight() const throw();

    /** Changes the size of the gap at the top and left-edge of the editor.

        By default there's a gap of 4 pixels.
    */
    void setIndents (const int newLeftIndent, const int newTopIndent) throw();

    /** Changes the size of border left around the edge of the component.

        @see getBorder
    */
    void setBorder (const BorderSize& border) throw();

    /** Returns the size of border around the edge of the component.

        @see setBorder
    */
    const BorderSize getBorder() const throw();

    /** Used to disable the auto-scrolling which keeps the cursor visible.

        If true (the default), the editor will scroll when the cursor moves offscreen. If
        set to false, it won't.
    */
    void setScrollToShowCursor (const bool shouldScrollToShowCursor) throw();

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void paintOverChildren (Graphics& g);
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseUp (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    void mouseDoubleClick (const MouseEvent& e);
    /** @internal */
    void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
    /** @internal */
    bool keyPressed (const KeyPress& key);
    /** @internal */
    bool keyStateChanged (const bool isKeyDown);
    /** @internal */
    void focusGained (FocusChangeType cause);
    /** @internal */
    void focusLost (FocusChangeType cause);
    /** @internal */
    void resized();
    /** @internal */
    void enablementChanged();
    /** @internal */
    void colourChanged();

    juce_UseDebuggingNewOperator

protected:

    /** This adds the items to the popup menu.

        By default it adds the cut/copy/paste items, but you can override this if
        you need to replace these with your own items.

        If you want to add your own items to the existing ones, you can override this,
        call the base class's addPopupMenuItems() method, then append your own items.

        When the menu has been shown, performPopupMenuAction() will be called to
        perform the item that the user has chosen.

        The default menu items will be added using item IDs in the range
        0x7fff0000 - 0x7fff1000, so you should avoid those values for your own
        menu IDs.

        If this was triggered by a mouse-click, the mouseClickEvent parameter will be
        a pointer to the info about it, or may be null if the menu is being triggered
        by some other means.

        @see performPopupMenuAction, setPopupMenuEnabled, isPopupMenuEnabled
    */
    virtual void addPopupMenuItems (PopupMenu& menuToAddTo,
                                    const MouseEvent* mouseClickEvent);

    /** This is called to perform one of the items that was shown on the popup menu.

        If you've overridden addPopupMenuItems(), you should also override this
        to perform the actions that you've added.

        If you've overridden addPopupMenuItems() but have still left the default items
        on the menu, remember to call the superclass's performPopupMenuAction()
        so that it can perform the default actions if that's what the user clicked on.

        @see addPopupMenuItems, setPopupMenuEnabled, isPopupMenuEnabled
    */
    virtual void performPopupMenuAction (const int menuItemID);

    /** Scrolls the minimum distance needed to get the caret into view. */
    void scrollToMakeSureCursorIsVisible() throw();

    /** @internal */
    void moveCaret (int newCaretPos) throw();

    /** @internal */
    void moveCursorTo (const int newPosition, const bool isSelecting) throw();

    /** Used internally to dispatch a text-change message. */
    void textChanged() throw();

    /** Begins a new transaction in the UndoManager.
    */
    void newTransaction() throw();

    /** Used internally to trigger an undo or redo. */
    void doUndoRedo (const bool isRedo);

    /** Can be overridden to intercept return key presses directly */
    virtual void returnPressed();

    /** Can be overridden to intercept escape key presses directly */
    virtual void escapePressed();

    /** @internal */
    void handleCommandMessage (int commandId);

private:

    Viewport* viewport;
    TextHolderComponent* textHolder;
    BorderSize borderSize;

    bool readOnly                   : 1;
    bool multiline                  : 1;
    bool wordWrap                   : 1;
    bool returnKeyStartsNewLine     : 1;
    bool caretVisible               : 1;
    bool popupMenuEnabled           : 1;
    bool selectAllTextWhenFocused   : 1;
    bool scrollbarVisible           : 1;
    bool wasFocused                 : 1;
    bool caretFlashState            : 1;
    bool keepCursorOnScreen         : 1;
    bool tabKeyUsed                 : 1;
    bool menuActive                 : 1;

    UndoManager undoManager;
    float cursorX, cursorY, cursorHeight;
    int maxTextLength;
    int selectionStart, selectionEnd;
    int leftIndent, topIndent;
    unsigned int lastTransactionTime;
    Font currentFont;
    int totalNumChars, caretPosition;
    VoidArray sections;
    String textToShowWhenEmpty;
    Colour colourForTextWhenEmpty;
    tchar passwordCharacter;

    enum
    {
        notDragging,
        draggingSelectionStart,
        draggingSelectionEnd
    } dragType;

    String allowedCharacters;
    SortedSet <void*> listeners;

    friend class TextEditorInsertAction;
    friend class TextEditorRemoveAction;

    void coalesceSimilarSections() throw();
    void splitSection (const int sectionIndex, const int charToSplitAt) throw();

    void clearInternal (UndoManager* const um) throw();

    void insert (const String& text,
                 const int insertIndex,
                 const Font& font,
                 const Colour& colour,
                 UndoManager* const um,
                 const int caretPositionToMoveTo) throw();

    void reinsert (const int insertIndex,
                   const VoidArray& sections) throw();

    void remove (const int startIndex,
                 int endIndex,
                 UndoManager* const um,
                 const int caretPositionToMoveTo) throw();

    void getCharPosition (const int index,
                          float& x, float& y,
                          float& lineHeight) const throw();

    void updateCaretPosition() throw();

    int indexAtPosition (const float x,
                         const float y) throw();

    int findWordBreakAfter (const int position) const throw();
    int findWordBreakBefore (const int position) const throw();

    friend class TextHolderComponent;
    friend class TextEditorViewport;
    void drawContent (Graphics& g);
    void updateTextHolderSize() throw();
    float getWordWrapWidth() const throw();
    void timerCallbackInt();
    void repaintCaret();
    void repaintText (int textStartIndex, int textEndIndex);

    TextEditor (const TextEditor&);
    const TextEditor& operator= (const TextEditor&);
};

#endif   // __JUCE_TEXTEDITOR_JUCEHEADER__
/********* End of inlined file: juce_TextEditor.h *********/

class Label;

/**
    A class for receiving events from a Label.

    You can register a LabelListener with a Label using the Label::addListener()
    method, and it will be called when the text of the label changes, either because
    of a call to Label::setText() or by the user editing the text (if the label is
    editable).

    @see Label::addListener, Label::removeListener
*/
class JUCE_API  LabelListener
{
public:
    /** Destructor. */
    virtual ~LabelListener() {}

    /** Called when a Label's text has changed.
    */
    virtual void labelTextChanged (Label* labelThatHasChanged) = 0;
};

/**
    A component that displays a text string, and can optionally become a text
    editor when clicked.
*/
class JUCE_API  Label  : public Component,
                         public SettableTooltipClient,
                         protected TextEditorListener,
                         private ComponentListener
{
public:

    /** Creates a Label.

        @param componentName    the name to give the component
        @param labelText        the text to show in the label
    */
    Label (const String& componentName,
           const String& labelText);

    /** Destructor. */
    ~Label();

    /** Changes the label text.

        If broadcastChangeMessage is true and the new text is different to the current
        text, then the class will broadcast a change message to any LabelListeners that
        are registered.
    */
    void setText (const String& newText,
                  const bool broadcastChangeMessage);

    /** Returns the label's current text.

        @param returnActiveEditorContents   if this is true and the label is currently
                                            being edited, then this method will return the
                                            text as it's being shown in the editor. If false,
                                            then the value returned here won't be updated until
                                            the user has finished typing and pressed the return
                                            key.
    */
    const String getText (const bool returnActiveEditorContents = false) const throw();

    /** Changes the font to use to draw the text.

        @see getFont
    */
    void setFont (const Font& newFont) throw();

    /** Returns the font currently being used.

        @see setFont
    */
    const Font& getFont() const throw();

    /** A set of colour IDs to use to change the colour of various aspects of the label.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        Note that you can also use the constants from TextEditor::ColourIds to change the
        colour of the text editor that is opened when a label is editable.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId     = 0x1000280, /**< The background colour to fill the label with. */
        textColourId           = 0x1000281, /**< The colour for the text. */
        outlineColourId        = 0x1000282  /**< An optional colour to use to draw a border around the label.
                                                 Leave this transparent to not have an outline. */
    };

    /** Sets the style of justification to be used for positioning the text.

        (The default is Justification::centredLeft)
    */
    void setJustificationType (const Justification& justification) throw();

    /** Returns the type of justification, as set in setJustificationType(). */
    const Justification getJustificationType() const throw()                    { return justification; }

    /** Changes the gap that is left between the edge of the component and the text.
        By default there's a small gap left at the sides of the component to allow for
        the drawing of the border, but you can change this if necessary.
    */
    void setBorderSize (int horizontalBorder, int verticalBorder);

    /** Returns the size of the horizontal gap being left around the text.
    */
    int getHorizontalBorderSize() const throw()                                 { return horizontalBorderSize; }

    /** Returns the size of the vertical gap being left around the text.
    */
    int getVerticalBorderSize() const throw()                                   { return verticalBorderSize; }

    /** Makes this label "stick to" another component.

        This will cause the label to follow another component around, staying
        either to its left or above it.

        @param owner    the component to follow
        @param onLeft   if true, the label will stay on the left of its component; if
                        false, it will stay above it.
    */
    void attachToComponent (Component* owner,
                            const bool onLeft);

    /** If this label has been attached to another component using attachToComponent, this
        returns the other component.

        Returns 0 if the label is not attached.
    */
    Component* getAttachedComponent() const throw()                             { return ownerComponent; }

    /** If the label is attached to the left of another component, this returns true.

        Returns false if the label is above the other component. This is only relevent if
        attachToComponent() has been called.
    */
    bool isAttachedOnLeft() const throw()                                       { return leftOfOwnerComp; }

    /** Specifies the minimum amount that the font can be squashed horizantally before it starts
        using ellipsis.

        @see Graphics::drawFittedText
    */
    void setMinimumHorizontalScale (const float newScale);

    float getMinimumHorizontalScale() const throw()                             { return minimumHorizontalScale; }

    /** Registers a listener that will be called when the label's text changes. */
    void addListener (LabelListener* const listener) throw();

    /** Deregisters a previously-registered listener. */
    void removeListener (LabelListener* const listener) throw();

    /** Makes the label turn into a TextEditor when clicked.

        By default this is turned off.

        If turned on, then single- or double-clicking will turn the label into
        an editor. If the user then changes the text, then the ChangeBroadcaster
        base class will be used to send change messages to any listeners that
        have registered.

        If the user changes the text, the textWasEdited() method will be called
        afterwards, and subclasses can override this if they need to do anything
        special.

        @param editOnSingleClick            if true, just clicking once on the label will start editing the text
        @param editOnDoubleClick            if true, a double-click is needed to start editing
        @param lossOfFocusDiscardsChanges   if true, clicking somewhere else while the text is being
                                            edited will discard any changes; if false, then this will
                                            commit the changes.
        @see showEditor, setEditorColours, TextEditor
    */
    void setEditable (const bool editOnSingleClick,
                      const bool editOnDoubleClick = false,
                      const bool lossOfFocusDiscardsChanges = false) throw();

    /** Returns true if this option was set using setEditable(). */
    bool isEditableOnSingleClick() const throw()                        { return editSingleClick; }

    /** Returns true if this option was set using setEditable(). */
    bool isEditableOnDoubleClick() const throw()                        { return editDoubleClick; }

    /** Returns true if this option has been set in a call to setEditable(). */
    bool doesLossOfFocusDiscardChanges() const throw()                  { return lossOfFocusDiscardsChanges; }

    /** Returns true if the user can edit this label's text. */
    bool isEditable() const throw()                                     { return editSingleClick || editDoubleClick; }

    /** Makes the editor appear as if the label had been clicked by the user.

        @see textWasEdited, setEditable
    */
    void showEditor();

    /** Hides the editor if it was being shown.

        @param discardCurrentEditorContents     if true, the label's text will be
                                                reset to whatever it was before the editor
                                                was shown; if false, the current contents of the
                                                editor will be used to set the label's text
                                                before it is hidden.
    */
    void hideEditor (const bool discardCurrentEditorContents);

    /** Returns true if the editor is currently focused and active. */
    bool isBeingEdited() const throw();

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void mouseUp (const MouseEvent& e);
    /** @internal */
    void mouseDoubleClick (const MouseEvent& e);
    /** @internal */
    void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized);
    /** @internal */
    void componentParentHierarchyChanged (Component& component);
    /** @internal */
    void componentVisibilityChanged (Component& component);
    /** @internal */
    void inputAttemptWhenModal();
    /** @internal */
    void focusGained (FocusChangeType);
    /** @internal */
    void enablementChanged();
    /** @internal */
    KeyboardFocusTraverser* createFocusTraverser();
    /** @internal */
    void textEditorTextChanged (TextEditor& editor);
    /** @internal */
    void textEditorReturnKeyPressed (TextEditor& editor);
    /** @internal */
    void textEditorEscapeKeyPressed (TextEditor& editor);
    /** @internal */
    void textEditorFocusLost (TextEditor& editor);
    /** @internal */
    void colourChanged();

    /** Creates the TextEditor component that will be used when the user has clicked on the label.

        Subclasses can override this if they need to customise this component in some way.
    */
    virtual TextEditor* createEditorComponent();

    /** Called after the user changes the text.
    */
    virtual void textWasEdited();

    /** Called when the text has been altered.
    */
    virtual void textWasChanged();

    /** Called when the text editor has just appeared, due to a user click or other
        focus change.
    */
    virtual void editorShown (TextEditor* editorComponent);

    /** Called when the text editor is going to be deleted, after editing has finished.
    */
    virtual void editorAboutToBeHidden (TextEditor* editorComponent);

private:
    String text;
    Font font;
    Justification justification;
    TextEditor* editor;
    SortedSet <void*> listeners;
    Component* ownerComponent;
    ComponentDeletionWatcher* deletionWatcher;
    int horizontalBorderSize, verticalBorderSize;
    float minimumHorizontalScale;
    bool editSingleClick : 1;
    bool editDoubleClick : 1;
    bool lossOfFocusDiscardsChanges : 1;
    bool leftOfOwnerComp : 1;

    bool updateFromTextEditorContents();
    void callChangeListeners();

    Label (const Label&);
    const Label& operator= (const Label&);
};

#endif   // __JUCE_LABEL_JUCEHEADER__
/********* End of inlined file: juce_Label.h *********/

class ComboBox;

/**
    A class for receiving events from a ComboBox.

    You can register a ComboBoxListener with a ComboBox using the ComboBox::addListener()
    method, and it will be called when the selected item in the box changes.

    @see ComboBox::addListener, ComboBox::removeListener
*/
class JUCE_API  ComboBoxListener
{
public:
    /** Destructor. */
    virtual ~ComboBoxListener() {}

    /** Called when a ComboBox has its selected item changed.
    */
    virtual void comboBoxChanged (ComboBox* comboBoxThatHasChanged) = 0;
};

/**
    A component that lets the user choose from a drop-down list of choices.

    The combo-box has a list of text strings, each with an associated id number,
    that will be shown in the drop-down list when the user clicks on the component.

    The currently selected choice is displayed in the combo-box, and this can
    either be read-only text, or editable.

    To find out when the user selects a different item or edits the text, you
    can register a ComboBoxListener to receive callbacks.

    @see ComboBoxListener
*/
class JUCE_API  ComboBox  : public Component,
                            public SettableTooltipClient,
                            private LabelListener,
                            private AsyncUpdater
{
public:

    /** Creates a combo-box.

        On construction, the text field will be empty, so you should call the
        setSelectedId() or setText() method to choose the initial value before
        displaying it.

        @param componentName    the name to set for the component (see Component::setName())
    */
    ComboBox (const String& componentName);

    /** Destructor. */
    ~ComboBox();

    /** Sets whether the test in the combo-box is editable.

        The default state for a new ComboBox is non-editable, and can only be changed
        by choosing from the drop-down list.
    */
    void setEditableText (const bool isEditable);

    /** Returns true if the text is directly editable.
        @see setEditableText
    */
    bool isTextEditable() const throw();

    /** Sets the style of justification to be used for positioning the text.

        The default is Justification::centredLeft. The text is displayed using a
        Label component inside the ComboBox.
    */
    void setJustificationType (const Justification& justification) throw();

    /** Returns the current justification for the text box.
        @see setJustificationType
    */
    const Justification getJustificationType() const throw();

    /** Adds an item to be shown in the drop-down list.

        @param newItemText      the text of the item to show in the list
        @param newItemId        an associated ID number that can be set or retrieved - see
                                getSelectedId() and setSelectedId()
        @see setItemEnabled, addSeparator, addSectionHeading, removeItem, getNumItems, getItemText, getItemId
    */
    void addItem (const String& newItemText,
                  const int newItemId) throw();

    /** Adds a separator line to the drop-down list.

        This is like adding a separator to a popup menu. See PopupMenu::addSeparator().
    */
    void addSeparator() throw();

    /** Adds a heading to the drop-down list, so that you can group the items into
        different sections.

        The headings are indented slightly differently to set them apart from the
        items on the list, and obviously can't be selected. You might want to add
        separators between your sections too.

        @see addItem, addSeparator
    */
    void addSectionHeading (const String& headingName) throw();

    /** This allows items in the drop-down list to be selectively disabled.

        When you add an item, it's enabled by default, but you can call this
        method to change its status.

        If you disable an item which is already selected, this won't change the
        current selection - it just stops the user choosing that item from the list.
    */
    void setItemEnabled (const int itemId,
                         const bool isEnabled) throw();

    /** Changes the text for an existing item.
    */
    void changeItemText (const int itemId,
                         const String& newText) throw();

    /** Removes all the items from the drop-down list.

        If this call causes the content to be cleared, then a change-message
        will be broadcast unless dontSendChangeMessage is true.

        @see addItem, removeItem, getNumItems
    */
    void clear (const bool dontSendChangeMessage = false);

    /** Returns the number of items that have been added to the list.

        Note that this doesn't include headers or separators.
    */
    int getNumItems() const throw();

    /** Returns the text for one of the items in the list.

        Note that this doesn't include headers or separators.

        @param index    the item's index from 0 to (getNumItems() - 1)
    */
    const String getItemText (const int index) const throw();

    /** Returns the ID for one of the items in the list.

        Note that this doesn't include headers or separators.

        @param index    the item's index from 0 to (getNumItems() - 1)
    */
    int getItemId (const int index) const throw();

    /** Returns the ID of the item that's currently shown in the box.

        If no item is selected, or if the text is editable and the user
        has entered something which isn't one of the items in the list, then
        this will return 0.

        @see setSelectedId, getSelectedItemIndex, getText
    */
    int getSelectedId() const throw();

    /** Sets one of the items to be the current selection.

        This will set the ComboBox's text to that of the item that matches
        this ID.

        @param newItemId                the new item to select
        @param dontSendChangeMessage    if set to true, this method won't trigger a
                                        change notification
        @see getSelectedId, setSelectedItemIndex, setText
    */
    void setSelectedId (const int newItemId,
                        const bool dontSendChangeMessage = false) throw();

    /** Returns the index of the item that's currently shown in the box.

        If no item is selected, or if the text is editable and the user
        has entered something which isn't one of the items in the list, then
        this will return -1.

        @see setSelectedItemIndex, getSelectedId, getText
    */
    int getSelectedItemIndex() const throw();

    /** Sets one of the items to be the current selection.

        This will set the ComboBox's text to that of the item at the given
        index in the list.

        @param newItemIndex             the new item to select
        @param dontSendChangeMessage    if set to true, this method won't trigger a
                                        change notification
        @see getSelectedItemIndex, setSelectedId, setText
    */
    void setSelectedItemIndex (const int newItemIndex,
                               const bool dontSendChangeMessage = false) throw();

    /** Returns the text that is currently shown in the combo-box's text field.

        If the ComboBox has editable text, then this text may have been edited
        by the user; otherwise it will be one of the items from the list, or
        possibly an empty string if nothing was selected.

        @see setText, getSelectedId, getSelectedItemIndex
    */
    const String getText() const throw();

    /** Sets the contents of the combo-box's text field.

        The text passed-in will be set as the current text regardless of whether
        it is one of the items in the list. If the current text isn't one of the
        items, then getSelectedId() will return -1, otherwise it wil return
        the approriate ID.

        @param newText                  the text to select
        @param dontSendChangeMessage    if set to true, this method won't trigger a
                                        change notification
        @see getText
    */
    void setText (const String& newText,
                  const bool dontSendChangeMessage = false) throw();

    /** Programmatically opens the text editor to allow the user to edit the current item.

        This is the same effect as when the box is clicked-on.
        @see Label::showEditor();
    */
    void showEditor();

    /** Registers a listener that will be called when the box's content changes. */
    void addListener (ComboBoxListener* const listener) throw();

    /** Deregisters a previously-registered listener. */
    void removeListener (ComboBoxListener* const listener) throw();

    /** Sets a message to display when there is no item currently selected.

        @see getTextWhenNothingSelected
    */
    void setTextWhenNothingSelected (const String& newMessage) throw();

    /** Returns the text that is shown when no item is selected.

        @see setTextWhenNothingSelected
    */
    const String getTextWhenNothingSelected() const throw();

    /** Sets the message to show when there are no items in the list, and the user clicks
        on the drop-down box.

        By default it just says "no choices", but this lets you change it to something more
        meaningful.
    */
    void setTextWhenNoChoicesAvailable (const String& newMessage) throw();

    /** Returns the text shown when no items have been added to the list.
        @see setTextWhenNoChoicesAvailable
    */
    const String getTextWhenNoChoicesAvailable() const throw();

    /** Gives the ComboBox a tooltip. */
    void setTooltip (const String& newTooltip);

    /** A set of colour IDs to use to change the colour of various aspects of the combo box.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        To change the colours of the menu that pops up

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId  = 0x1000b00,    /**< The background colour to fill the box with. */
        textColourId        = 0x1000a00,    /**< The colour for the text in the box. */
        outlineColourId     = 0x1000c00,    /**< The colour for an outline around the box. */
        buttonColourId      = 0x1000d00,    /**< The base colour for the button (a LookAndFeel class will probably use variations on this). */
        arrowColourId       = 0x1000e00,    /**< The colour for the arrow shape that pops up the menu */
    };

    /** @internal */
    void labelTextChanged (Label*);
    /** @internal */
    void enablementChanged();
    /** @internal */
    void colourChanged();
    /** @internal */
    void focusGained (Component::FocusChangeType cause);
    /** @internal */
    void focusLost (Component::FocusChangeType cause);
    /** @internal */
    void handleAsyncUpdate();
    /** @internal */
    const String getTooltip()                                       { return label->getTooltip(); }
    /** @internal */
    void mouseDown (const MouseEvent&);
    /** @internal */
    void mouseDrag (const MouseEvent&);
    /** @internal */
    void mouseUp (const MouseEvent&);
    /** @internal */
    void lookAndFeelChanged();
    /** @internal */
    void paint (Graphics&);
    /** @internal */
    void resized();
    /** @internal */
    bool keyStateChanged (const bool isKeyDown);
    /** @internal */
    bool keyPressed (const KeyPress&);

    juce_UseDebuggingNewOperator

private:
    struct ItemInfo
    {
        String name;
        int itemId;
        bool isEnabled : 1, isHeading : 1;

        bool isSeparator() const throw();
        bool isRealItem() const throw();
    };

    OwnedArray <ItemInfo> items;
    int currentIndex;
    bool isButtonDown;
    bool separatorPending;
    bool menuActive;
    SortedSet <void*> listeners;
    Label* label;
    String textWhenNothingSelected, noChoicesMessage;

    void showPopup();

    ItemInfo* getItemForId (const int itemId) const throw();
    ItemInfo* getItemForIndex (const int index) const throw();

    ComboBox (const ComboBox&);
    const ComboBox& operator= (const ComboBox&);
};

#endif   // __JUCE_COMBOBOX_JUCEHEADER__
/********* End of inlined file: juce_ComboBox.h *********/

/**
    Manages the state of some audio and midi i/o devices.

    This class keeps tracks of a currently-selected audio device, through
    with which it continuously streams data from an audio callback, as well as
    one or more midi inputs.

    The idea is that your application will create one global instance of this object,
    and let it take care of creating and deleting specific types of audio devices
    internally. So when the device is changed, your callbacks will just keep running
    without having to worry about this.

    The manager can save and reload all of its device settings as XML, which
    makes it very easy for you to save and reload the audio setup of your
    application.

    And to make it easy to let the user change its settings, there's a component
    to do just that - the AudioDeviceSelectorComponent class, which contains a set of
    device selection/sample-rate/latency controls.

    To use an AudioDeviceManager, create one, and use initialise() to set it up. Then
    call addAudioCallback() to register your audio callback with it, and use that to process
    your audio data.

    The manager also acts as a handy hub for incoming midi messages, allowing a
    listener to register for messages from either a specific midi device, or from whatever
    the current default midi input device is. The listener then doesn't have to worry about
    re-registering with different midi devices if they are changed or deleted.

    And yet another neat trick is that amount of CPU time being used is measured and
    available with the getCpuUsage() method.

    The AudioDeviceManager is a ChangeBroadcaster, and will send a change message to
    listeners whenever one of its settings is changed.

    @see AudioDeviceSelectorComponent, AudioIODevice, AudioIODeviceType
*/
class JUCE_API  AudioDeviceManager  : public ChangeBroadcaster
{
public:

    /** Creates a default AudioDeviceManager.

        Initially no audio device will be selected. You should call the initialise() method
        and register an audio callback with setAudioCallback() before it'll be able to
        actually make any noise.
    */
    AudioDeviceManager();

    /** Destructor. */
    ~AudioDeviceManager();

    /**
        This structure holds a set of properties describing the current audio setup.

        @see AudioDeviceManager::setAudioDeviceSetup()
    */
    struct JUCE_API  AudioDeviceSetup
    {
        AudioDeviceSetup();
        bool operator== (const AudioDeviceSetup& other) const;

        /** The name of the audio device used for output.
            This may be the same as the input device.
        */
        String outputDeviceName;

        /** The name of the audio device used for input.
            This may be the same as the output device.
        */
        String inputDeviceName;

        /** The current sample rate.
            This rate is used for both the input and output devices.
        */
        double sampleRate;

        /** The buffer size, in samples.
            This buffer size is used for both the input and output devices.
        */
        int bufferSize;

        /** The set of active input channels.
            The bits that are set in this array indicate the channels of the
            input device that are active.
        */
        BitArray inputChannels;

        /** If this is true, it indicates that the inputChannels array
            should be ignored, and instead, the device's default channels
            should be used.
        */
        bool useDefaultInputChannels;

        /** The set of active output channels.
            The bits that are set in this array indicate the channels of the
            input device that are active.
        */
        BitArray outputChannels;

        /** If this is true, it indicates that the outputChannels array
            should be ignored, and instead, the device's default channels
            should be used.
        */
        bool useDefaultOutputChannels;
    };

    /** Opens a set of audio devices ready for use.

        This will attempt to open either a default audio device, or one that was
        previously saved as XML.

        @param numInputChannelsNeeded       a minimum number of input channels needed
                                            by your app.
        @param numOutputChannelsNeeded      a minimum number of output channels to open
        @param savedState                   either a previously-saved state that was produced
                                            by createStateXml(), or 0 if you want the manager
                                            to choose the best device to open.
        @param selectDefaultDeviceOnFailure if true, then if the device specified in the XML
                                            fails to open, then a default device will be used
                                            instead. If false, then on failure, no device is
                                            opened.
        @param preferredDefaultDeviceName   if this is not empty, and there's a device with this
                                            name, then that will be used as the default device
                                            (assuming that there wasn't one specified in the XML).
                                            The string can actually be a simple wildcard, containing "*"
                                            and "?" characters
        @param preferredSetupOptions        if this is non-null, the structure will be used as the
                                            set of preferred settings when opening the device. If you
                                            use this parameter, the preferredDefaultDeviceName
                                            field will be ignored

        @returns an error message if anything went wrong, or an empty string if it worked ok.
    */
    const String initialise (const int numInputChannelsNeeded,
                             const int numOutputChannelsNeeded,
                             const XmlElement* const savedState,
                             const bool selectDefaultDeviceOnFailure,
                             const String& preferredDefaultDeviceName = String::empty,
                             const AudioDeviceSetup* preferredSetupOptions = 0);

    /** Returns some XML representing the current state of the manager.

        This stores the current device, its samplerate, block size, etc, and
        can be restored later with initialise().
    */
    XmlElement* createStateXml() const;

    /** Returns the current device properties that are in use.

        @see setAudioDeviceSetup
    */
    void getAudioDeviceSetup (AudioDeviceSetup& setup);

    /** Changes the current device or its settings.

        If you want to change a device property, like the current sample rate or
        block size, you can call getAudioDeviceSetup() to retrieve the current
        settings, then tweak the appropriate fields in the AudioDeviceSetup structure,
        and pass it back into this method to apply the new settings.

        @param newSetup             the settings that you'd like to use
        @param treatAsChosenDevice  if this is true and if the device opens correctly, these new
                                    settings will be taken as having been explicitly chosen by the
                                    user, and the next time createStateXml() is called, these settings
                                    will be returned. If it's false, then the device is treated as a
                                    temporary or default device, and a call to createStateXml() will
                                    return either the last settings that were made with treatAsChosenDevice
                                    as true, or the last XML settings that were passed into initialise().
        @returns an error message if anything went wrong, or an empty string if it worked ok.

        @see getAudioDeviceSetup
    */
    const String setAudioDeviceSetup (const AudioDeviceSetup& newSetup,
                                      const bool treatAsChosenDevice);

    /** Returns the currently-active audio device. */
    AudioIODevice* getCurrentAudioDevice() const throw()                { return currentAudioDevice; }

    /** Returns the type of audio device currently in use.
        @see setCurrentAudioDeviceType
    */
    const String getCurrentAudioDeviceType() const throw()              { return currentDeviceType; }

    /** Changes the class of audio device being used.

        This switches between, e.g. ASIO and DirectSound. On the Mac you probably won't ever call
        this because there's only one type: CoreAudio.

        For a list of types, see getAvailableDeviceTypes().
    */
    void setCurrentAudioDeviceType (const String& type,
                                    const bool treatAsChosenDevice);

    /** Closes the currently-open device.

        You can call restartLastAudioDevice() later to reopen it in the same state
        that it was just in.
    */
    void closeAudioDevice();

    /** Tries to reload the last audio device that was running.

        Note that this only reloads the last device that was running before
        closeAudioDevice() was called - it doesn't reload any kind of saved-state,
        and can only be called after a device has been opened with SetAudioDevice().

        If a device is already open, this call will do nothing.
    */
    void restartLastAudioDevice();

    /** Registers an audio callback to be used.

        The manager will redirect callbacks from whatever audio device is currently
        in use to all registered callback objects. If more than one callback is
        active, they will all be given the same input data, and their outputs will
        be summed.

        If necessary, this method will invoke audioDeviceAboutToStart() on the callback
        object before returning.

        To remove a callback, use removeAudioCallback().
    */
    void addAudioCallback (AudioIODeviceCallback* newCallback);

    /** Deregisters a previously added callback.

        If necessary, this method will invoke audioDeviceStopped() on the callback
        object before returning.

        @see addAudioCallback
    */
    void removeAudioCallback (AudioIODeviceCallback* callback);

    /** Returns the average proportion of available CPU being spent inside the audio callbacks.

        Returns a value between 0 and 1.0
    */
    double getCpuUsage() const;

    /** Enables or disables a midi input device.

        The list of devices can be obtained with the MidiInput::getDevices() method.

        Any incoming messages from enabled input devices will be forwarded on to all the
        listeners that have been registered with the addMidiInputCallback() method. They
        can either register for messages from a particular device, or from just the
        "default" midi input.

        Routing the midi input via an AudioDeviceManager means that when a listener
        registers for the default midi input, this default device can be changed by the
        manager without the listeners having to know about it or re-register.

        It also means that a listener can stay registered for a midi input that is disabled
        or not present, so that when the input is re-enabled, the listener will start
        receiving messages again.

        @see addMidiInputCallback, isMidiInputEnabled
    */
    void setMidiInputEnabled (const String& midiInputDeviceName,
                              const bool enabled);

    /** Returns true if a given midi input device is being used.

        @see setMidiInputEnabled
    */
    bool isMidiInputEnabled (const String& midiInputDeviceName) const;

    /** Registers a listener for callbacks when midi events arrive from a midi input.

        The device name can be empty to indicate that it wants events from whatever the
        current "default" device is. Or it can be the name of one of the midi input devices
        (see MidiInput::getDevices() for the names).

        Only devices which are enabled (see the setMidiInputEnabled() method) will have their
        events forwarded on to listeners.
    */
    void addMidiInputCallback (const String& midiInputDeviceName,
                               MidiInputCallback* callback);

    /** Removes a listener that was previously registered with addMidiInputCallback().
    */
    void removeMidiInputCallback (const String& midiInputDeviceName,
                                  MidiInputCallback* callback);

    /** Sets a midi output device to use as the default.

        The list of devices can be obtained with the MidiOutput::getDevices() method.

        The specified device will be opened automatically and can be retrieved with the
        getDefaultMidiOutput() method.

        Pass in an empty string to deselect all devices. For the default device, you
        can use MidiOutput::getDevices() [MidiOutput::getDefaultDeviceIndex()].

        @see getDefaultMidiOutput, getDefaultMidiOutputName
    */
    void setDefaultMidiOutput (const String& deviceName);

    /** Returns the name of the default midi output.

        @see setDefaultMidiOutput, getDefaultMidiOutput
    */
    const String getDefaultMidiOutputName() const throw()           { return defaultMidiOutputName; }

    /** Returns the current default midi output device.

        If no device has been selected, or the device can't be opened, this will
        return 0.

        @see getDefaultMidiOutputName
    */
    MidiOutput* getDefaultMidiOutput() const throw()                { return defaultMidiOutput; }

    /** Returns a list of the types of device supported.
    */
    const OwnedArray <AudioIODeviceType>& getAvailableDeviceTypes();

    /** Creates a list of available types.

        This will add a set of new AudioIODeviceType objects to the specified list, to
        represent each available types of device.

        You can override this if your app needs to do something specific, like avoid
        using DirectSound devices, etc.
    */
    virtual void createAudioDeviceTypes (OwnedArray <AudioIODeviceType>& types);

    /** Plays a beep through the current audio device.

        This is here to allow the audio setup UI panels to easily include a "test"
        button so that the user can check where the audio is coming from.
    */
    void playTestSound();

    /** Turns on level-measuring.

        When enabled, the device manager will measure the peak input level
        across all channels, and you can get this level by calling getCurrentInputLevel().

        This is mainly intended for audio setup UI panels to use to create a mic
        level display, so that the user can check that they've selected the right
        device.

        A simple filter is used to make the level decay smoothly, but this is
        only intended for giving rough feedback, and not for any kind of accurate
        measurement.
    */
    void enableInputLevelMeasurement (const bool enableMeasurement);

    /** Returns the current input level.

        To use this, you must first enable it by calling enableInputLevelMeasurement().

        See enableInputLevelMeasurement() for more info.
    */
    double getCurrentInputLevel() const;

    juce_UseDebuggingNewOperator

private:

    OwnedArray <AudioIODeviceType> availableDeviceTypes;
    OwnedArray <AudioDeviceSetup> lastDeviceTypeConfigs;

    AudioDeviceSetup currentSetup;
    AudioIODevice* currentAudioDevice;
    SortedSet <AudioIODeviceCallback*> callbacks;
    int numInputChansNeeded, numOutputChansNeeded;
    String currentDeviceType;
    BitArray inputChannels, outputChannels;
    XmlElement* lastExplicitSettings;
    mutable bool listNeedsScanning;
    bool useInputNames;
    int inputLevelMeasurementEnabledCount;
    double inputLevel;
    AudioSampleBuffer* testSound;
    int testSoundPosition;
    AudioSampleBuffer tempBuffer;

    StringArray midiInsFromXml;
    OwnedArray <MidiInput> enabledMidiInputs;
    Array <MidiInputCallback*> midiCallbacks;
    Array <MidiInput*> midiCallbackDevices;
    String defaultMidiOutputName;
    MidiOutput* defaultMidiOutput;
    CriticalSection audioCallbackLock, midiCallbackLock;

    double cpuUsageMs, timeToCpuScale;

    class CallbackHandler  : public AudioIODeviceCallback,
                             public MidiInputCallback
    {
    public:
        AudioDeviceManager* owner;

        void audioDeviceIOCallback (const float** inputChannelData,
                                    int totalNumInputChannels,
                                    float** outputChannelData,
                                    int totalNumOutputChannels,
                                    int numSamples);

        void audioDeviceAboutToStart (AudioIODevice*);

        void audioDeviceStopped();

        void handleIncomingMidiMessage (MidiInput* source, const MidiMessage& message);
    };

    CallbackHandler callbackHandler;
    friend class CallbackHandler;

    void audioDeviceIOCallbackInt (const float** inputChannelData,
                                   int totalNumInputChannels,
                                   float** outputChannelData,
                                   int totalNumOutputChannels,
                                   int numSamples);
    void audioDeviceAboutToStartInt (AudioIODevice* const device);
    void audioDeviceStoppedInt();

    void handleIncomingMidiMessageInt (MidiInput* source, const MidiMessage& message);

    const String restartDevice (int blockSizeToUse, double sampleRateToUse,
                                const BitArray& ins, const BitArray& outs);
    void stopDevice();

    void updateXml();

    void createDeviceTypesIfNeeded();
    void scanDevicesIfNeeded();
    void deleteCurrentDevice();
    double chooseBestSampleRate (double preferred) const;
    AudioIODeviceType* getCurrentDeviceTypeObject() const;
    void insertDefaultDeviceNames (AudioDeviceSetup& setup) const;

    AudioIODeviceType* findType (const String& inputName, const String& outputName);

    AudioDeviceManager (const AudioDeviceManager&);
    const AudioDeviceManager& operator= (const AudioDeviceManager&);
};

#endif   // __JUCE_AUDIODEVICEMANAGER_JUCEHEADER__
/********* End of inlined file: juce_AudioDeviceManager.h *********/

#endif
#ifndef __JUCE_MIDIOUTPUT_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOIODEVICETYPE_JUCEHEADER__

#endif
#ifndef __JUCE_SAMPLER_JUCEHEADER__

/********* Start of inlined file: juce_Sampler.h *********/
#ifndef __JUCE_SAMPLER_JUCEHEADER__
#define __JUCE_SAMPLER_JUCEHEADER__

/********* Start of inlined file: juce_Synthesiser.h *********/
#ifndef __JUCE_SYNTHESISER_JUCEHEADER__
#define __JUCE_SYNTHESISER_JUCEHEADER__

/**
    Describes one of the sounds that a Synthesiser can play.

    A synthesiser can contain one or more sounds, and a sound can choose which
    midi notes and channels can trigger it.

    The SynthesiserSound is a passive class that just describes what the sound is -
    the actual audio rendering for a sound is done by a SynthesiserVoice. This allows
    more than one SynthesiserVoice to play the same sound at the same time.

    @see Synthesiser, SynthesiserVoice
*/
class JUCE_API  SynthesiserSound    : public ReferenceCountedObject
{
protected:

    SynthesiserSound();

public:
    /** Destructor. */
    virtual ~SynthesiserSound();

    /** Returns true if this sound should be played when a given midi note is pressed.

        The Synthesiser will use this information when deciding which sounds to trigger
        for a given note.
    */
    virtual bool appliesToNote (const int midiNoteNumber) = 0;

    /** Returns true if the sound should be triggered by midi events on a given channel.

        The Synthesiser will use this information when deciding which sounds to trigger
        for a given note.
    */
    virtual bool appliesToChannel (const int midiChannel) = 0;

    /**
    */
    typedef ReferenceCountedObjectPtr <SynthesiserSound> Ptr;

    juce_UseDebuggingNewOperator
};

/**
    Represents a voice that a Synthesiser can use to play a SynthesiserSound.

    A voice plays a single sound at a time, and a synthesiser holds an array of
    voices so that it can play polyphonically.

    @see Synthesiser, SynthesiserSound
*/
class JUCE_API  SynthesiserVoice
{
public:

    /** Creates a voice. */
    SynthesiserVoice();

    /** Destructor. */
    virtual ~SynthesiserVoice();

    /** Returns the midi note that this voice is currently playing.

        Returns a value less than 0 if no note is playing.
    */
    int getCurrentlyPlayingNote() const throw()                     { return currentlyPlayingNote; }

    /** Returns the sound that this voice is currently playing.

        Returns 0 if it's not playing.
    */
    const SynthesiserSound::Ptr getCurrentlyPlayingSound() const throw()      { return currentlyPlayingSound; }

    /** Must return true if this voice object is capable of playing the given sound.

        If there are different classes of sound, and different classes of voice, a voice can
        choose which ones it wants to take on.

        A typical implementation of this method may just return true if there's only one type
        of voice and sound, or it might check the type of the sound object passed-in and
        see if it's one that it understands.
    */
    virtual bool canPlaySound (SynthesiserSound* sound) = 0;

    /** Called to start a new note.

        This will be called during the rendering callback, so must be fast and thread-safe.
    */
    virtual void startNote (const int midiNoteNumber,
                            const float velocity,
                            SynthesiserSound* sound,
                            const int currentPitchWheelPosition) = 0;

    /** Called to stop a note.

        This will be called during the rendering callback, so must be fast and thread-safe.

        If allowTailOff is false or the voice doesn't want to tail-off, then it must stop all
        sound immediately, and must call clearCurrentNote() to reset the state of this voice
        and allow the synth to reassign it another sound.

        If allowTailOff is true and the voice decides to do a tail-off, then it's allowed to
        begin fading out its sound, and it can stop playing until it's finished. As soon as it
        finishes playing (during the rendering callback), it must make sure that it calls
        clearCurrentNote().
    */
    virtual void stopNote (const bool allowTailOff) = 0;

    /** Called to let the voice know that the pitch wheel has been moved.

        This will be called during the rendering callback, so must be fast and thread-safe.
    */
    virtual void pitchWheelMoved (const int newValue) = 0;

    /** Called to let the voice know that a midi controller has been moved.

        This will be called during the rendering callback, so must be fast and thread-safe.
    */
    virtual void controllerMoved (const int controllerNumber,
                                  const int newValue) = 0;

    /** Renders the next block of data for this voice.

        The output audio data must be added to the current contents of the buffer provided.
        Only the region of the buffer between startSample and (startSample + numSamples)
        should be altered by this method.

        If the voice is currently silent, it should just return without doing anything.

        If the sound that the voice is playing finishes during the course of this rendered
        block, it must call clearCurrentNote(), to tell the synthesiser that it has finished.

        The size of the blocks that are rendered can change each time it is called, and may
        involve rendering as little as 1 sample at a time. In between rendering callbacks,
        the voice's methods will be called to tell it about note and controller events.
    */
    virtual void renderNextBlock (AudioSampleBuffer& outputBuffer,
                                  int startSample,
                                  int numSamples) = 0;

    /** Returns true if the voice is currently playing a sound which is mapped to the given
        midi channel.

        If it's not currently playing, this will return false.
    */
    bool isPlayingChannel (const int midiChannel) const;

    /** Changes the voice's reference sample rate.

        The rate is set so that subclasses know the output rate and can set their pitch
        accordingly.

        This method is called by the synth, and subclasses can access the current rate with
        the currentSampleRate member.
    */
    void setCurrentPlaybackSampleRate (const double newRate);

    juce_UseDebuggingNewOperator

protected:

    /** Returns the current target sample rate at which rendering is being done.

        This is available for subclasses so they can pitch things correctly.
    */
    double getSampleRate() const throw()                        { return currentSampleRate; }

    /** Resets the state of this voice after a sound has finished playing.

        The subclass must call this when it finishes playing a note and becomes available
        to play new ones.

        It must either call it in the stopNote() method, or if the voice is tailing off,
        then it should call it later during the renderNextBlock method, as soon as it
        finishes its tail-off.

        It can also be called at any time during the render callback if the sound happens
        to have finished, e.g. if it's playing a sample and the sample finishes.
    */
    void clearCurrentNote();

private:

    friend class Synthesiser;

    double currentSampleRate;
    int currentlyPlayingNote;
    uint32 noteOnTime;
    SynthesiserSound::Ptr currentlyPlayingSound;
};

/**
    Base class for a musical device that can play sounds.

    To create a synthesiser, you'll need to create a subclass of SynthesiserSound
    to describe each sound available to your synth, and a subclass of SynthesiserVoice
    which can play back one of these sounds.

    Then you can use the addVoice() and addSound() methods to give the synthesiser a
    set of sounds, and a set of voices it can use to play them. If you only give it
    one voice it will be monophonic - the more voices it has, the more polyphony it'll
    have available.

    Then repeatedly call the renderNextBlock() method to produce the audio. Any midi
    events that go in will be scanned for note on/off messages, and these are used to
    start and stop the voices playing the appropriate sounds.

    While it's playing, you can also cause notes to be triggered by calling the noteOn(),
    noteOff() and other controller methods.

    Before rendering, be sure to call the setCurrentPlaybackSampleRate() to tell it
    what the target playback rate is. This value is passed on to the voices so that
    they can pitch their output correctly.
*/
class JUCE_API  Synthesiser
{
public:

    /** Creates a new synthesiser.

        You'll need to add some sounds and voices before it'll make any sound..
    */
    Synthesiser();

    /** Destructor. */
    virtual ~Synthesiser();

    /** Deletes all voices. */
    void clearVoices();

    /** Returns the number of voices that have been added. */
    int getNumVoices() const throw()                                { return voices.size(); }

    /** Returns one of the voices that have been added. */
    SynthesiserVoice* getVoice (const int index) const throw();

    /** Adds a new voice to the synth.

        All the voices should be the same class of object and are treated equally.

        The object passed in will be managed by the synthesiser, which will delete
        it later on when no longer needed. The caller should not retain a pointer to the
        voice.
    */
    void addVoice (SynthesiserVoice* const newVoice);

    /** Deletes one of the voices. */
    void removeVoice (const int index);

    /** Deletes all sounds. */
    void clearSounds();

    /** Returns the number of sounds that have been added to the synth. */
    int getNumSounds() const throw()                                { return sounds.size(); }

    /** Returns one of the sounds. */
    SynthesiserSound* getSound (const int index) const throw()      { return sounds [index]; }

    /** Adds a new sound to the synthesiser.

        The object passed in is reference counted, so will be deleted when it is removed
        from the synthesiser, and when no voices are still using it.
    */
    void addSound (const SynthesiserSound::Ptr& newSound);

    /** Removes and deletes one of the sounds. */
    void removeSound (const int index);

    /** If set to true, then the synth will try to take over an existing voice if
        it runs out and needs to play another note.

        The value of this boolean is passed into findFreeVoice(), so the result will
        depend on the implementation of this method.
    */
    void setNoteStealingEnabled (const bool shouldStealNotes);

    /** Returns true if note-stealing is enabled.
        @see setNoteStealingEnabled
    */
    bool isNoteStealingEnabled() const throw()                      { return shouldStealNotes; }

    /** Triggers a note-on event.

        The default method here will find all the sounds that want to be triggered by
        this note/channel. For each sound, it'll try to find a free voice, and use the
        voice to start playing the sound.

        Subclasses might want to override this if they need a more complex algorithm.

        This method will be called automatically according to the midi data passed into
        renderNextBlock(), but may be called explicitly too.
    */
    virtual void noteOn (const int midiChannel,
                         const int midiNoteNumber,
                         const float velocity);

    /** Triggers a note-off event.

        This will turn off any voices that are playing a sound for the given note/channel.

        If allowTailOff is true, the voices will be allowed to fade out the notes gracefully
        (if they can do). If this is false, the notes will all be cut off immediately.

        This method will be called automatically according to the midi data passed into
        renderNextBlock(), but may be called explicitly too.
    */
    virtual void noteOff (const int midiChannel,
                          const int midiNoteNumber,
                          const bool allowTailOff);

    /** Turns off all notes.

        This will turn off any voices that are playing a sound on the given midi channel.

        If midiChannel is 0 or less, then all voices will be turned off, regardless of
        which channel they're playing.

        If allowTailOff is true, the voices will be allowed to fade out the notes gracefully
        (if they can do). If this is false, the notes will all be cut off immediately.

        This method will be called automatically according to the midi data passed into
        renderNextBlock(), but may be called explicitly too.
    */
    virtual void allNotesOff (const int midiChannel,
                              const bool allowTailOff);

    /** Sends a pitch-wheel message.

        This will send a pitch-wheel message to any voices that are playing sounds on
        the given midi channel.

        This method will be called automatically according to the midi data passed into
        renderNextBlock(), but may be called explicitly too.

        @param midiChannel          the midi channel for the event
        @param wheelValue           the wheel position, from 0 to 0x3fff, as returned by MidiMessage::getPitchWheelValue()
    */
    virtual void handlePitchWheel (const int midiChannel,
                                   const int wheelValue);

    /** Sends a midi controller message.

        This will send a midi controller message to any voices that are playing sounds on
        the given midi channel.

        This method will be called automatically according to the midi data passed into
        renderNextBlock(), but may be called explicitly too.

        @param midiChannel          the midi channel for the event
        @param controllerNumber     the midi controller type, as returned by MidiMessage::getControllerNumber()
        @param controllerValue      the midi controller value, between 0 and 127, as returned by MidiMessage::getControllerValue()
    */
    virtual void handleController (const int midiChannel,
                                   const int controllerNumber,
                                   const int controllerValue);

    /** Tells the synthesiser what the sample rate is for the audio it's being used to
        render.

        This value is propagated to the voices so that they can use it to render the correct
        pitches.
    */
    void setCurrentPlaybackSampleRate (const double sampleRate);

    /** Creates the next block of audio output.

        This will process the next numSamples of data from all the voices, and add that output
        to the audio block supplied, starting from the offset specified. Note that the
        data will be added to the current contents of the buffer, so you should clear it
        before calling this method if necessary.

        The midi events in the inputMidi buffer are parsed for note and controller events,
        and these are used to trigger the voices. Note that the startSample offset applies
        both to the audio output buffer and the midi input buffer, so any midi events
        with timestamps outside the specified region will be ignored.
    */
    void renderNextBlock (AudioSampleBuffer& outputAudio,
                          const MidiBuffer& inputMidi,
                          int startSample,
                          int numSamples);

    juce_UseDebuggingNewOperator

protected:

    /** This is used to control access to the rendering callback and the note trigger methods. */
    CriticalSection lock;

    OwnedArray <SynthesiserVoice> voices;
    ReferenceCountedArray <SynthesiserSound> sounds;

    /** The last pitch-wheel values for each midi channel. */
    int lastPitchWheelValues [16];

    /** Searches through the voices to find one that's not currently playing, and which
        can play the given sound.

        Returns 0 if all voices are busy and stealing isn't enabled.

        This can be overridden to implement custom voice-stealing algorithms.
    */
    virtual SynthesiserVoice* findFreeVoice (SynthesiserSound* soundToPlay,
                                             const bool stealIfNoneAvailable) const;

    /** Starts a specified voice playing a particular sound.

        You'll probably never need to call this, it's used internally by noteOn(), but
        may be needed by subclasses for custom behaviours.
    */
    void startVoice (SynthesiserVoice* const voice,
                     SynthesiserSound* const sound,
                     const int midiChannel,
                     const int midiNoteNumber,
                     const float velocity);

    /** xxx Temporary method here to cause a compiler error - note the new parameters for this method. */
    int findFreeVoice (const bool) const { return 0; }

private:
    double sampleRate;
    uint32 lastNoteOnCounter;
    bool shouldStealNotes;

    Synthesiser (const Synthesiser&);
    const Synthesiser& operator= (const Synthesiser&);
};

#endif   // __JUCE_SYNTHESISER_JUCEHEADER__
/********* End of inlined file: juce_Synthesiser.h *********/

/**
    A subclass of SynthesiserSound that represents a sampled audio clip.

    This is a pretty basic sampler, and just attempts to load the whole audio stream
    into memory.

    To use it, create a Synthesiser, add some SamplerVoice objects to it, then
    give it some SampledSound objects to play.

    @see SamplerVoice, Synthesiser, SynthesiserSound
*/
class JUCE_API  SamplerSound    : public SynthesiserSound
{
public:

    /** Creates a sampled sound from an audio reader.

        This will attempt to load the audio from the source into memory and store
        it in this object.

        @param name         a name for the sample
        @param source       the audio to load. This object can be safely deleted by the
                            caller after this constructor returns
        @param midiNotes    the set of midi keys that this sound should be played on. This
                            is used by the SynthesiserSound::appliesToNote() method
        @param midiNoteForNormalPitch   the midi note at which the sample should be played
                                        with its natural rate. All other notes will be pitched
                                        up or down relative to this one
        @param attackTimeSecs   the attack (fade-in) time, in seconds
        @param releaseTimeSecs  the decay (fade-out) time, in seconds
        @param maxSampleLengthSeconds   a maximum length of audio to read from the audio
                                        source, in seconds
    */
    SamplerSound (const String& name,
                  AudioFormatReader& source,
                  const BitArray& midiNotes,
                  const int midiNoteForNormalPitch,
                  const double attackTimeSecs,
                  const double releaseTimeSecs,
                  const double maxSampleLengthSeconds);

    /** Destructor. */
    ~SamplerSound();

    /** Returns the sample's name */
    const String& getName() const throw()                   { return name; }

    /** Returns the audio sample data.
        This could be 0 if there was a problem loading it.
    */
    AudioSampleBuffer* getAudioData() const throw()         { return data; }

    bool appliesToNote (const int midiNoteNumber);
    bool appliesToChannel (const int midiChannel);

    juce_UseDebuggingNewOperator

private:
    friend class SamplerVoice;

    String name;
    AudioSampleBuffer* data;
    double sourceSampleRate;
    BitArray midiNotes;
    int length, attackSamples, releaseSamples;
    int midiRootNote;
};

/**
    A subclass of SynthesiserVoice that can play a SamplerSound.

    To use it, create a Synthesiser, add some SamplerVoice objects to it, then
    give it some SampledSound objects to play.

    @see SamplerSound, Synthesiser, SynthesiserVoice
*/
class JUCE_API  SamplerVoice    : public SynthesiserVoice
{
public:

    /** Creates a SamplerVoice.
    */
    SamplerVoice();

    /** Destructor. */
    ~SamplerVoice();

    bool canPlaySound (SynthesiserSound* sound);

    void startNote (const int midiNoteNumber,
                    const float velocity,
                    SynthesiserSound* sound,
                    const int currentPitchWheelPosition);

    void stopNote (const bool allowTailOff);

    void pitchWheelMoved (const int newValue);
    void controllerMoved (const int controllerNumber,
                          const int newValue);

    void renderNextBlock (AudioSampleBuffer& outputBuffer, int startSample, int numSamples);

    juce_UseDebuggingNewOperator

private:
    double pitchRatio;
    double sourceSamplePosition;
    float lgain, rgain, attackReleaseLevel, attackDelta, releaseDelta;
    bool isInAttack, isInRelease;
};

#endif   // __JUCE_SAMPLER_JUCEHEADER__
/********* End of inlined file: juce_Sampler.h *********/

#endif
#ifndef __JUCE_SYNTHESISER_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_AudioUnitPluginFormat.h *********/
#ifndef __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__
#define __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__

#if JUCE_PLUGINHOST_AU && JUCE_MAC

/**
    Implements a plugin format manager for AudioUnits.
*/
class JUCE_API  AudioUnitPluginFormat   : public AudioPluginFormat
{
public:

    AudioUnitPluginFormat();
    ~AudioUnitPluginFormat();

    const String getName() const                { return "AudioUnit"; }
    void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
    AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
    bool fileMightContainThisPluginType (const String& fileOrIdentifier);
    const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier);
    const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive);
    bool doesPluginStillExist (const PluginDescription& desc);
    const FileSearchPath getDefaultLocationsToSearch();

    juce_UseDebuggingNewOperator

private:
    AudioUnitPluginFormat (const AudioUnitPluginFormat&);
    const AudioUnitPluginFormat& operator= (const AudioUnitPluginFormat&);
};

#endif

#endif   // __JUCE_AUDIOUNITPLUGINFORMAT_JUCEHEADER__
/********* End of inlined file: juce_AudioUnitPluginFormat.h *********/

#endif
#ifndef __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_DirectXPluginFormat.h *********/
#ifndef __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__
#define __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__

#if JUCE_PLUGINHOST_DX && JUCE_WIN32

//   Sorry, this file is just a placeholder at the moment!...

/**
    Implements a plugin format manager for DirectX plugins.
*/
class JUCE_API  DirectXPluginFormat   : public AudioPluginFormat
{
public:

    DirectXPluginFormat();
    ~DirectXPluginFormat();

    const String getName() const                { return "DirectX"; }
    void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
    AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
    bool fileMightContainThisPluginType (const String& fileOrIdentifier);
    const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier)  { return fileOrIdentifier; }
    const FileSearchPath getDefaultLocationsToSearch();

    juce_UseDebuggingNewOperator

private:
    DirectXPluginFormat (const DirectXPluginFormat&);
    const DirectXPluginFormat& operator= (const DirectXPluginFormat&);
};

#endif

#endif   // __JUCE_DIRECTXPLUGINFORMAT_JUCEHEADER__
/********* End of inlined file: juce_DirectXPluginFormat.h *********/

#endif
#ifndef __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_LADSPAPluginFormat.h *********/
#ifndef __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
#define __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__

#if JUCE_PLUGINHOST_LADSPA && JUCE_LINUX

//   Sorry, this file is just a placeholder at the moment!...

/**
    Implements a plugin format manager for DirectX plugins.
*/
class JUCE_API  LADSPAPluginFormat   : public AudioPluginFormat
{
public:

    LADSPAPluginFormat();
    ~LADSPAPluginFormat();

    const String getName() const                { return "LADSPA"; }
    void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
    AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
    bool fileMightContainThisPluginType (const String& fileOrIdentifier);
    const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier)  { return fileOrIdentifier; }
    const FileSearchPath getDefaultLocationsToSearch();

    juce_UseDebuggingNewOperator

private:
    LADSPAPluginFormat (const LADSPAPluginFormat&);
    const LADSPAPluginFormat& operator= (const LADSPAPluginFormat&);
};

#endif

#endif   // __JUCE_LADSPAPLUGINFORMAT_JUCEHEADER__
/********* End of inlined file: juce_LADSPAPluginFormat.h *********/

#endif
#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__

/********* Start of inlined file: juce_VSTMidiEventList.h *********/
#ifdef __aeffect__

#ifndef __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
#define __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__

/** Holds a set of VSTMidiEvent objects and makes it easy to add
    events to the list.

    This is used by both the VST hosting code and the plugin wrapper.
*/
class VSTMidiEventList
{
public:

    VSTMidiEventList()
        : events (0), numEventsUsed (0), numEventsAllocated (0)
    {
    }

    ~VSTMidiEventList()
    {
        freeEvents();
    }

    void clear()
    {
        numEventsUsed = 0;

        if (events != 0)
            events->numEvents = 0;
    }

    void addEvent (const void* const midiData, const int numBytes, const int frameOffset)
    {
        ensureSize (numEventsUsed + 1);

        VstMidiEvent* const e = (VstMidiEvent*) (events->events [numEventsUsed]);
        events->numEvents = ++numEventsUsed;

        if (numBytes <= 4)
        {
            if (e->type == kVstSysExType)
            {
                juce_free (((VstMidiSysexEvent*) e)->sysexDump);
                e->type = kVstMidiType;
                e->byteSize = sizeof (VstMidiEvent);
                e->noteLength = 0;
                e->noteOffset = 0;
                e->detune = 0;
                e->noteOffVelocity = 0;
            }

            e->deltaFrames = frameOffset;
            memcpy (e->midiData, midiData, numBytes);
        }
        else
        {
            VstMidiSysexEvent* const se = (VstMidiSysexEvent*) e;

            if (se->type == kVstSysExType)
                se->sysexDump = (char*) juce_realloc (se->sysexDump, numBytes);
            else
                se->sysexDump = (char*) juce_malloc (numBytes);

            memcpy (se->sysexDump, midiData, numBytes);

            se->type = kVstSysExType;
            se->byteSize = sizeof (VstMidiSysexEvent);
            se->deltaFrames = frameOffset;
            se->flags = 0;
            se->dumpBytes = numBytes;
            se->resvd1 = 0;
            se->resvd2 = 0;
        }
    }

    // Handy method to pull the events out of an event buffer supplied by the host
    // or plugin.
    static void addEventsToMidiBuffer (const VstEvents* events, MidiBuffer& dest)
    {
        for (int i = 0; i < events->numEvents; ++i)
        {
            const VstEvent* const e = events->events[i];

            if (e != 0)
            {
                if (e->type == kVstMidiType)
                {
                    dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiEvent*) e)->midiData,
                                   4, e->deltaFrames);
                }
                else if (e->type == kVstSysExType)
                {
                    dest.addEvent ((const JUCE_NAMESPACE::uint8*) ((const VstMidiSysexEvent*) e)->sysexDump,
                                   (int) ((const VstMidiSysexEvent*) e)->dumpBytes,
                                   e->deltaFrames);
                }
            }
        }
    }

    void ensureSize (int numEventsNeeded)
    {
        if (numEventsNeeded > numEventsAllocated)
        {
            numEventsNeeded = (numEventsNeeded + 32) & ~31;

            const int size = 20 + sizeof (VstEvent*) * numEventsNeeded;

            if (events == 0)
                events = (VstEvents*) juce_calloc (size);
            else
                events = (VstEvents*) juce_realloc (events, size);

            for (int i = numEventsAllocated; i < numEventsNeeded; ++i)
            {
                VstMidiEvent* const e = (VstMidiEvent*) juce_calloc (jmax ((int) sizeof (VstMidiEvent),
                                                                           (int) sizeof (VstMidiSysexEvent)));
                e->type = kVstMidiType;
                e->byteSize = sizeof (VstMidiEvent);

                events->events[i] = (VstEvent*) e;
            }

            numEventsAllocated = numEventsNeeded;
        }
    }

    void freeEvents()
    {
        if (events != 0)
        {
            for (int i = numEventsAllocated; --i >= 0;)
            {
                VstMidiEvent* const e = (VstMidiEvent*) (events->events[i]);

                if (e->type == kVstSysExType)
                    juce_free (((VstMidiSysexEvent*) e)->sysexDump);

                juce_free (e);
            }

            juce_free (events);
            events = 0;
            numEventsUsed = 0;
            numEventsAllocated = 0;
        }
    }

    VstEvents* events;

private:
    int numEventsUsed, numEventsAllocated;
};

#endif   // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
#endif   // __JUCE_VSTMIDIEVENTLIST_JUCEHEADER__
/********* End of inlined file: juce_VSTMidiEventList.h *********/

#endif
#ifndef __JUCE_VSTPLUGINFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_VSTPluginFormat.h *********/
#ifndef __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
#define __JUCE_VSTPLUGINFORMAT_JUCEHEADER__

#if JUCE_PLUGINHOST_VST

/**
    Implements a plugin format manager for VSTs.
*/
class JUCE_API  VSTPluginFormat   : public AudioPluginFormat
{
public:

    VSTPluginFormat();
    ~VSTPluginFormat();

    const String getName() const                { return "VST"; }
    void findAllTypesForFile (OwnedArray <PluginDescription>& results, const String& fileOrIdentifier);
    AudioPluginInstance* createInstanceFromDescription (const PluginDescription& desc);
    bool fileMightContainThisPluginType (const String& fileOrIdentifier);
    const String getNameOfPluginFromIdentifier (const String& fileOrIdentifier);
    const StringArray searchPathsForPlugins (const FileSearchPath& directoriesToSearch, const bool recursive);
    bool doesPluginStillExist (const PluginDescription& desc);
    const FileSearchPath getDefaultLocationsToSearch();

    juce_UseDebuggingNewOperator

private:
    VSTPluginFormat (const VSTPluginFormat&);
    const VSTPluginFormat& operator= (const VSTPluginFormat&);

    void recursiveFileSearch (StringArray& results, const File& dir, const bool recursive);
};

#endif
#endif   // __JUCE_VSTPLUGINFORMAT_JUCEHEADER__
/********* End of inlined file: juce_VSTPluginFormat.h *********/

#endif
#ifndef __JUCE_AUDIOPLUGINFORMAT_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOPLUGINFORMATMANAGER_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOPLUGININSTANCE_JUCEHEADER__

#endif
#ifndef __JUCE_KNOWNPLUGINLIST_JUCEHEADER__

#endif
#ifndef __JUCE_PLUGINDESCRIPTION_JUCEHEADER__

#endif
#ifndef __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__

/********* Start of inlined file: juce_PluginDirectoryScanner.h *********/
#ifndef __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__
#define __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__

/**
    Scans a directory for plugins, and adds them to a KnownPluginList.

    To use one of these, create it and call scanNextFile() repeatedly, until
    it returns false.
*/
class JUCE_API  PluginDirectoryScanner
{
public:

    /**
        Creates a scanner.

        @param listToAddResultsTo       this will get the new types added to it.
        @param formatToLookFor          this is the type of format that you want to look for
        @param directoriesToSearch      the path to search
        @param searchRecursively        true to search recursively
        @param deadMansPedalFile        if this isn't File::nonexistent, then it will
                                        be used as a file to store the names of any plugins
                                        that crash during initialisation. If there are
                                        any plugins listed in it, then these will always
                                        be scanned after all other possible files have
                                        been tried - in this way, even if there's a few
                                        dodgy plugins in your path, then a couple of rescans
                                        will still manage to find all the proper plugins.
                                        It's probably best to choose a file in the user's
                                        application data directory (alongside your app's
                                        settings file) for this. The file format it uses
                                        is just a list of filenames of the modules that
                                        failed.
    */
    PluginDirectoryScanner (KnownPluginList& listToAddResultsTo,
                            AudioPluginFormat& formatToLookFor,
                            FileSearchPath directoriesToSearch,
                            const bool searchRecursively,
                            const File& deadMansPedalFile);

    /** Destructor. */
    ~PluginDirectoryScanner();

    /** Tries the next likely-looking file.

        If dontRescanIfAlreadyInList is true, then the file will only be loaded and
        re-tested if it's not already in the list, or if the file's modification
        time has changed since the list was created. If dontRescanIfAlreadyInList is
        false, the file will always be reloaded and tested.

        Returns false when there are no more files to try.
    */
    bool scanNextFile (const bool dontRescanIfAlreadyInList);

    /** Returns the description of the plugin that will be scanned during the next
        call to scanNextFile().

        This is handy if you want to show the user which file is currently getting
        scanned.
    */
    const String getNextPluginFileThatWillBeScanned() const throw();

    /** Returns the estimated progress, between 0 and 1.
    */
    float getProgress() const                                       { return progress; }

    /** This returns a list of all the filenames of things that looked like being
        a plugin file, but which failed to open for some reason.
    */
    const StringArray& getFailedFiles() const throw()               { return failedFiles; }

    juce_UseDebuggingNewOperator

private:
    KnownPluginList& list;
    AudioPluginFormat& format;
    StringArray filesOrIdentifiersToScan;
    File deadMansPedalFile;
    StringArray failedFiles;
    int nextIndex;
    float progress;

    const StringArray getDeadMansPedalFile() throw();
    void setDeadMansPedalFile (const StringArray& newContents) throw();

    PluginDirectoryScanner (const PluginDirectoryScanner&);
    const PluginDirectoryScanner& operator= (const PluginDirectoryScanner&);
};

#endif   // __JUCE_PLUGINDIRECTORYSCANNER_JUCEHEADER__
/********* End of inlined file: juce_PluginDirectoryScanner.h *********/

#endif
#ifndef __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_PluginListComponent.h *********/
#ifndef __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
#define __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_ListBox.h *********/
#ifndef __JUCE_LISTBOX_JUCEHEADER__
#define __JUCE_LISTBOX_JUCEHEADER__

class ListViewport;

/**
    A subclass of this is used to drive a ListBox.

    @see ListBox
*/
class JUCE_API  ListBoxModel
{
public:

    /** Destructor. */
    virtual ~ListBoxModel()  {}

    /** This has to return the number of items in the list.

        @see ListBox::getNumRows()
    */
    virtual int getNumRows() = 0;

    /** This method must be implemented to draw a row of the list.
    */
    virtual void paintListBoxItem (int rowNumber,
                                   Graphics& g,
                                   int width, int height,
                                   bool rowIsSelected) = 0;

    /** This is used to create or update a custom component to go in a row of the list.

        Any row may contain a custom component, or can just be drawn with the paintListBoxItem() method
        and handle mouse clicks with listBoxItemClicked().

        This method will be called whenever a custom component might need to be updated - e.g.
        when the table is changed, or TableListBox::updateContent() is called.

        If you don't need a custom component for the specified row, then return 0.

        If you do want a custom component, and the existingComponentToUpdate is null, then
        this method must create a suitable new component and return it.

        If the existingComponentToUpdate is non-null, it will be a pointer to a component previously created
        by this method. In this case, the method must either update it to make sure it's correctly representing
        the given row (which may be different from the one that the component was created for), or it can
        delete this component and return a new one.

        The component that your method returns will be deleted by the ListBox when it is no longer needed.
    */
    virtual Component* refreshComponentForRow (int rowNumber, bool isRowSelected,
                                               Component* existingComponentToUpdate);

    /** This can be overridden to react to the user clicking on a row.

        @see listBoxItemDoubleClicked
    */
    virtual void listBoxItemClicked (int row, const MouseEvent& e);

    /** This can be overridden to react to the user double-clicking on a row.

        @see listBoxItemClicked
    */
    virtual void listBoxItemDoubleClicked (int row, const MouseEvent& e);

    /** This can be overridden to react to the user double-clicking on a part of the list where
        there are no rows.

        @see listBoxItemClicked
    */
    virtual void backgroundClicked();

    /** Override this to be informed when rows are selected or deselected.

        This will be called whenever a row is selected or deselected. If a range of
        rows is selected all at once, this will just be called once for that event.

        @param lastRowSelected      the last row that the user selected. If no
                                    rows are currently selected, this may be -1.
    */
    virtual void selectedRowsChanged (int lastRowSelected);

    /** Override this to be informed when the delete key is pressed.

        If no rows are selected when they press the key, this won't be called.

        @param lastRowSelected   the last row that had been selected when they pressed the
                                 key - if there are multiple selections, this might not be
                                 very useful
    */
    virtual void deleteKeyPressed (int lastRowSelected);

    /** Override this to be informed when the return key is pressed.

        If no rows are selected when they press the key, this won't be called.

        @param lastRowSelected   the last row that had been selected when they pressed the
                                 key - if there are multiple selections, this might not be
                                  very useful
    */
    virtual void returnKeyPressed (int lastRowSelected);

    /** Override this to be informed when the list is scrolled.

        This might be caused by the user moving the scrollbar, or by programmatic changes
        to the list position.
    */
    virtual void listWasScrolled();

    /** To allow rows from your list to be dragged-and-dropped, implement this method.

        If this returns a non-empty name then when the user drags a row, the listbox will
        try to find a DragAndDropContainer in its parent hierarchy, and will use it to trigger
        a drag-and-drop operation, using this string as the source description, with the listbox
        itself as the source component.

        @see DragAndDropContainer::startDragging
    */
    virtual const String getDragSourceDescription (const SparseSet<int>& currentlySelectedRows);
};

/**
    A list of items that can be scrolled vertically.

    To create a list, you'll need to create a subclass of ListBoxModel. This can
    either paint each row of the list and respond to events via callbacks, or for
    more specialised tasks, it can supply a custom component to fill each row.

    @see ComboBox, TableListBox
*/
class JUCE_API  ListBox  : public Component,
                           public SettableTooltipClient
{
public:

    /** Creates a ListBox.

        The model pointer passed-in can be null, in which case you can set it later
        with setModel().
    */
    ListBox (const String& componentName,
             ListBoxModel* const model);

    /** Destructor. */
    ~ListBox();

    /** Changes the current data model to display. */
    void setModel (ListBoxModel* const newModel);

    /** Returns the current list model. */
    ListBoxModel* getModel() const throw()                      { return model; }

    /** Causes the list to refresh its content.

        Call this when the number of rows in the list changes, or if you want it
        to call refreshComponentForRow() on all the row components.

        Be careful not to call it from a different thread, though, as it's not
        thread-safe.
    */
    void updateContent();

    /** Turns on multiple-selection of rows.

        By default this is disabled.

        When your row component gets clicked you'll need to call the
        selectRowsBasedOnModifierKeys() method to tell the list that it's been
        clicked and to get it to do the appropriate selection based on whether
        the ctrl/shift keys are held down.
    */
    void setMultipleSelectionEnabled (bool shouldBeEnabled);

    /** Makes the list react to mouse moves by selecting the row that the mouse if over.

        This function is here primarily for the ComboBox class to use, but might be
        useful for some other purpose too.
    */
    void setMouseMoveSelectsRows (bool shouldSelect);

    /** Selects a row.

        If the row is already selected, this won't do anything.

        @param rowNumber                the row to select
        @param dontScrollToShowThisRow  if true, the list's position won't change; if false and
                                        the selected row is off-screen, it'll scroll to make
                                        sure that row is on-screen
        @param deselectOthersFirst      if true and there are multiple selections, these will
                                        first be deselected before this item is selected
        @see isRowSelected, selectRowsBasedOnModifierKeys, flipRowSelection, deselectRow,
             deselectAllRows, selectRangeOfRows
    */
    void selectRow (const int rowNumber,
                    bool dontScrollToShowThisRow = false,
                    bool deselectOthersFirst = true);

    /** Selects a set of rows.

        This will add these rows to the current selection, so you might need to
        clear the current selection first with deselectAllRows()

        @param firstRow     the first row to select (inclusive)
        @param lastRow      the last row to select (inclusive)
    */
    void selectRangeOfRows (int firstRow,
                            int lastRow);

    /** Deselects a row.

        If it's not currently selected, this will do nothing.

        @see selectRow, deselectAllRows
    */
    void deselectRow (const int rowNumber);

    /** Deselects any currently selected rows.

        @see deselectRow
    */
    void deselectAllRows();

    /** Selects or deselects a row.

        If the row's currently selected, this deselects it, and vice-versa.
    */
    void flipRowSelection (const int rowNumber);

    /** Returns a sparse set indicating the rows that are currently selected.

        @see setSelectedRows
    */
    const SparseSet<int> getSelectedRows() const;

    /** Sets the rows that should be selected, based on an explicit set of ranges.

        If sendNotificationEventToModel is true, the ListBoxModel::selectedRowsChanged()
        method will be called. If it's false, no notification will be sent to the model.

        @see getSelectedRows
    */
    void setSelectedRows (const SparseSet<int>& setOfRowsToBeSelected,
                          const bool sendNotificationEventToModel = true);

    /** Checks whether a row is selected.
    */
    bool isRowSelected (const int rowNumber) const;

    /** Returns the number of rows that are currently selected.

        @see getSelectedRow, isRowSelected, getLastRowSelected
    */
    int getNumSelectedRows() const;

    /** Returns the row number of a selected row.

        This will return the row number of the Nth selected row. The row numbers returned will
        be sorted in order from low to high.

        @param index    the index of the selected row to return, (from 0 to getNumSelectedRows() - 1)
        @returns        the row number, or -1 if the index was out of range or if there aren't any rows
                        selected
        @see getNumSelectedRows, isRowSelected, getLastRowSelected
    */
    int getSelectedRow (const int index = 0) const;

    /** Returns the last row that the user selected.

        This isn't the same as the highest row number that is currently selected - if the user
        had multiply-selected rows 10, 5 and then 6 in that order, this would return 6.

        If nothing is selected, it will return -1.
    */
    int getLastRowSelected() const;

    /** Multiply-selects rows based on the modifier keys.

        If no modifier keys are down, this will select the given row and
        deselect any others.

        If the ctrl (or command on the Mac) key is down, it'll flip the
        state of the selected row.

        If the shift key is down, it'll select up to the given row from the
        last row selected.

        @see selectRow
    */
    void selectRowsBasedOnModifierKeys (const int rowThatWasClickedOn,
                                        const ModifierKeys& modifiers);

    /** Scrolls the list to a particular position.

        The proportion is between 0 and 1.0, so 0 scrolls to the top of the list,
        1.0 scrolls to the bottom.

        If the total number of rows all fit onto the screen at once, then this
        method won't do anything.

        @see getVerticalPosition
    */
    void setVerticalPosition (const double newProportion);

    /** Returns the current vertical position as a proportion of the total.

        This can be used in conjunction with setVerticalPosition() to save and restore
        the list's position. It returns a value in the range 0 to 1.

        @see setVerticalPosition
    */
    double getVerticalPosition() const;

    /** Scrolls if necessary to make sure that a particular row is visible.
    */
    void scrollToEnsureRowIsOnscreen (const int row);

    /** Returns a pointer to the scrollbar.

        (Unlikely to be useful for most people).
    */
    ScrollBar* getVerticalScrollBar() const throw();

    /** Returns a pointer to the scrollbar.

        (Unlikely to be useful for most people).
    */
    ScrollBar* getHorizontalScrollBar() const throw();

    /** Finds the row index that contains a given x,y position.

        The position is relative to the ListBox's top-left.

        If no row exists at this position, the method will return -1.

        @see getComponentForRowNumber
    */
    int getRowContainingPosition (const int x, const int y) const throw();

    /** Finds a row index that would be the most suitable place to insert a new
        item for a given position.

        This is useful when the user is e.g. dragging and dropping onto the listbox,
        because it lets you easily choose the best position to insert the item that
        they drop, based on where they drop it.

        If the position is out of range, this will return -1. If the position is
        beyond the end of the list, it will return getNumRows() to indicate the end
        of the list.

        @see getComponentForRowNumber
    */
    int getInsertionIndexForPosition (const int x, const int y) const throw();

    /** Returns the position of one of the rows, relative to the top-left of
        the listbox.

        This may be off-screen, and the range of the row number that is passed-in is
        not checked to see if it's a valid row.
    */
    const Rectangle getRowPosition (const int rowNumber,
                                    const bool relativeToComponentTopLeft) const throw();

    /** Finds the row component for a given row in the list.

        The component returned will have been created using createRowComponent().

        If the component for this row is off-screen or if the row is out-of-range,
        this will return 0.

        @see getRowContainingPosition
    */
    Component* getComponentForRowNumber (const int rowNumber) const throw();

    /** Returns the row number that the given component represents.

        If the component isn't one of the list's rows, this will return -1.
    */
    int getRowNumberOfComponent (Component* const rowComponent) const throw();

    /** Returns the width of a row (which may be less than the width of this component
        if there's a scrollbar).
    */
    int getVisibleRowWidth() const throw();

    /** Sets the height of each row in the list.

        The default height is 22 pixels.

        @see getRowHeight
    */
    void setRowHeight (const int newHeight);

    /** Returns the height of a row in the list.

        @see setRowHeight
    */
    int getRowHeight() const throw()   { return rowHeight; }

    /** Returns the number of rows actually visible.

        This is the number of whole rows which will fit on-screen, so the value might
        be more than the actual number of rows in the list.
    */
    int getNumRowsOnScreen() const throw();

    /** A set of colour IDs to use to change the colour of various aspects of the label.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId      = 0x1002800, /**< The background colour to fill the list with.
                                                  Make this transparent if you don't want the background to be filled. */
        outlineColourId         = 0x1002810, /**< An optional colour to use to draw a border around the list.
                                                  Make this transparent to not have an outline. */
        textColourId            = 0x1002820  /**< The preferred colour to use for drawing text in the listbox. */
    };

    /** Sets the thickness of a border that will be drawn around the box.

        To set the colour of the outline, use @code setColour (ListBox::outlineColourId, colourXYZ); @endcode
        @see outlineColourId
    */
    void setOutlineThickness (const int outlineThickness);

    /** Returns the thickness of outline that will be drawn around the listbox.

        @see setOutlineColour
    */
    int getOutlineThickness() const throw()    { return outlineThickness; }

    /** Sets a component that the list should use as a header.

        This will position the given component at the top of the list, maintaining the
        height of the component passed-in, but rescaling it horizontally to match the
        width of the items in the listbox.

        The component will be deleted when setHeaderComponent() is called with a
        different component, or when the listbox is deleted.
    */
    void setHeaderComponent (Component* const newHeaderComponent);

    /** Changes the width of the rows in the list.

        This can be used to make the list's row components wider than the list itself - the
        width of the rows will be either the width of the list or this value, whichever is
        greater, and if the rows become wider than the list, a horizontal scrollbar will
        appear.

        The default value for this is 0, which means that the rows will always
        be the same width as the list.
    */
    void setMinimumContentWidth (const int newMinimumWidth);

    /** Returns the space currently available for the row items, taking into account
        borders, scrollbars, etc.
    */
    int getVisibleContentWidth() const throw();

    /** Repaints one of the rows.

        This is a lightweight alternative to calling updateContent, and just causes a
        repaint of the row's area.
    */
    void repaintRow (const int rowNumber) throw();

    /** This fairly obscure method creates an image that just shows the currently
        selected row components.

        It's a handy method for doing drag-and-drop, as it can be passed to the
        DragAndDropContainer for use as the drag image.

        Note that it will make the row components temporarily invisible, so if you're
        using custom components this could affect them if they're sensitive to that
        sort of thing.

        @see Component::createComponentSnapshot
    */
    Image* createSnapshotOfSelectedRows();

    /** Returns the viewport that this ListBox uses.

        You may need to use this to change parameters such as whether scrollbars
        are shown, etc.
    */
    Viewport* getViewport() const throw();

    /** @internal */
    bool keyPressed (const KeyPress& key);
    /** @internal */
    bool keyStateChanged (const bool isKeyDown);
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void paintOverChildren (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void visibilityChanged();
    /** @internal */
    void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
    /** @internal */
    void mouseMove (const MouseEvent&);
    /** @internal */
    void mouseExit (const MouseEvent&);
    /** @internal */
    void mouseUp (const MouseEvent&);
    /** @internal */
    void colourChanged();

    juce_UseDebuggingNewOperator

private:

    friend class ListViewport;
    friend class TableListBox;
    ListBoxModel* model;
    ListViewport* viewport;
    Component* headerComponent;
    int totalItems, rowHeight, minimumRowWidth;
    int outlineThickness;
    int lastMouseX, lastMouseY, lastRowSelected;
    bool mouseMoveSelects, multipleSelection, hasDoneInitialUpdate;
    SparseSet <int> selected;

    void selectRowInternal (const int rowNumber,
                            bool dontScrollToShowThisRow,
                            bool deselectOthersFirst,
                            bool isMouseClick);

    ListBox (const ListBox&);
    const ListBox& operator= (const ListBox&);
};

#endif   // __JUCE_LISTBOX_JUCEHEADER__
/********* End of inlined file: juce_ListBox.h *********/

/********* Start of inlined file: juce_TextButton.h *********/
#ifndef __JUCE_TEXTBUTTON_JUCEHEADER__
#define __JUCE_TEXTBUTTON_JUCEHEADER__

/**
    A button that uses the standard lozenge-shaped background with a line of
    text on it.

    @see Button, DrawableButton
*/
class JUCE_API  TextButton  : public Button
{
public:

    /** Creates a TextButton.

        @param buttonName           the text to put in the button (the component's name is also
                                    initially set to this string, but these can be changed later
                                    using the setName() and setButtonText() methods)
        @param toolTip              an optional string to use as a toolip

        @see Button
    */
    TextButton (const String& buttonName,
                const String& toolTip = String::empty);

    /** Destructor. */
    ~TextButton();

    /** A set of colour IDs to use to change the colour of various aspects of the button.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        buttonColourId                  = 0x1000100,  /**< The colour used to fill the button shape (when the button is toggled
                                                           'off'). The look-and-feel class might re-interpret this to add
                                                           effects, etc. */
        buttonOnColourId                = 0x1000101,  /**< The colour used to fill the button shape (when the button is toggled
                                                           'on'). The look-and-feel class might re-interpret this to add
                                                           effects, etc. */
        textColourId                    = 0x1000102   /**< The colour to use for the button's text. */
    };

    /** Resizes the button to fit neatly around its current text.

        If newHeight is >= 0, the button's height will be changed to this
        value. If it's less than zero, its height will be unaffected.
    */
    void changeWidthToFitText (const int newHeight = -1);

    /** This can be overridden to use different fonts than the default one.

        Note that you'll need to set the font's size appropriately, too.
    */
    virtual const Font getFont();

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown);
    /** @internal */
    void colourChanged();

private:
    TextButton (const TextButton&);
    const TextButton& operator= (const TextButton&);
};

#endif   // __JUCE_TEXTBUTTON_JUCEHEADER__
/********* End of inlined file: juce_TextButton.h *********/

/**
    A component displaying a list of plugins, with options to scan for them,
    add, remove and sort them.
*/
class JUCE_API  PluginListComponent   : public Component,
                                        public ListBoxModel,
                                        public ChangeListener,
                                        public ButtonListener,
                                        public Timer
{
public:

    /**
        Creates the list component.

        For info about the deadMansPedalFile, see the PluginDirectoryScanner constructor.

        The properties file, if supplied, is used to store the user's last search paths.
    */
    PluginListComponent (KnownPluginList& listToRepresent,
                         const File& deadMansPedalFile,
                         PropertiesFile* const propertiesToUse);

    /** Destructor. */
    ~PluginListComponent();

    /** @internal */
    void resized();
    /** @internal */
    bool isInterestedInFileDrag (const StringArray& files);
    /** @internal */
    void filesDropped (const StringArray& files, int, int);
    /** @internal */
    int getNumRows();
    /** @internal */
    void paintListBoxItem (int row, Graphics& g, int width, int height, bool rowIsSelected);
    /** @internal */
    void deleteKeyPressed (int lastRowSelected);
    /** @internal */
    void buttonClicked (Button* b);
    /** @internal */
    void changeListenerCallback (void*);
    /** @internal */
    void timerCallback();

    juce_UseDebuggingNewOperator

private:
    KnownPluginList& list;
    File deadMansPedalFile;
    ListBox* listBox;
    TextButton* optionsButton;
    PropertiesFile* propertiesToUse;
    int typeToScan;

    void scanFor (AudioPluginFormat* format);

    PluginListComponent (const PluginListComponent&);
    const PluginListComponent& operator= (const PluginListComponent&);
};

#endif   // __JUCE_PLUGINLISTCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_PluginListComponent.h *********/

#endif
#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_AiffAudioFormat.h *********/
#ifndef __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__
#define __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_AudioFormat.h *********/
#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__
#define __JUCE_AUDIOFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_AudioFormatWriter.h *********/
#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__
#define __JUCE_AUDIOFORMATWRITER_JUCEHEADER__

/**
    Writes samples to an audio file stream.

    A subclass that writes a specific type of audio format will be created by
    an AudioFormat object.

    After creating one of these with the AudioFormat::createWriterFor() method
    you can call its write() method to store the samples, and then delete it.

    @see AudioFormat, AudioFormatReader
*/
class JUCE_API  AudioFormatWriter
{
protected:

    /** Creates an AudioFormatWriter object.

        @param destStream       the stream to write to - this will be deleted
                                by this object when it is no longer needed
        @param formatName       the description that will be returned by the getFormatName()
                                method
        @param sampleRate       the sample rate to use - the base class just stores
                                this value, it doesn't do anything with it
        @param numberOfChannels the number of channels to write - the base class just stores
                                this value, it doesn't do anything with it
        @param bitsPerSample    the bit depth of the stream - the base class just stores
                                this value, it doesn't do anything with it
    */
    AudioFormatWriter (OutputStream* const destStream,
                       const String& formatName,
                       const double sampleRate,
                       const unsigned int numberOfChannels,
                       const unsigned int bitsPerSample);

public:
    /** Destructor. */
    virtual ~AudioFormatWriter();

    /** Returns a description of what type of format this is.

        E.g. "AIFF file"
    */
    const String getFormatName() const throw()      { return formatName; }

    /** Writes a set of samples to the audio stream.

        Note that if you're trying to write the contents of an AudioSampleBuffer, you
        can use AudioSampleBuffer::writeToAudioWriter().

        @param samplesToWrite   an array of arrays containing the sample data for
                                each channel to write. This is a zero-terminated
                                array of arrays, and can contain a different number
                                of channels than the actual stream uses, and the
                                writer should do its best to cope with this.
                                If the format is fixed-point, each channel will be formatted
                                as an array of signed integers using the full 32-bit
                                range -0x80000000 to 0x7fffffff, regardless of the source's
                                bit-depth. If it is a floating-point format, you should treat
                                the arrays as arrays of floats, and just cast it to an (int**)
                                to pass it into the method.
        @param numSamples       the number of samples to write
    */
    virtual bool write (const int** samplesToWrite,
                        int numSamples) = 0;

    /** Reads a section of samples from an AudioFormatReader, and writes these to
        the output.

        This will take care of any floating-point conversion that's required to convert
        between the two formats. It won't deal with sample-rate conversion, though.

        If numSamplesToRead < 0, it will write the entire length of the reader.

        @returns false if it can't read or write properly during the operation
    */
    bool writeFromAudioReader (AudioFormatReader& reader,
                               int64 startSample,
                               int64 numSamplesToRead);

    /** Reads some samples from an AudioSource, and writes these to the output.

        The source must already have been initialised with the AudioSource::prepareToPlay() method

        @param source               the source to read from
        @param numSamplesToRead     total number of samples to read and write
        @param samplesPerBlock      the maximum number of samples to fetch from the source
        @returns false if it can't read or write properly during the operation
    */
    bool writeFromAudioSource (AudioSource& source,
                               int numSamplesToRead,
                               const int samplesPerBlock = 2048);

    /** Returns the sample rate being used. */
    double getSampleRate() const throw()        { return sampleRate; }

    /** Returns the number of channels being written. */
    int getNumChannels() const throw()          { return numChannels; }

    /** Returns the bit-depth of the data being written. */
    int getBitsPerSample() const throw()        { return bitsPerSample; }

    /** Returns true if it's a floating-point format, false if it's fixed-point. */
    bool isFloatingPoint() const throw()        { return usesFloatingPointData; }

    juce_UseDebuggingNewOperator

protected:
    /** The sample rate of the stream. */
    double sampleRate;

    /** The number of channels being written to the stream. */
    unsigned int numChannels;

    /** The bit depth of the file. */
    unsigned int bitsPerSample;

    /** True if it's a floating-point format, false if it's fixed-point. */
    bool usesFloatingPointData;

    /** The output stream for Use by subclasses. */
    OutputStream* output;

private:
    String formatName;
};

#endif   // __JUCE_AUDIOFORMATWRITER_JUCEHEADER__
/********* End of inlined file: juce_AudioFormatWriter.h *********/

/**
    Subclasses of AudioFormat are used to read and write different audio
    file formats.

    @see AudioFormatReader, AudioFormatWriter, WavAudioFormat, AiffAudioFormat
*/
class JUCE_API  AudioFormat
{
public:

    /** Destructor. */
    virtual ~AudioFormat();

    /** Returns the name of this format.

        e.g. "WAV file" or "AIFF file"
    */
    const String& getFormatName() const;

    /** Returns all the file extensions that might apply to a file of this format.

        The first item will be the one that's preferred when creating a new file.

        So for a wav file this might just return ".wav"; for an AIFF file it might
        return two items, ".aif" and ".aiff"
    */
    const StringArray& getFileExtensions() const;

    /** Returns true if this the given file can be read by this format.

        Subclasses shouldn't do too much work here, just check the extension or
        file type. The base class implementation just checks the file's extension
        against one of the ones that was registered in the constructor.
    */
    virtual bool canHandleFile (const File& fileToTest);

    /** Returns a set of sample rates that the format can read and write. */
    virtual const Array <int> getPossibleSampleRates() = 0;

    /** Returns a set of bit depths that the format can read and write. */
    virtual const Array <int> getPossibleBitDepths() = 0;

    /** Returns true if the format can do 2-channel audio. */
    virtual bool canDoStereo() = 0;

    /** Returns true if the format can do 1-channel audio. */
    virtual bool canDoMono() = 0;

    /** Returns true if the format uses compressed data. */
    virtual bool isCompressed();

    /** Returns a list of different qualities that can be used when writing.

        Non-compressed formats will just return an empty array, but for something
        like Ogg-Vorbis or MP3, it might return a list of bit-rates, etc.

        When calling createWriterFor(), an index from this array is passed in to
        tell the format which option is required.
    */
    virtual const StringArray getQualityOptions();

    /** Tries to create an object that can read from a stream containing audio
        data in this format.

        The reader object that is returned can be used to read from the stream, and
        should then be deleted by the caller.

        @param sourceStream                 the stream to read from - the AudioFormatReader object
                                            that is returned will delete this stream when it no longer
                                            needs it.
        @param deleteStreamIfOpeningFails   if no reader can be created, this determines whether this method
                                            should delete the stream object that was passed-in. (If a valid
                                            reader is returned, it will always be in charge of deleting the
                                            stream, so this parameter is ignored)
        @see AudioFormatReader
    */
    virtual AudioFormatReader* createReaderFor (InputStream* sourceStream,
                                                const bool deleteStreamIfOpeningFails) = 0;

    /** Tries to create an object that can write to a stream with this audio format.

        The writer object that is returned can be used to write to the stream, and
        should then be deleted by the caller.

        If the stream can't be created for some reason (e.g. the parameters passed in
        here aren't suitable), this will return 0.

        @param streamToWriteTo      the stream that the data will go to - this will be
                                    deleted by the AudioFormatWriter object when it's no longer
                                    needed. If no AudioFormatWriter can be created by this method,
                                    the stream will NOT be deleted, so that the caller can re-use it
                                    to try to open a different format, etc
        @param sampleRateToUse      the sample rate for the file, which must be one of the ones
                                    returned by getPossibleSampleRates()
        @param numberOfChannels     the number of channels - this must be either 1 or 2, and
                                    the choice will depend on the results of canDoMono() and
                                    canDoStereo()
        @param bitsPerSample        the bits per sample to use - this must be one of the values
                                    returned by getPossibleBitDepths()
        @param metadataValues       a set of metadata values that the writer should try to write
                                    to the stream. Exactly what these are depends on the format,
                                    and the subclass doesn't actually have to do anything with
                                    them if it doesn't want to. Have a look at the specific format
                                    implementation classes to see possible values that can be
                                    used
        @param qualityOptionIndex   the index of one of compression qualities returned by the
                                    getQualityOptions() method. If there aren't any quality options
                                    for this format, just pass 0 in this parameter, as it'll be
                                    ignored
        @see AudioFormatWriter
    */
    virtual AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
                                                double sampleRateToUse,
                                                unsigned int numberOfChannels,
                                                int bitsPerSample,
                                                const StringPairArray& metadataValues,
                                                int qualityOptionIndex) = 0;

protected:
    /** Creates an AudioFormat object.

        @param formatName       this sets the value that will be returned by getFormatName()
        @param fileExtensions   a zero-terminated list of file extensions - this is what will
                                be returned by getFileExtension()
    */
    AudioFormat (const String& formatName,
                 const tchar** const fileExtensions);

private:

    String formatName;
    StringArray fileExtensions;
};

#endif   // __JUCE_AUDIOFORMAT_JUCEHEADER__
/********* End of inlined file: juce_AudioFormat.h *********/

/**
    Reads and Writes AIFF format audio files.

    @see AudioFormat
*/
class JUCE_API  AiffAudioFormat  : public AudioFormat
{
public:

    /** Creates an format object. */
    AiffAudioFormat();

    /** Destructor. */
    ~AiffAudioFormat();

    const Array <int> getPossibleSampleRates();
    const Array <int> getPossibleBitDepths();
    bool canDoStereo();
    bool canDoMono();
#if JUCE_MAC
    bool canHandleFile (const File& fileToTest);
#endif

    AudioFormatReader* createReaderFor (InputStream* sourceStream,
                                        const bool deleteStreamIfOpeningFails);

    AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
                                        double sampleRateToUse,
                                        unsigned int numberOfChannels,
                                        int bitsPerSample,
                                        const StringPairArray& metadataValues,
                                        int qualityOptionIndex);

    juce_UseDebuggingNewOperator
};

#endif   // __JUCE_AIFFAUDIOFORMAT_JUCEHEADER__
/********* End of inlined file: juce_AiffAudioFormat.h *********/

#endif
#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__

/********* Start of inlined file: juce_AudioCDBurner.h *********/
#ifndef __JUCE_AUDIOCDBURNER_JUCEHEADER__
#define __JUCE_AUDIOCDBURNER_JUCEHEADER__

/**
*/
class AudioCDBurner
{
public:

    /** Returns a list of available optical drives.

        Use openDevice() to open one of the items from this list.
    */
    static const StringArray findAvailableDevices();

    /** Tries to open one of the optical drives.

        The deviceIndex is an index into the array returned by findAvailableDevices().
    */
    static AudioCDBurner* openDevice (const int deviceIndex);

    /** Destructor. */
    ~AudioCDBurner();

    /** Returns true if there's a writable disk in the drive.
    */
    bool isDiskPresent() const;

    /** Returns the number of free blocks on the disk.

        There are 75 blocks per second, at 44100Hz.
    */
    int getNumAvailableAudioBlocks() const;

    /** Adds a track to be written.

        The source passed-in here will be kept by this object, and it will
        be used and deleted at some point in the future, either during the
        burn() method or when this AudioCDBurner object is deleted. Your caller
        method shouldn't keep a reference to it or use it again after passing
        it in here.
    */
    bool addAudioTrack (AudioSource* source, int numSamples);

    /**

        Return true to cancel the current burn operation
    */
    class BurnProgressListener
    {
    public:
        BurnProgressListener() throw() {}
        virtual ~BurnProgressListener() {}

        /** Called at intervals to report on the progress of the AudioCDBurner.

            To cancel the burn, return true from this.
        */
        virtual bool audioCDBurnProgress (float proportionComplete) = 0;
    };

    const String burn (BurnProgressListener* listener,
                       const bool ejectDiscAfterwards,
                       const bool peformFakeBurnForTesting);

    juce_UseDebuggingNewOperator

private:
    AudioCDBurner (const int deviceIndex);

    void* internal;
};

#endif   // __JUCE_AUDIOCDBURNER_JUCEHEADER__
/********* End of inlined file: juce_AudioCDBurner.h *********/

#endif
#ifndef __JUCE_AUDIOFORMAT_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__

/********* Start of inlined file: juce_AudioFormatManager.h *********/
#ifndef __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__
#define __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__

/**
    A class for keeping a list of available audio formats, and for deciding which
    one to use to open a given file.

    You can either use this class as a singleton object, or create instances of it
    yourself. Once created, use its registerFormat() method to tell it which
    formats it should use.

    @see AudioFormat
*/
class JUCE_API  AudioFormatManager
{
public:

    /** Creates an empty format manager.

        Before it'll be any use, you'll need to call registerFormat() with all the
        formats you want it to be able to recognise.
    */
    AudioFormatManager();

    /** Destructor. */
    ~AudioFormatManager();

    juce_DeclareSingleton (AudioFormatManager, false);

    /** Adds a format to the manager's list of available file types.

        The object passed-in will be deleted by this object, so don't keep a pointer
        to it!

        If makeThisTheDefaultFormat is true, then the getDefaultFormat() method will
        return this one when called.
    */
    void registerFormat (AudioFormat* newFormat,
                         const bool makeThisTheDefaultFormat);

    /** Handy method to make it easy to register the formats that come with Juce.

        Currently, this will add WAV and AIFF to the list.
    */
    void registerBasicFormats();

    /** Clears the list of known formats. */
    void clearFormats();

    /** Returns the number of currently registered file formats. */
    int getNumKnownFormats() const;

    /** Returns one of the registered file formats. */
    AudioFormat* getKnownFormat (const int index) const;

    /** Looks for which of the known formats is listed as being for a given file
        extension.

        The extension may have a dot before it, so e.g. ".wav" or "wav" are both ok.
    */
    AudioFormat* findFormatForFileExtension (const String& fileExtension) const;

    /** Returns the format which has been set as the default one.

        You can set a format as being the default when it is registered. It's useful
        when you want to write to a file, because the best format may change between
        platforms, e.g. AIFF is preferred on the Mac, WAV on Windows.

        If none has been set as the default, this method will just return the first
        one in the list.
    */
    AudioFormat* getDefaultFormat() const;

    /** Returns a set of wildcards for file-matching that contains the extensions for
        all known formats.

        E.g. if might return "*.wav;*.aiff" if it just knows about wavs and aiffs.
    */
    const String getWildcardForAllFormats() const;

    /** Searches through the known formats to try to create a suitable reader for
        this file.

        If none of the registered formats can open the file, it'll return 0. If it
        returns a reader, it's the caller's responsibility to delete the reader.
    */
    AudioFormatReader* createReaderFor (const File& audioFile);

    /** Searches through the known formats to try to create a suitable reader for
        this stream.

        The stream object that is passed-in will be deleted by this method or by the
        reader that is returned, so the caller should not keep any references to it.

        The stream that is passed-in must be capable of being repositioned so
        that all the formats can have a go at opening it.

        If none of the registered formats can open the stream, it'll return 0. If it
        returns a reader, it's the caller's responsibility to delete the reader.
    */
    AudioFormatReader* createReaderFor (InputStream* audioFileStream);

    juce_UseDebuggingNewOperator

private:
    VoidArray knownFormats;
    int defaultFormatIndex;
};

#endif   // __JUCE_AUDIOFORMATMANAGER_JUCEHEADER__
/********* End of inlined file: juce_AudioFormatManager.h *********/

#endif
#ifndef __JUCE_AUDIOFORMATWRITER_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__

/********* Start of inlined file: juce_AudioThumbnail.h *********/
#ifndef __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__
#define __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__

class AudioThumbnailCache;

/**
    Makes it easy to quickly draw scaled views of the waveform shape of an
    audio file.

    To use this class, just create an AudioThumbNail class for the file you want
    to draw, call setSource to tell it which file or resource to use, then call
    drawChannel() to draw it.

    The class will asynchronously scan the wavefile to create its scaled-down view,
    so you should make your UI repaint itself as this data comes in. To do this, the
    AudioThumbnail is a ChangeBroadcaster, and will broadcast a message when its
    listeners should repaint themselves.

    The thumbnail stores an internal low-res version of the wave data, and this can
    be loaded and saved to avoid having to scan the file again.

    @see AudioThumbnailCache
*/
class JUCE_API  AudioThumbnail    : public ChangeBroadcaster,
                                    public TimeSliceClient,
                                    private Timer
{
public:

    /** Creates an audio thumbnail.

        @param sourceSamplesPerThumbnailSample  when creating a stored, low-res version
                        of the audio data, this is the scale at which it should be done
        @param formatManagerToUse   the audio format manager that is used to open the file
        @param cacheToUse   an instance of an AudioThumbnailCache - this provides a background
                            thread and storage that is used to by the thumbnail, and the cache
                            object can be shared between multiple thumbnails
    */
    AudioThumbnail (const int sourceSamplesPerThumbnailSample,
                    AudioFormatManager& formatManagerToUse,
                    AudioThumbnailCache& cacheToUse);

    /** Destructor. */
    ~AudioThumbnail();

    /** Specifies the file or stream that contains the audio file.

        For a file, just call
        @code
        setSource (new FileInputSource (file))
        @endcode

        You can pass a zero in here to clear the thumbnail.

        The source that is passed in will be deleted by this object when it is no
        longer needed
    */
    void setSource (InputSource* const newSource);

    /** Reloads the low res thumbnail data from an input stream.

        The thumb will automatically attempt to reload itself from its
        AudioThumbnailCache.
    */
    void loadFrom (InputStream& input);

    /** Saves the low res thumbnail data to an output stream.

        The thumb will automatically attempt to save itself to its
        AudioThumbnailCache after it finishes scanning the wave file.
    */
    void saveTo (OutputStream& output) const;

    /** Returns the number of channels in the file.
    */
    int getNumChannels() const throw();

    /** Returns the length of the audio file.
    */
    double getTotalLength() const throw();

    /** Renders the waveform shape for a channel.

        The waveform will be drawn within  the specified rectangle, where startTime
        and endTime specify the times within the audio file that should be positioned
        at the left and right edges of the rectangle.

        The waveform will be scaled vertically so that a full-volume sample will fill
        the rectangle vertically, but you can also specify an extra vertical scale factor
        with the verticalZoomFactor parameter.
    */
    void drawChannel (Graphics& g,
                      int x, int y, int w, int h,
                      double startTime,
                      double endTime,
                      int channelNum,
                      const float verticalZoomFactor);

    /** Returns true if the low res preview is fully generated.
    */
    bool isFullyLoaded() const throw();

    /** @internal */
    bool useTimeSlice();
    /** @internal */
    void timerCallback();

    juce_UseDebuggingNewOperator

private:
    AudioFormatManager& formatManagerToUse;
    AudioThumbnailCache& cache;
    InputSource* source;

    CriticalSection readerLock;
    AudioFormatReader* reader;

    MemoryBlock data, cachedLevels;
    int orginalSamplesPerThumbnailSample;

    int numChannelsCached, numSamplesCached;
    double cachedStart, cachedTimePerPixel;
    bool cacheNeedsRefilling;

    void clear();

    AudioFormatReader* createReader() const;

    void generateSection (AudioFormatReader& reader,
                          int64 startSample,
                          int numSamples);

    char* getChannelData (int channel) const;

    void refillCache (const int numSamples,
                      double startTime,
                      const double timePerPixel);

    friend class AudioThumbnailCache;

    // true if it needs more callbacks from the readNextBlockFromAudioFile() method
    bool initialiseFromAudioFile (AudioFormatReader& reader);

    // returns true if more needs to be read
    bool readNextBlockFromAudioFile (AudioFormatReader& reader);
};

#endif   // __JUCE_AUDIOTHUMBNAIL_JUCEHEADER__
/********* End of inlined file: juce_AudioThumbnail.h *********/

#endif
#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__

/********* Start of inlined file: juce_AudioThumbnailCache.h *********/
#ifndef __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__
#define __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__

struct ThumbnailCacheEntry;

/**
    An instance of this class is used to manage multiple AudioThumbnail objects.

    The cache runs a single background thread that is shared by all the thumbnails
    that need it, and it maintains a set of low-res previews in memory, to avoid
    having to re-scan audio files too often.

    @see AudioThumbnail
*/
class JUCE_API  AudioThumbnailCache   : public TimeSliceThread
{
public:

    /** Creates a cache object.

        The maxNumThumbsToStore parameter lets you specify how many previews should
        be kept in memory at once.
    */
    AudioThumbnailCache (const int maxNumThumbsToStore);

    /** Destructor. */
    ~AudioThumbnailCache();

    /** Clears out any stored thumbnails.
    */
    void clear();

    /** Reloads the specified thumb if this cache contains the appropriate stored
        data.

        This is called automatically by the AudioThumbnail class, so you shouldn't
        normally need to call it directly.
    */
    bool loadThumb (AudioThumbnail& thumb, const int64 hashCode);

    /** Stores the cachable data from the specified thumb in this cache.

        This is called automatically by the AudioThumbnail class, so you shouldn't
        normally need to call it directly.
    */
    void storeThumb (const AudioThumbnail& thumb, const int64 hashCode);

    juce_UseDebuggingNewOperator

private:

    OwnedArray <ThumbnailCacheEntry> thumbs;
    int maxNumThumbsToStore;

    friend class AudioThumbnail;
    void addThumbnail (AudioThumbnail* const thumb);
    void removeThumbnail (AudioThumbnail* const thumb);
};

#endif   // __JUCE_AUDIOTHUMBNAILCACHE_JUCEHEADER__
/********* End of inlined file: juce_AudioThumbnailCache.h *********/

#endif
#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_FlacAudioFormat.h *********/
#ifndef __JUCE_FLACAUDIOFORMAT_JUCEHEADER__
#define __JUCE_FLACAUDIOFORMAT_JUCEHEADER__

#if JUCE_USE_FLAC || defined (DOXYGEN)

/**
    Reads and writes the lossless-compression FLAC audio format.

    To compile this, you'll need to set the JUCE_USE_FLAC flag in juce_Config.h,
    and make sure your include search path and library search path are set up to find
    the FLAC header files and static libraries.

    @see AudioFormat
*/
class JUCE_API  FlacAudioFormat    : public AudioFormat
{
public:

    FlacAudioFormat();
    ~FlacAudioFormat();

    const Array <int> getPossibleSampleRates();
    const Array <int> getPossibleBitDepths();
    bool canDoStereo();
    bool canDoMono();
    bool isCompressed();

    AudioFormatReader* createReaderFor (InputStream* sourceStream,
                                        const bool deleteStreamIfOpeningFails);

    AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
                                        double sampleRateToUse,
                                        unsigned int numberOfChannels,
                                        int bitsPerSample,
                                        const StringPairArray& metadataValues,
                                        int qualityOptionIndex);

    juce_UseDebuggingNewOperator
};

#endif
#endif   // __JUCE_FLACAUDIOFORMAT_JUCEHEADER__
/********* End of inlined file: juce_FlacAudioFormat.h *********/

#endif
#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_WavAudioFormat.h *********/
#ifndef __JUCE_WAVAUDIOFORMAT_JUCEHEADER__
#define __JUCE_WAVAUDIOFORMAT_JUCEHEADER__

/**
    Reads and Writes WAV format audio files.

    @see AudioFormat
*/
class JUCE_API  WavAudioFormat  : public AudioFormat
{
public:

    /** Creates a format object. */
    WavAudioFormat();

    /** Destructor. */
    ~WavAudioFormat();

    /** Metadata property name used by wav readers and writers for adding
        a BWAV chunk to the file.

        @see AudioFormatReader::metadataValues, createWriterFor
    */
    static const tchar* const bwavDescription;

    /** Metadata property name used by wav readers and writers for adding
        a BWAV chunk to the file.

        @see AudioFormatReader::metadataValues, createWriterFor
    */
    static const tchar* const bwavOriginator;

    /** Metadata property name used by wav readers and writers for adding
        a BWAV chunk to the file.

        @see AudioFormatReader::metadataValues, createWriterFor
    */
    static const tchar* const bwavOriginatorRef;

    /** Metadata property name used by wav readers and writers for adding
        a BWAV chunk to the file.

        Date format is: yyyy-mm-dd

        @see AudioFormatReader::metadataValues, createWriterFor
    */
    static const tchar* const bwavOriginationDate;

    /** Metadata property name used by wav readers and writers for adding
        a BWAV chunk to the file.

        Time format is: hh-mm-ss

        @see AudioFormatReader::metadataValues, createWriterFor
    */
    static const tchar* const bwavOriginationTime;

    /** Metadata property name used by wav readers and writers for adding
        a BWAV chunk to the file.

        This is the number of samples from the start of an edit that the
        file is supposed to begin at. Seems like an obvious mistake to
        only allow a file to occur in an edit once, but that's the way
        it is..

        @see AudioFormatReader::metadataValues, createWriterFor
    */
    static const tchar* const bwavTimeReference;

    /** Metadata property name used by wav readers and writers for adding
        a BWAV chunk to the file.

        This is a

        @see AudioFormatReader::metadataValues, createWriterFor
    */
    static const tchar* const bwavCodingHistory;

    /** Utility function to fill out the appropriate metadata for a BWAV file.

        This just makes it easier than using the property names directly, and it
        fills out the time and date in the right format.
    */
    static const StringPairArray createBWAVMetadata (const String& description,
                                                     const String& originator,
                                                     const String& originatorRef,
                                                     const Time& dateAndTime,
                                                     const int64 timeReferenceSamples,
                                                     const String& codingHistory);

    const Array <int> getPossibleSampleRates();
    const Array <int> getPossibleBitDepths();
    bool canDoStereo();
    bool canDoMono();

    AudioFormatReader* createReaderFor (InputStream* sourceStream,
                                        const bool deleteStreamIfOpeningFails);

    AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
                                        double sampleRateToUse,
                                        unsigned int numberOfChannels,
                                        int bitsPerSample,
                                        const StringPairArray& metadataValues,
                                        int qualityOptionIndex);

    /** Utility function to replace the metadata in a wav file with a new set of values.

        If possible, this cheats by overwriting just the metadata region of the file, rather
        than by copying the whole file again.
    */
    bool replaceMetadataInFile (const File& wavFile, const StringPairArray& newMetadata);

    juce_UseDebuggingNewOperator
};

#endif   // __JUCE_WAVAUDIOFORMAT_JUCEHEADER__
/********* End of inlined file: juce_WavAudioFormat.h *********/

#endif
#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_OggVorbisAudioFormat.h *********/
#ifndef __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__
#define __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__

#if JUCE_USE_OGGVORBIS || defined (DOXYGEN)

/**
    Reads and writes the Ogg-Vorbis audio format.

    To compile this, you'll need to set the JUCE_USE_OGGVORBIS flag in juce_Config.h,
    and make sure your include search path and library search path are set up to find
    the Vorbis and Ogg header files and static libraries.

    @see AudioFormat,
*/
class JUCE_API  OggVorbisAudioFormat : public AudioFormat
{
public:

    OggVorbisAudioFormat();
    ~OggVorbisAudioFormat();

    const Array <int> getPossibleSampleRates();
    const Array <int> getPossibleBitDepths();
    bool canDoStereo();
    bool canDoMono();
    bool isCompressed();
    const StringArray getQualityOptions();

    /** Tries to estimate the quality level of an ogg file based on its size.

        If it can't read the file for some reason, this will just return 1 (medium quality),
        otherwise it will return the approximate quality setting that would have been used
        to create the file.

        @see getQualityOptions
    */
    int estimateOggFileQuality (const File& source);

    AudioFormatReader* createReaderFor (InputStream* sourceStream,
                                        const bool deleteStreamIfOpeningFails);

    AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
                                        double sampleRateToUse,
                                        unsigned int numberOfChannels,
                                        int bitsPerSample,
                                        const StringPairArray& metadataValues,
                                        int qualityOptionIndex);

    juce_UseDebuggingNewOperator
};

#endif
#endif   // __JUCE_OGGVORBISAUDIOFORMAT_JUCEHEADER__
/********* End of inlined file: juce_OggVorbisAudioFormat.h *********/

#endif
#ifndef __JUCE_AUDIOFORMATREADER_JUCEHEADER__

#endif
#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__

/********* Start of inlined file: juce_AudioCDReader.h *********/
#ifndef __JUCE_AUDIOCDREADER_JUCEHEADER__
#define __JUCE_AUDIOCDREADER_JUCEHEADER__

#if JUCE_MAC

#endif

/**
    A type of AudioFormatReader that reads from an audio CD.

    One of these can be used to read a CD as if it's one big audio stream. Use the
    getPositionOfTrackStart() method to find where the individual tracks are
    within the stream.

    @see AudioFormatReader
*/
class JUCE_API  AudioCDReader  : public AudioFormatReader
{
public:

    /** Returns a list of names of Audio CDs currently available for reading.

        If there's a CD drive but no CD in it, this might return an empty list, or
        possibly a device that can be opened but which has no tracks, depending
        on the platform.

        @see createReaderForCD
    */
    static const StringArray getAvailableCDNames();

    /** Tries to create an AudioFormatReader that can read from an Audio CD.

        @param index    the index of one of the available CDs - use getAvailableCDNames()
                        to find out how many there are.
        @returns        a new AudioCDReader object, or 0 if it couldn't be created. The
                        caller will be responsible for deleting the object returned.
    */
    static AudioCDReader* createReaderForCD (const int index);

    /** Destructor. */
    ~AudioCDReader();

    /** Implementation of the AudioFormatReader method. */
    bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
                      int64 startSampleInFile, int numSamples);

    /** Checks whether the CD has been removed from the drive.
    */
    bool isCDStillPresent() const;

    /** Returns the total number of tracks (audio + data).
    */
    int getNumTracks() const;

    /** Finds the sample offset of the start of a track.

        @param trackNum     the track number, where 0 is the first track.
    */
    int getPositionOfTrackStart (int trackNum) const;

    /** Returns true if a given track is an audio track.

        @param trackNum     the track number, where 0 is the first track.
    */
    bool isTrackAudio (int trackNum) const;

    /** Refreshes the object's table of contents.

        If the disc has been ejected and a different one put in since this
        object was created, this will cause it to update its idea of how many tracks
        there are, etc.
    */
    void refreshTrackLengths();

    /** Enables scanning for indexes within tracks.

        @see getLastIndex
    */
    void enableIndexScanning (bool enabled);

    /** Returns the index number found during the last read() call.

        Index scanning is turned off by default - turn it on with enableIndexScanning().

        Then when the read() method is called, if it comes across an index within that
        block, the index number is stored and returned by this method.

        Some devices might not support indexes, of course.

        (If you don't know what CD indexes are, it's unlikely you'll ever need them).

        @see enableIndexScanning
    */
    int getLastIndex() const;

    /** Scans a track to find the position of any indexes within it.

        @param trackNumber  the track to look in, where 0 is the first track on the disc
        @returns    an array of sample positions of any index points found (not including
                    the index that marks the start of the track)
    */
    const Array <int> findIndexesInTrack (const int trackNumber);

    /** Returns the CDDB id number for the CD.

        It's not a great way of identifying a disc, but it's traditional.
    */
    int getCDDBId();

    /** Tries to eject the disk.

        Of course this might not be possible, if some other process is using it.
    */
    void ejectDisk();

    juce_UseDebuggingNewOperator

private:

#if JUCE_MAC
    File volumeDir;
    OwnedArray<File> tracks;
    Array <int> trackStartSamples;
    int currentReaderTrack;
    AudioFormatReader* reader;
    AudioCDReader (const File& volume);
public:
    static int compareElements (const File* const, const File* const) throw();
private:

#elif JUCE_WIN32
    int numTracks;
    int trackStarts[100];
    bool audioTracks [100];
    void* handle;
    bool indexingEnabled;
    int lastIndex, firstFrameInBuffer, samplesInBuffer;
    MemoryBlock buffer;
    AudioCDReader (void* handle);
    int getIndexAt (int samplePos);

#elif JUCE_LINUX
    AudioCDReader();
#endif

    AudioCDReader (const AudioCDReader&);
    const AudioCDReader& operator= (const AudioCDReader&);
};

#endif   // __JUCE_AUDIOCDREADER_JUCEHEADER__
/********* End of inlined file: juce_AudioCDReader.h *********/

#endif
#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_QuickTimeAudioFormat.h *********/
#ifndef __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__
#define __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__

#if JUCE_QUICKTIME

/**
    Uses QuickTime to read the audio track a movie or media file.

    As well as QuickTime movies, this should also manage to open other audio
    files that quicktime can understand, like mp3, m4a, etc.

    @see AudioFormat
*/
class JUCE_API  QuickTimeAudioFormat  : public AudioFormat
{
public:

    /** Creates a format object. */
    QuickTimeAudioFormat();

    /** Destructor. */
    ~QuickTimeAudioFormat();

    const Array <int> getPossibleSampleRates();
    const Array <int> getPossibleBitDepths();
    bool canDoStereo();
    bool canDoMono();

    AudioFormatReader* createReaderFor (InputStream* sourceStream,
                                        const bool deleteStreamIfOpeningFails);

    AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
                                        double sampleRateToUse,
                                        unsigned int numberOfChannels,
                                        int bitsPerSample,
                                        const StringPairArray& metadataValues,
                                        int qualityOptionIndex);

    juce_UseDebuggingNewOperator
};

#endif
#endif   // __JUCE_QUICKTIMEAUDIOFORMAT_JUCEHEADER__
/********* End of inlined file: juce_QuickTimeAudioFormat.h *********/

#endif
#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__

/********* Start of inlined file: juce_AudioSubsectionReader.h *********/
#ifndef __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__
#define __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__

/**
    This class is used to wrap an AudioFormatReader and only read from a
    subsection of the file.

    So if you have a reader which can read a 1000 sample file, you could wrap it
    in one of these to only access, e.g. samples 100 to 200, and any samples
    outside that will come back as 0. Accessing sample 0 from this reader will
    actually read the first sample from the other's subsection, which might
    be at a non-zero position.

    @see AudioFormatReader
*/
class JUCE_API  AudioSubsectionReader  : public AudioFormatReader
{
public:

    /** Creates a AudioSubsectionReader for a given data source.

        @param sourceReader             the source reader from which we'll be taking data
        @param subsectionStartSample    the sample within the source reader which will be
                                        mapped onto sample 0 for this reader.
        @param subsectionLength         the number of samples from the source that will
                                        make up the subsection. If this reader is asked for
                                        any samples beyond this region, it will return zero.
        @param deleteSourceWhenDeleted  if true, the sourceReader object will be deleted when
                                        this object is deleted.
    */
    AudioSubsectionReader (AudioFormatReader* const sourceReader,
                           const int64 subsectionStartSample,
                           const int64 subsectionLength,
                           const bool deleteSourceWhenDeleted);

    /** Destructor. */
    ~AudioSubsectionReader();

    bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
                      int64 startSampleInFile, int numSamples);

    void readMaxLevels (int64 startSample,
                        int64 numSamples,
                        float& lowestLeft,
                        float& highestLeft,
                        float& lowestRight,
                        float& highestRight);

    juce_UseDebuggingNewOperator

private:
    AudioFormatReader* const source;
    int64 startSample, length;
    const bool deleteSourceWhenDeleted;

    AudioSubsectionReader (const AudioSubsectionReader&);
    const AudioSubsectionReader& operator= (const AudioSubsectionReader&);
};

#endif   // __JUCE_AUDIOSUBSECTIONREADER_JUCEHEADER__
/********* End of inlined file: juce_AudioSubsectionReader.h *********/

#endif
#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__

/********* Start of inlined file: juce_ActionBroadcaster.h *********/
#ifndef __JUCE_ACTIONBROADCASTER_JUCEHEADER__
#define __JUCE_ACTIONBROADCASTER_JUCEHEADER__

/********* Start of inlined file: juce_ActionListenerList.h *********/
#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__
#define __JUCE_ACTIONLISTENERLIST_JUCEHEADER__

/**
    A set of ActionListeners.

    Listeners can be added and removed from the list, and messages can be
    broadcast to all the listeners.

    @see ActionListener, ActionBroadcaster
*/
class JUCE_API  ActionListenerList  : public MessageListener
{
public:

    /** Creates an empty list. */
    ActionListenerList() throw();

    /** Destructor. */
    ~ActionListenerList() throw();

    /** Adds a listener to the list.

        (Trying to add a listener that's already on the list will have no effect).
    */
    void addActionListener (ActionListener* const listener) throw();

    /** Removes a listener from the list.

        If the listener isn't on the list, this won't have any effect.
    */
    void removeActionListener (ActionListener* const listener) throw();

    /** Removes all listeners from the list. */
    void removeAllActionListeners() throw();

    /** Broadcasts a message to all the registered listeners.

        This sends the message asynchronously.

        If a listener is on the list when this method is called but is removed from
        the list before the message arrives, it won't receive the message. Similarly
        listeners that are added to the list after the message is sent but before it
        arrives won't get the message either.
    */
    void sendActionMessage (const String& message) const;

    /** @internal */
    void handleMessage (const Message&);

    juce_UseDebuggingNewOperator

private:
    SortedSet <void*> actionListeners_;
    CriticalSection actionListenerLock_;

    ActionListenerList (const ActionListenerList&);
    const ActionListenerList& operator= (const ActionListenerList&);
};

#endif   // __JUCE_ACTIONLISTENERLIST_JUCEHEADER__
/********* End of inlined file: juce_ActionListenerList.h *********/

/** Manages a list of ActionListeners, and can send them messages.

    To quickly add methods to your class that can add/remove action
    listeners and broadcast to them, you can derive from this.

    @see ActionListenerList, ActionListener
*/
class JUCE_API  ActionBroadcaster
{
public:

    /** Creates an ActionBroadcaster. */
    ActionBroadcaster() throw();

    /** Destructor. */
    virtual ~ActionBroadcaster();

    /** Adds a listener to the list.

        (Trying to add a listener that's already on the list will have no effect).
    */
    void addActionListener (ActionListener* const listener);

    /** Removes a listener from the list.

        If the listener isn't on the list, this won't have any effect.
    */
    void removeActionListener (ActionListener* const listener);

    /** Removes all listeners from the list. */
    void removeAllActionListeners();

    /** Broadcasts a message to all the registered listeners.

        @see ActionListenerList::sendActionMessage
    */
    void sendActionMessage (const String& message) const;

private:

    ActionListenerList actionListenerList;

    ActionBroadcaster (const ActionBroadcaster&);
    const ActionBroadcaster& operator= (const ActionBroadcaster&);
};

#endif   // __JUCE_ACTIONBROADCASTER_JUCEHEADER__
/********* End of inlined file: juce_ActionBroadcaster.h *********/

#endif
#ifndef __JUCE_ACTIONLISTENER_JUCEHEADER__

#endif
#ifndef __JUCE_ACTIONLISTENERLIST_JUCEHEADER__

#endif
#ifndef __JUCE_ASYNCUPDATER_JUCEHEADER__

#endif
#ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__

/********* Start of inlined file: juce_CallbackMessage.h *********/
#ifndef __JUCE_CALLBACKMESSAGE_JUCEHEADER__
#define __JUCE_CALLBACKMESSAGE_JUCEHEADER__

/**
    A message that calls a custom function when it gets delivered.

    You can use this class to fire off actions that you want to be performed later
    on the message thread.

    Unlike other Message objects, these don't get sent to a MessageListener, you
    just call the post() method to send them, and when they arrive, your
    messageCallback() method will automatically be invoked.

    @see MessageListener, MessageManager, ActionListener, ChangeListener
*/
class JUCE_API  CallbackMessage   : public Message
{
public:

    CallbackMessage() throw();

    /** Destructor. */
    ~CallbackMessage() throw();

    /** Called when the message is delivered.

        You should implement this method and make it do whatever action you want
        to perform.

        Note that like all other messages, this object will be deleted immediately
        after this method has been invoked.
    */
    virtual void messageCallback() = 0;

    /** Instead of sending this message to a MessageListener, just call this method
        to post it to the event queue.

        After you've called this, this object will belong to the MessageManager,
        which will delete it later. So make sure you don't delete the object yourself,
        call post() more than once, or call post() on a stack-based obect!
    */
    void post();

    juce_UseDebuggingNewOperator

private:
    CallbackMessage (const CallbackMessage&);
    const CallbackMessage& operator= (const CallbackMessage&);
};

#endif   // __JUCE_CALLBACKMESSAGE_JUCEHEADER__
/********* End of inlined file: juce_CallbackMessage.h *********/

#endif
#ifndef __JUCE_CHANGEBROADCASTER_JUCEHEADER__

#endif
#ifndef __JUCE_CHANGELISTENER_JUCEHEADER__

#endif
#ifndef __JUCE_CHANGELISTENERLIST_JUCEHEADER__

#endif
#ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__

/********* Start of inlined file: juce_InterprocessConnection.h *********/
#ifndef __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__
#define __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__

class InterprocessConnectionServer;

/**
    Manages a simple two-way messaging connection to another process, using either
    a socket or a named pipe as the transport medium.

    To connect to a waiting socket or an open pipe, use the connectToSocket() or
    connectToPipe() methods. If this succeeds, messages can be sent to the other end,
    and incoming messages will result in a callback via the messageReceived()
    method.

    To open a pipe and wait for another client to connect to it, use the createPipe()
    method.

    To act as a socket server and create connections for one or more client, see the
    InterprocessConnectionServer class.

    @see InterprocessConnectionServer, Socket, NamedPipe
*/
class JUCE_API  InterprocessConnection    : public Thread,
                                            private MessageListener
{
public:

    /** Creates a connection.

        Connections are created manually, connecting them with the connectToSocket()
        or connectToPipe() methods, or they are created automatically by a InterprocessConnectionServer
        when a client wants to connect.

        @param callbacksOnMessageThread     if true, callbacks to the connectionMade(),
                                            connectionLost() and messageReceived() methods will
                                            always be made using the message thread; if false,
                                            these will be called immediately on the connection's
                                            own thread.
        @param magicMessageHeaderNumber     a magic number to use in the header to check the
                                            validity of the data blocks being sent and received. This
                                            can be any number, but the sender and receiver must obviously
                                            use matching values or they won't recognise each other.
    */
    InterprocessConnection (const bool callbacksOnMessageThread = true,
                            const uint32 magicMessageHeaderNumber = 0xf2b49e2c);

    /** Destructor. */
    ~InterprocessConnection();

    /** Tries to connect this object to a socket.

        For this to work, the machine on the other end needs to have a InterprocessConnectionServer
        object waiting to receive client connections on this port number.

        @param hostName             the host computer, either a network address or name
        @param portNumber           the socket port number to try to connect to
        @param timeOutMillisecs     how long to keep trying before giving up
        @returns true if the connection is established successfully
        @see Socket
    */
    bool connectToSocket (const String& hostName,
                          const int portNumber,
                          const int timeOutMillisecs);

    /** Tries to connect the object to an existing named pipe.

        For this to work, another process on the same computer must already have opened
        an InterprocessConnection object and used createPipe() to create a pipe for this
        to connect to.

        You can optionally specify a timeout length to be passed to the NamedPipe::read() method.

        @returns true if it connects successfully.
        @see createPipe, NamedPipe
    */
    bool connectToPipe (const String& pipeName,
                        const int pipeReceiveMessageTimeoutMs = -1);

    /** Tries to create a new pipe for other processes to connect to.

        This creates a pipe with the given name, so that other processes can use
        connectToPipe() to connect to the other end.

        You can optionally specify a timeout length to be passed to the NamedPipe::read() method.

        If another process is already using this pipe, this will fail and return false.
    */
    bool createPipe (const String& pipeName,
                     const int pipeReceiveMessageTimeoutMs = -1);

    /** Disconnects and closes any currently-open sockets or pipes. */
    void disconnect();

    /** True if a socket or pipe is currently active. */
    bool isConnected() const;

    /** Returns the socket that this connection is using (or null if it uses a pipe). */
    StreamingSocket* getSocket() const throw()                  { return socket; }

    /** Returns the pipe that this connection is using (or null if it uses a socket). */
    NamedPipe* getPipe() const throw()                          { return pipe; }

    /** Returns the name of the machine at the other end of this connection.

        This will return an empty string if the other machine isn't known for
        some reason.
    */
    const String getConnectedHostName() const;

    /** Tries to send a message to the other end of this connection.

        This will fail if it's not connected, or if there's some kind of write error. If
        it succeeds, the connection object at the other end will receive the message by
        a callback to its messageReceived() method.

        @see messageReceived
    */
    bool sendMessage (const MemoryBlock& message);

    /** Called when the connection is first connected.

        If the connection was created with the callbacksOnMessageThread flag set, then
        this will be called on the message thread; otherwise it will be called on a server
        thread.
    */
    virtual void connectionMade() = 0;

    /** Called when the connection is broken.

        If the connection was created with the callbacksOnMessageThread flag set, then
        this will be called on the message thread; otherwise it will be called on a server
        thread.
    */
    virtual void connectionLost() = 0;

    /** Called when a message arrives.

        When the object at the other end of this connection sends us a message with sendMessage(),
        this callback is used to deliver it to us.

        If the connection was created with the callbacksOnMessageThread flag set, then
        this will be called on the message thread; otherwise it will be called on a server
        thread.

        @see sendMessage
    */
    virtual void messageReceived (const MemoryBlock& message) = 0;

    juce_UseDebuggingNewOperator

private:
    CriticalSection pipeAndSocketLock;
    StreamingSocket* socket;
    NamedPipe* pipe;
    bool callbackConnectionState;
    const bool useMessageThread;
    const uint32 magicMessageHeader;
    int pipeReceiveMessageTimeout;

    friend class InterprocessConnectionServer;

    void initialiseWithSocket (StreamingSocket* const socket_);
    void initialiseWithPipe (NamedPipe* const pipe_);

    void handleMessage (const Message& message);

    void connectionMadeInt();
    void connectionLostInt();
    void deliverDataInt (const MemoryBlock& data);

    bool readNextMessageInt();
    void run();

    InterprocessConnection (const InterprocessConnection&);
    const InterprocessConnection& operator= (const InterprocessConnection&);
};

#endif   // __JUCE_INTERPROCESSCONNECTION_JUCEHEADER__
/********* End of inlined file: juce_InterprocessConnection.h *********/

#endif
#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__

/********* Start of inlined file: juce_InterprocessConnectionServer.h *********/
#ifndef __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__
#define __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__

/**
    An object that waits for client sockets to connect to a port on this host, and
    creates InterprocessConnection objects for each one.

    To use this, create a class derived from it which implements the createConnectionObject()
    method, so that it creates suitable connection objects for each client that tries
    to connect.

    @see InterprocessConnection
*/
class JUCE_API  InterprocessConnectionServer    : private Thread
{
public:

    /** Creates an uninitialised server object.
    */
    InterprocessConnectionServer();

    /** Destructor. */
    ~InterprocessConnectionServer();

    /** Starts an internal thread which listens on the given port number.

        While this is running, in another process tries to connect with the
        InterprocessConnection::connectToSocket() method, this object will call
        createConnectionObject() to create a connection to that client.

        Use stop() to stop the thread running.

        @see createConnectionObject, stop
    */
    bool beginWaitingForSocket (const int portNumber);

    /** Terminates the listener thread, if it's active.

        @see beginWaitingForSocket
    */
    void stop();

protected:
    /** Creates a suitable connection object for a client process that wants to
        connect to this one.

        This will be called by the listener thread when a client process tries
        to connect, and must return a new InterprocessConnection object that will
        then run as this end of the connection.

        @see InterprocessConnection
    */
    virtual InterprocessConnection* createConnectionObject() = 0;

public:

    juce_UseDebuggingNewOperator

private:
    StreamingSocket* volatile socket;

    void run();

    InterprocessConnectionServer (const InterprocessConnectionServer&);
    const InterprocessConnectionServer& operator= (const InterprocessConnectionServer&);
};

#endif   // __JUCE_INTERPROCESSCONNECTIONSERVER_JUCEHEADER__
/********* End of inlined file: juce_InterprocessConnectionServer.h *********/

#endif
#ifndef __JUCE_MESSAGE_JUCEHEADER__

#endif
#ifndef __JUCE_MESSAGELISTENER_JUCEHEADER__

#endif
#ifndef __JUCE_MULTITIMER_JUCEHEADER__

/********* Start of inlined file: juce_MultiTimer.h *********/
#ifndef __JUCE_MULTITIMER_JUCEHEADER__
#define __JUCE_MULTITIMER_JUCEHEADER__

/**
    A type of timer class that can run multiple timers with different frequencies,
    all of which share a single callback.

    This class is very similar to the Timer class, but allows you run multiple
    separate timers, where each one has a unique ID number. The methods in this
    class are exactly equivalent to those in Timer, but with the addition of
    this ID number.

    To use it, you need to create a subclass of MultiTimer, implementing the
    timerCallback() method. Then you can start timers with startTimer(), and
    each time the callback is triggered, it passes in the ID of the timer that
    caused it.

    @see Timer
*/
class JUCE_API  MultiTimer
{
protected:

    /** Creates a MultiTimer.

        When created, no timers are running, so use startTimer() to start things off.
    */
    MultiTimer() throw();

    /** Creates a copy of another timer.

        Note that this timer will not contain any running timers, even if the one you're
        copying from was running.
    */
    MultiTimer (const MultiTimer& other) throw();

public:

    /** Destructor. */
    virtual ~MultiTimer();

    /** The user-defined callback routine that actually gets called by each of the
        timers that are running.

        It's perfectly ok to call startTimer() or stopTimer() from within this
        callback to change the subsequent intervals.
    */
    virtual void timerCallback (const int timerId) = 0;

    /** Starts a timer and sets the length of interval required.

        If the timer is already started, this will reset it, so the
        time between calling this method and the next timer callback
        will not be less than the interval length passed in.

        @param timerId                  a unique Id number that identifies the timer to
                                        start. This is the id that will be passed back
                                        to the timerCallback() method when this timer is
                                        triggered
        @param  intervalInMilliseconds  the interval to use (any values less than 1 will be
                                        rounded up to 1)
    */
    void startTimer (const int timerId, const int intervalInMilliseconds) throw();

    /** Stops a timer.

        If a timer has been started with the given ID number, it will be cancelled.
        No more callbacks will be made for the specified timer after this method returns.

        If this is called from a different thread, any callbacks that may
        be currently executing may be allowed to finish before the method
        returns.
    */
    void stopTimer (const int timerId) throw();

    /** Checks whether a timer has been started for a specified ID.

        @returns true if a timer with the given ID is running.
    */
    bool isTimerRunning (const int timerId) const throw();

    /** Returns the interval for a specified timer ID.

        @returns    the timer's interval in milliseconds if it's running, or 0 if it's no timer
                    is running for the ID number specified.
    */
    int getTimerInterval (const int timerId) const throw();

private:
    CriticalSection timerListLock;
    VoidArray timers;

    const MultiTimer& operator= (const MultiTimer&);
};

#endif   // __JUCE_MULTITIMER_JUCEHEADER__
/********* End of inlined file: juce_MultiTimer.h *********/

#endif
#ifndef __JUCE_TIMER_JUCEHEADER__

#endif
#ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__

/********* Start of inlined file: juce_MessageManager.h *********/
#ifndef __JUCE_MESSAGEMANAGER_JUCEHEADER__
#define __JUCE_MESSAGEMANAGER_JUCEHEADER__

class Component;
class MessageManagerLock;

/** See MessageManager::callFunctionOnMessageThread() for use of this function type
*/
typedef void* (MessageCallbackFunction) (void* userData);

/** Delivers Message objects to MessageListeners, and handles the event-dispatch loop.

    @see Message, MessageListener, MessageManagerLock, JUCEApplication
*/
class JUCE_API  MessageManager
{
public:

    /** Returns the global instance of the MessageManager. */
    static MessageManager* getInstance() throw();

    /** Runs the event dispatch loop until a stop message is posted.

        This method is only intended to be run by the application's startup routine,
        as it blocks, and will only return after the stopDispatchLoop() method has been used.

        @see stopDispatchLoop
    */
    void runDispatchLoop();

    /** Sends a signal that the dispatch loop should terminate.

        After this is called, the runDispatchLoop() or runDispatchLoopUntil() methods
        will be interrupted and will return.

        @see runDispatchLoop
    */
    void stopDispatchLoop();

    /** Returns true if the stopDispatchLoop() method has been called.
    */
    bool hasStopMessageBeenSent() const throw()         { return quitMessagePosted; }

    /** Synchronously dispatches messages until a given time has elapsed.

        Returns false if a quit message has been posted by a call to stopDispatchLoop(),
        otherwise returns true.
    */
    bool runDispatchLoopUntil (int millisecondsToRunFor);

    /** Calls a function using the message-thread.

        This can be used by any thread to cause this function to be called-back
        by the message thread. If it's the message-thread that's calling this method,
        then the function will just be called; if another thread is calling, a message
        will be posted to the queue, and this method will block until that message
        is delivered, the function is called, and the result is returned.

        Be careful not to cause any deadlocks with this! It's easy to do - e.g. if the caller
        thread has a critical section locked, which an unrelated message callback then tries to lock
        before the message thread gets round to processing this callback.

        @param callback     the function to call - its signature must be @code
                            void* myCallbackFunction (void*) @endcode
        @param userData     a user-defined pointer that will be passed to the function that gets called
        @returns            the value that the callback function returns.
        @see MessageManagerLock
    */
    void* callFunctionOnMessageThread (MessageCallbackFunction* callback,
                                       void* userData);

    /** Returns true if the caller-thread is the message thread. */
    bool isThisTheMessageThread() const throw();

    /** Called to tell the manager which thread is the one that's running the dispatch loop.

        (Best to ignore this method unless you really know what you're doing..)
        @see getCurrentMessageThread
    */
    void setCurrentMessageThread (const Thread::ThreadID threadId) throw();

    /** Returns the ID of the current message thread, as set by setCurrentMessageThread().

        (Best to ignore this method unless you really know what you're doing..)
        @see setCurrentMessageThread
    */
    Thread::ThreadID getCurrentMessageThread() const throw()             { return messageThreadId; }

    /** Returns true if the caller thread has currenltly got the message manager locked.

        see the MessageManagerLock class for more info about this.

        This will be true if the caller is the message thread, because that automatically
        gains a lock while a message is being dispatched.
    */
    bool currentThreadHasLockedMessageManager() const throw();

    /** Sends a message to all other JUCE applications that are running.

        @param messageText      the string that will be passed to the actionListenerCallback()
                                method of the broadcast listeners in the other app.
        @see registerBroadcastListener, ActionListener
    */
    static void broadcastMessage (const String& messageText) throw();

    /** Registers a listener to get told about broadcast messages.

        The actionListenerCallback() callback's string parameter
        is the message passed into broadcastMessage().

        @see broadcastMessage
    */
    void registerBroadcastListener (ActionListener* listener) throw();

    /** Deregisters a broadcast listener. */
    void deregisterBroadcastListener (ActionListener* listener) throw();

    /** @internal */
    void deliverMessage (void*);
    /** @internal */
    void deliverBroadcastMessage (const String&);
    /** @internal */
    ~MessageManager() throw();

    juce_UseDebuggingNewOperator

private:
    MessageManager() throw();

    friend class MessageListener;
    friend class ChangeBroadcaster;
    friend class ActionBroadcaster;
    friend class CallbackMessage;
    static MessageManager* instance;

    SortedSet<const MessageListener*> messageListeners;
    ActionListenerList* broadcastListeners;

    friend class JUCEApplication;
    bool quitMessagePosted, quitMessageReceived;
    Thread::ThreadID messageThreadId;

    VoidArray modalComponents;
    static void* exitModalLoopCallback (void*);

    void postMessageToQueue (Message* const message);
    void postCallbackMessage (Message* const message);

    static void doPlatformSpecificInitialisation();
    static void doPlatformSpecificShutdown();

    friend class MessageManagerLock;
    Thread::ThreadID volatile threadWithLock;
    CriticalSection lockingLock;

    MessageManager (const MessageManager&);
    const MessageManager& operator= (const MessageManager&);
};

/** Used to make sure that the calling thread has exclusive access to the message loop.

    Because it's not thread-safe to call any of the Component or other UI classes
    from threads other than the message thread, one of these objects can be used to
    lock the message loop and allow this to be done. The message thread will be
    suspended for the lifetime of the MessageManagerLock object, so create one on
    the stack like this: @code
    void MyThread::run()
    {
        someData = 1234;

        const MessageManagerLock mmLock;
        // the event loop will now be locked so it's safe to make a few calls..

        myComponent->setBounds (newBounds);
        myComponent->repaint();

        // ..the event loop will now be unlocked as the MessageManagerLock goes out of scope
    }
    @endcode

    Obviously be careful not to create one of these and leave it lying around, or
    your app will grind to a halt!

    Another caveat is that using this in conjunction with other CriticalSections
    can create lots of interesting ways of producing a deadlock! In particular, if
    your message thread calls stopThread() for a thread that uses these locks,
    you'll get an (occasional) deadlock..

    @see MessageManager, MessageManager::currentThreadHasLockedMessageManager
*/
class JUCE_API MessageManagerLock
{
public:

    /** Tries to acquire a lock on the message manager.

        The constructor attempts to gain a lock on the message loop, and the lock will be
        kept for the lifetime of this object.

        Optionally, you can pass a thread object here, and while waiting to obtain the lock,
        this method will keep checking whether the thread has been given the
        Thread::signalThreadShouldExit() signal. If this happens, then it will return
        without gaining the lock. If you pass a thread, you must check whether the lock was
        successful by calling lockWasGained(). If this is false, your thread is being told to
        die, so you should take evasive action.

        If you pass zero for the thread object, it will wait indefinitely for the lock - be
        careful when doing this, because it's very easy to deadlock if your message thread
        attempts to call stopThread() on a thread just as that thread attempts to get the
        message lock.

        If the calling thread already has the lock, nothing will be done, so it's safe and
        quick to use these locks recursively.

        E.g.
        @code
        void run()
        {
            ...

            while (! threadShouldExit())
            {
                MessageManagerLock mml (Thread::getCurrentThread());

                if (! mml.lockWasGained())
                    return; // another thread is trying to kill us!

                ..do some locked stuff here..
            }

            ..and now the MM is now unlocked..
        }
        @endcode

    */
    MessageManagerLock (Thread* const threadToCheckForExitSignal = 0) throw();

    /** This has the same behaviour as the other constructor, but takes a ThreadPoolJob
        instead of a thread.

        See the MessageManagerLock (Thread*) constructor for details on how this works.
    */
    MessageManagerLock (ThreadPoolJob* const jobToCheckForExitSignal) throw();

    /** Releases the current thread's lock on the message manager.

        Make sure this object is created and deleted by the same thread,
        otherwise there are no guarantees what will happen!
   */
    ~MessageManagerLock() throw();

    /** Returns true if the lock was successfully acquired.

        (See the constructor that takes a Thread for more info).
    */
    bool lockWasGained() const throw()                      { return locked; }

private:
    bool locked, needsUnlocking;
    void* sharedEvents;

    void init (Thread* const thread, ThreadPoolJob* const job) throw();
};

#endif   // __JUCE_MESSAGEMANAGER_JUCEHEADER__
/********* End of inlined file: juce_MessageManager.h *********/

#endif
#ifndef __JUCE_BRUSH_JUCEHEADER__

#endif
#ifndef __JUCE_GRADIENTBRUSH_JUCEHEADER__

/********* Start of inlined file: juce_GradientBrush.h *********/
#ifndef __JUCE_GRADIENTBRUSH_JUCEHEADER__
#define __JUCE_GRADIENTBRUSH_JUCEHEADER__

/********* Start of inlined file: juce_ColourGradient.h *********/
#ifndef __JUCE_COLOURGRADIENT_JUCEHEADER__
#define __JUCE_COLOURGRADIENT_JUCEHEADER__

/**
    Structure used to define a colour gradient for painting areas.

    @see GradientBrush
*/
class JUCE_API  ColourGradient
{
public:

    /** Creates a gradient object.

        (x1, y1) is the location to draw with colour1. Likewise (x2, y2) is where
        colour2 should be. In between them there's a gradient.

        If isRadial is true, the colours form a circular gradient with (x1, y1) at
        its centre.

        The alpha transparencies of the colours are used, so note that
        if you blend from transparent to a solid colour, the RGB of the transparent
        colour will become visible in parts of the gradient. e.g. blending
        from Colour::transparentBlack to Colours::white will produce a
        muddy grey colour midway, but Colour::transparentWhite to Colours::white
        will be white all the way across.

        @see ColourGradient
    */
    ColourGradient (const Colour& colour1,
                    const float x1,
                    const float y1,
                    const Colour& colour2,
                    const float x2,
                    const float y2,
                    const bool isRadial) throw();

    /** Creates an uninitialised gradient.

        If you use this constructor instead of the other one, be sure to set all the
        object's public member variables before using it!
    */
    ColourGradient() throw();

    /** Destructor */
    ~ColourGradient() throw();

    /** Removes any colours that have been added.

        This will also remove any start and end colours, so the gradient won't work. You'll
        need to add more colours with addColour().
    */
    void clearColours() throw();

    /** Adds a colour at a point along the length of the gradient.

        This allows the gradient to go through a spectrum of colours, instead of just a
        start and end colour.

        @param proportionAlongGradient      a value between 0 and 1.0, which is the proportion
                                            of the distance along the line between the two points
                                            at which the colour should occur.
        @param colour                       the colour that should be used at this point
    */
    void addColour (const double proportionAlongGradient,
                    const Colour& colour) throw();

    /** Multiplies the alpha value of all the colours by the given scale factor */
    void multiplyOpacity (const float multiplier) throw();

    /** Returns the number of colour-stops that have been added. */
    int getNumColours() const throw();

    /** Returns the position along the length of the gradient of the colour with this index.

        The index is from 0 to getNumColours() - 1. The return value will be between 0.0 and 1.0
    */
    double getColourPosition (const int index) const throw();

    /** Returns the colour that was added with a given index.

        The index is from 0 to getNumColours() - 1. The return value will be between 0.0 and 1.0
    */
    const Colour getColour (const int index) const throw();

    /** Creates a set of interpolated premultiplied ARGB values.

        The caller must delete the array that is returned using juce_free().
    */
    PixelARGB* createLookupTable (int& numEntries) const throw();

    /** Returns true if all colours are opaque. */
    bool isOpaque() const throw();

    /** Returns true if all colours are completely transparent. */
    bool isInvisible() const throw();

    float x1;
    float y1;

    float x2;
    float y2;

    /** If true, the gradient should be filled circularly, centred around
        (x1, y1), with (x2, y2) defining a point on the circumference.

        If false, the gradient is linear between the two points.
    */
    bool isRadial;

    /** A transform to apply to the resultant gradient shape */
    AffineTransform transform;

    juce_UseDebuggingNewOperator

private:
    Array <uint32> colours;
};

#endif   // __JUCE_COLOURGRADIENT_JUCEHEADER__
/********* End of inlined file: juce_ColourGradient.h *********/

/**
    A Brush that fills areas with a colour gradient.

    The gradient can either be linear or circular.

    @see Brush, Graphics::setBrush, SolidColourBrush, ImageBrush
*/
class JUCE_API  GradientBrush  : public Brush
{
public:

    /** Creates a gradient brush, ready for use in Graphics::setBrush().

        (x1, y1) is the location relative to the origin of the Graphics context,
        at which the colour should be colour1. Likewise for (x2, y2) and colour2.

        If isRadial is true, the colours form a circular gradient with (x1, y1) at
        its centre.

        The alpha transparencies of the colours are used, so the brush
        need not be completely opaque. Note that this means that if you
        blend from transparent to a solid colour, the RGB of the transparent
        colour will become visible in parts of the gradient. e.g. blending
        from Colour::transparentBlack to Colours::white will produce a
        grey colour, but Colour::transparentWhite to Colours::white will be
        white all the way across.

        @see ColourGradient
    */
    GradientBrush (const Colour& colour1,
                   const float x1,
                   const float y1,
                   const Colour& colour2,
                   const float x2,
                   const float y2,
                   const bool isRadial) throw();

    /** Creates a gradient brush from a ColourGradient object.
    */
    GradientBrush (const ColourGradient& gradient) throw();

    /** Destructor. */
    ~GradientBrush() throw();

    Brush* createCopy() const throw();

    void applyTransform (const AffineTransform& transform) throw();

    void multiplyOpacity (const float multiple) throw();

    bool isInvisible() const throw();

    void paintPath (LowLevelGraphicsContext& context,
                    const Path& path, const AffineTransform& transform) throw();

    void paintRectangle (LowLevelGraphicsContext& context,
                         int x, int y, int w, int h) throw();

    void paintAlphaChannel (LowLevelGraphicsContext& context,
                            const Image& alphaChannelImage, int imageX, int imageY,
                            int x, int y, int w, int h) throw();

    juce_UseDebuggingNewOperator

protected:
    ColourGradient gradient;

private:
    GradientBrush (const GradientBrush&);
    const GradientBrush& operator= (const GradientBrush&);
};

#endif   // __JUCE_GRADIENTBRUSH_JUCEHEADER__
/********* End of inlined file: juce_GradientBrush.h *********/

#endif
#ifndef __JUCE_IMAGEBRUSH_JUCEHEADER__

/********* Start of inlined file: juce_ImageBrush.h *********/
#ifndef __JUCE_IMAGEBRUSH_JUCEHEADER__
#define __JUCE_IMAGEBRUSH_JUCEHEADER__

/********* Start of inlined file: juce_Image.h *********/
#ifndef __JUCE_IMAGE_JUCEHEADER__
#define __JUCE_IMAGE_JUCEHEADER__

/**
    Holds a fixed-size bitmap.

    The image is stored in either 24-bit RGB or 32-bit premultiplied-ARGB format.

    To draw into an image, create a Graphics object for it.
    e.g. @code

    // create a transparent 500x500 image..
    Image myImage (Image::RGB, 500, 500, true);

    Graphics g (myImage);
    g.setColour (Colours::red);
    g.fillEllipse (20, 20, 300, 200);  // draws a red ellipse in our image.
    @endcode

    Other useful ways to create an image are with the ImageCache class, or the
    ImageFileFormat, which provides a way to load common image files.

    @see Graphics, ImageFileFormat, ImageCache, ImageConvolutionKernel
*/
class JUCE_API  Image
{
public:

    enum PixelFormat
    {
        RGB,                /**<< each pixel is a 3-byte packed RGB colour value. For byte order, see the PixelRGB class. */
        ARGB,               /**<< each pixel is a 4-byte ARGB premultiplied colour value. For byte order, see the PixelARGB class. */
        SingleChannel       /**<< each pixel is a 1-byte alpha channel value. */
    };

    /** Creates an in-memory image with a specified size and format.

        @param format           the number of colour channels in the image
        @param imageWidth       the desired width of the image, in pixels - this value must be
                                greater than zero (otherwise a width of 1 will be used)
        @param imageHeight      the desired width of the image, in pixels - this value must be
                                greater than zero (otherwise a height of 1 will be used)
        @param clearImage       if true, the image will initially be cleared to black or transparent
                                black. If false, the image may contain random data, and the
                                user will have to deal with this
    */
    Image (const PixelFormat format,
           const int imageWidth,
           const int imageHeight,
           const bool clearImage);

    /** Creates a copy of another image.

        @see createCopy
    */
    Image (const Image& other);

    /** Destructor. */
    virtual ~Image();

    /** Returns the image's width (in pixels). */
    int getWidth() const throw()                    { return imageWidth; }

    /** Returns the image's height (in pixels). */
    int getHeight() const throw()                   { return imageHeight; }

    /** Returns the image's pixel format. */
    PixelFormat getFormat() const throw()           { return format; }

    /** True if the image's format is ARGB. */
    bool isARGB() const throw()                     { return format == ARGB; }

    /** True if the image's format is RGB. */
    bool isRGB() const throw()                      { return format == RGB; }

    /** True if the image contains an alpha-channel. */
    bool hasAlphaChannel() const throw()            { return format != RGB; }

    /** Clears a section of the image with a given colour.

        This won't do any alpha-blending - it just sets all pixels in the image to
        the given colour (which may be non-opaque if the image has an alpha channel).
    */
    virtual void clear (int x, int y, int w, int h,
                        const Colour& colourToClearTo = Colour (0x00000000));

    /** Returns a new image that's a copy of this one.

        A new size for the copied image can be specified, or values less than
        zero can be passed-in to use the image's existing dimensions.

        It's up to the caller to delete the image when no longer needed.
    */
    virtual Image* createCopy (int newWidth = -1,
                               int newHeight = -1,
                               const Graphics::ResamplingQuality quality = Graphics::mediumResamplingQuality) const;

    /** Returns the colour of one of the pixels in the image.

        If the co-ordinates given are beyond the image's boundaries, this will
        return Colours::transparentBlack.

        (0, 0) is the image's top-left corner.

        @see getAlphaAt, setPixelAt, blendPixelAt
    */
    virtual const Colour getPixelAt (const int x, const int y) const;

    /** Sets the colour of one of the image's pixels.

        If the co-ordinates are beyond the image's boundaries, then nothing will
        happen.

        Note that unlike blendPixelAt(), this won't do any alpha-blending, it'll
        just replace the existing pixel with the given one. The colour's opacity
        will be ignored if this image doesn't have an alpha-channel.

        (0, 0) is the image's top-left corner.

        @see blendPixelAt
    */
    virtual void setPixelAt (const int x, const int y, const Colour& colour);

    /** Changes the opacity of a pixel.

        This only has an effect if the image has an alpha channel and if the
        given co-ordinates are inside the image's boundary.

        The multiplier must be in the range 0 to 1.0, and the current alpha
        at the given co-ordinates will be multiplied by this value.

        @see getAlphaAt, setPixelAt
    */
    virtual void multiplyAlphaAt (const int x, const int y, const float multiplier);

    /** Changes the overall opacity of the image.

        This will multiply the alpha value of each pixel in the image by the given
        amount (limiting the resulting alpha values between 0 and 255). This allows
        you to make an image more or less transparent.

        If the image doesn't have an alpha channel, this won't have any effect.
    */
    virtual void multiplyAllAlphas (const float amountToMultiplyBy);

    /** Changes all the colours to be shades of grey, based on their current luminosity.
    */
    virtual void desaturate();

    /** Locks some of the pixels in the image so they can be read and written to.

        This returns a pointer to some memory containing the pixels in the given
        rectangle. It also returns values for the line and pixel stride used within
        the data. The format of the pixel data is the same as that of this image.

        When you've finished reading and changing the data, you must call
        releasePixelDataReadWrite() to give the pixels back to the image.

        For images that are stored in memory, this method may just return a direct
        pointer to the image's data, but other types of image may be stored elsewhere,
        e.g. in video memory, and if so, this lockPixelDataReadWrite() and
        releasePixelDataReadWrite() may need to create a temporary copy in main memory.

        If you only need read-access to the pixel data, use lockPixelDataReadOnly()
        instead.

        @see releasePixelDataReadWrite, lockPixelDataReadOnly
    */
    virtual uint8* lockPixelDataReadWrite (int x, int y, int w, int h, int& lineStride, int& pixelStride);

    /** Releases a block of memory that was locked with lockPixelDataReadWrite().
    */
    virtual void releasePixelDataReadWrite (void* sourceData);

    /** Locks some of the pixels in the image so they can be read.

        This returns a pointer to some memory containing the pixels in the given
        rectangle. It also returns values for the line and pixel stride used within
        the data. The format of the pixel data is the same as that of this image.

        When you've finished reading the data, you must call releasePixelDataReadOnly()
        to let the image free the memory if necessary.

        For images that are stored in memory, this method may just return a direct
        pointer to the image's data, but other types of image may be stored elsewhere,
        e.g. in video memory, and if so, this lockPixelDataReadWrite() and
        releasePixelDataReadWrite() may need to create a temporary copy in main memory.

        If you only need to read and write the pixel data, use lockPixelDataReadWrite()
        instead.

        @see releasePixelDataReadOnly, lockPixelDataReadWrite
    */
    virtual const uint8* lockPixelDataReadOnly (int x, int y, int w, int h, int& lineStride, int& pixelStride) const;

    /** Releases a block of memory that was locked with lockPixelDataReadOnly().
    */
    virtual void releasePixelDataReadOnly (const void* sourceData) const;

    /** Copies some pixel values to a rectangle of the image.

        The format of the pixel data must match that of the image itself, and the
        rectangle supplied must be within the image's bounds.
    */
    virtual void setPixelData (int destX, int destY, int destW, int destH,
                               const uint8* sourcePixelData, int sourceLineStride);

    /** Copies a section of the image to somewhere else within itself.
    */
    virtual void moveImageSection (int destX, int destY,
                                   int sourceX, int sourceY,
                                   int width, int height);

    /** Creates a RectangleList containing rectangles for all non-transparent pixels
        of the image.

        @param result           the list that will have the area added to it
        @param alphaThreshold   for a semi-transparent image, any pixels whose alpha is
                                above this level will be considered opaque
    */
    void createSolidAreaMask (RectangleList& result,
                              const float alphaThreshold = 0.5f) const;

    juce_UseDebuggingNewOperator

    /** Creates a context suitable for drawing onto this image.

        Don't call this method directly! It's used internally by the Graphics class.
    */
    virtual LowLevelGraphicsContext* createLowLevelContext();

protected:
    const PixelFormat format;
    const int imageWidth, imageHeight;

    /** Used internally so that subclasses can call a constructor that doesn't allocate memory */
    Image (const PixelFormat format,
           const int imageWidth,
           const int imageHeight);

    int pixelStride, lineStride;
    uint8* imageData;

private:

    const Image& operator= (const Image&);
};

#endif   // __JUCE_IMAGE_JUCEHEADER__
/********* End of inlined file: juce_Image.h *********/

/**
    A Brush that fills areas with tiled repetitions of an image.

    @see Brush, Graphics::setBrush, SolidColourBrush, GradientBrush
*/
class JUCE_API  ImageBrush  : public Brush
{
public:

    /* Creates an image brush, ready for use in Graphics::setBrush().

       (x, y) is an anchor point for the top-left of the image
       A reference to the image passed in will be kept, so don't delete
       it within the lifetime of this object
    */
    ImageBrush (Image* const image,
                const int anchorX,
                const int anchorY,
                const float opacity) throw();

    /** Destructor. */
    ~ImageBrush() throw();

    Brush* createCopy() const throw();

    void applyTransform (const AffineTransform& transform) throw();

    void multiplyOpacity (const float multiple) throw();

    bool isInvisible() const throw();

    void paintPath (LowLevelGraphicsContext& context,
                    const Path& path, const AffineTransform& transform) throw();

    void paintRectangle (LowLevelGraphicsContext& context,
                         int x, int y, int w, int h) throw();

    void paintAlphaChannel (LowLevelGraphicsContext& context,
                            const Image& alphaChannelImage, int imageX, int imageY,
                            int x, int y, int w, int h) throw();

    juce_UseDebuggingNewOperator

protected:
    Image* image;
    int anchorX, anchorY;
    float opacity;

private:
    ImageBrush (const ImageBrush&);
    const ImageBrush& operator= (const ImageBrush&);

    void getStartXY (int& x, int& y) const throw();
};

#endif   // __JUCE_IMAGEBRUSH_JUCEHEADER__
/********* End of inlined file: juce_ImageBrush.h *********/

#endif
#ifndef __JUCE_SOLIDCOLOURBRUSH_JUCEHEADER__

#endif
#ifndef __JUCE_COLOUR_JUCEHEADER__

#endif
#ifndef __JUCE_COLOURGRADIENT_JUCEHEADER__

#endif
#ifndef __JUCE_COLOURS_JUCEHEADER__

#endif
#ifndef __JUCE_PIXELFORMATS_JUCEHEADER__

#endif
#ifndef __JUCE_FONT_JUCEHEADER__

#endif
#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__

/********* Start of inlined file: juce_GlyphArrangement.h *********/
#ifndef __JUCE_GLYPHARRANGEMENT_JUCEHEADER__
#define __JUCE_GLYPHARRANGEMENT_JUCEHEADER__

/**
    An glyph from a particular font, with a particular size, style,
    typeface and position.

    @see GlyphArrangement, Font
*/
class JUCE_API  PositionedGlyph
{
public:

    /** Returns the character the glyph represents. */
    juce_wchar getCharacter() const throw()     { return glyphInfo->getCharacter(); }
    /** Checks whether the glyph is actually empty. */
    bool isWhitespace() const throw()           { return CharacterFunctions::isWhitespace (glyphInfo->getCharacter()); }

    /** Returns the position of the glyph's left-hand edge. */
    float getLeft() const throw()               { return x; }
    /** Returns the position of the glyph's right-hand edge. */
    float getRight() const throw()              { return x + w; }
    /** Returns the y position of the glyph's baseline. */
    float getBaselineY() const throw()          { return y; }
    /** Returns the y position of the top of the glyph. */
    float getTop() const throw()                { return y - fontAscent; }
    /** Returns the y position of the bottom of the glyph. */
    float getBottom() const throw()             { return y + fontHeight - fontAscent; }

    /** Shifts the glyph's position by a relative amount. */
    void moveBy (const float deltaX,
                 const float deltaY) throw();

    /** Draws the glyph into a graphics context. */
    void draw (const Graphics& g) const throw();

    /** Draws the glyph into a graphics context, with an extra transform applied to it. */
    void draw (const Graphics& g, const AffineTransform& transform) const throw();

    /** Returns the path for this glyph.

        @param path     the glyph's outline will be appended to this path
    */
    void createPath (Path& path) const throw();

    /** Checks to see if a point lies within this glyph. */
    bool hitTest (float x, float y) const throw();

    juce_UseDebuggingNewOperator

private:

    friend class GlyphArrangement;
    float x, y, w;
    float fontHeight, fontAscent, fontHorizontalScale;
    bool isUnderlined;
    const TypefaceGlyphInfo* glyphInfo;

    PositionedGlyph() throw();
};

/**
    A set of glyphs, each with a position.

    You can create a GlyphArrangement, text to it and then draw it onto a
    graphics context. It's used internally by the text methods in the
    Graphics class, but can be used directly if more control is needed.

    @see Font, PositionedGlyph
*/
class JUCE_API  GlyphArrangement
{
public:

    /** Creates an empty arrangement. */
    GlyphArrangement() throw();

    /** Takes a copy of another arrangement. */
    GlyphArrangement (const GlyphArrangement& other) throw();

    /** Copies another arrangement onto this one.

        To add another arrangement without clearing this one, use addGlyphArrangement().
    */
    const GlyphArrangement& operator= (const GlyphArrangement& other) throw();

    /** Destructor. */
    ~GlyphArrangement() throw();

    /** Returns the total number of glyphs in the arrangement. */
    int getNumGlyphs() const throw()                            { return numGlyphs; }

    /** Returns one of the glyphs from the arrangement.

        @param index    the glyph's index, from 0 to (getNumGlyphs() - 1). Be
                        careful not to pass an out-of-range index here, as it
                        doesn't do any bounds-checking.
    */
    PositionedGlyph& getGlyph (const int index) const throw();

    /** Clears all text from the arrangement and resets it.
    */
    void clear() throw();

    /** Appends a line of text to the arrangement.

        This will add the text as a single line, where x is the left-hand edge of the
        first character, and y is the position for the text's baseline.

        If the text contains new-lines or carriage-returns, this will ignore them - use
        addJustifiedText() to add multi-line arrangements.
    */
    void addLineOfText (const Font& font,
                        const String& text,
                        const float x,
                        const float y) throw();

    /** Adds a line of text, truncating it if it's wider than a specified size.

        This is the same as addLineOfText(), but if the line's width exceeds the value
        specified in maxWidthPixels, it will be truncated using either ellipsis (i.e. dots: "..."),
        if useEllipsis is true, or if this is false, it will just drop any subsequent characters.
    */
    void addCurtailedLineOfText (const Font& font,
                                 const String& text,
                                 float x,
                                 const float y,
                                 const float maxWidthPixels,
                                 const bool useEllipsis) throw();

    /** Adds some multi-line text, breaking lines at word-boundaries if they are too wide.

        This will add text to the arrangement, breaking it into new lines either where there
        is a new-line or carriage-return character in the text, or where a line's width
        exceeds the value set in maxLineWidth.

        Each line that is added will be laid out using the flags set in horizontalLayout, so
        the lines can be left- or right-justified, or centred horizontally in the space
        between x and (x + maxLineWidth).

        The y co-ordinate is the position of the baseline of the first line of text - subsequent
        lines will be placed below it, separated by a distance of font.getHeight().
    */
    void addJustifiedText (const Font& font,
                           const String& text,
                           float x, float y,
                           const float maxLineWidth,
                           const Justification& horizontalLayout) throw();

    /** Tries to fit some text withing a given space.

        This does its best to make the given text readable within the specified rectangle,
        so it useful for labelling things.

        If the text is too big, it'll be squashed horizontally or broken over multiple lines
        if the maximumLinesToUse value allows this. If the text just won't fit into the space,
        it'll cram as much as possible in there, and put some ellipsis at the end to show that
        it's been truncated.

        A Justification parameter lets you specify how the text is laid out within the rectangle,
        both horizontally and vertically.

        @see Graphics::drawFittedText
    */
    void addFittedText (const Font& font,
                        const String& text,
                        float x, float y,
                        float width, float height,
                        const Justification& layout,
                        int maximumLinesToUse,
                        const float minimumHorizontalScale = 0.7f) throw();

    /** Appends another glyph arrangement to this one. */
    void addGlyphArrangement (const GlyphArrangement& other) throw();

    /** Draws this glyph arrangement to a graphics context.

        This uses cached bitmaps so is much faster than the draw (Graphics&, const AffineTransform&)
        method, which renders the glyphs as filled vectors.
    */
    void draw (const Graphics& g) const throw();

    /** Draws this glyph arrangement to a graphics context.

        This renders the paths as filled vectors, so is far slower than the draw (Graphics&)
        method for non-transformed arrangements.
    */
    void draw (const Graphics& g, const AffineTransform& transform) const throw();

    /** Converts the set of glyphs into a path.

        @param path     the glyphs' outlines will be appended to this path
    */
    void createPath (Path& path) const throw();

    /** Looks for a glyph that contains the given co-ordinate.

        @returns the index of the glyph, or -1 if none were found.
    */
    int findGlyphIndexAt (float x, float y) const throw();

    /** Finds the smallest rectangle that will enclose a subset of the glyphs.

        @param startIndex               the first glyph to test
        @param numGlyphs                the number of glyphs to include; if this is < 0, all glyphs after
                                        startIndex will be included
        @param left                     on return, the leftmost co-ordinate of the rectangle
        @param top                      on return, the top co-ordinate of the rectangle
        @param right                    on return, the rightmost co-ordinate of the rectangle
        @param bottom                   on return, the bottom co-ordinate of the rectangle
        @param includeWhitespace        if true, the extent of any whitespace characters will also
                                        be taken into account
    */
    void getBoundingBox (int startIndex,
                         int numGlyphs,
                         float& left,
                         float& top,
                         float& right,
                         float& bottom,
                         const bool includeWhitespace) const throw();

    /** Shifts a set of glyphs by a given amount.

        @param startIndex   the first glyph to transform
        @param numGlyphs    the number of glyphs to move; if this is < 0, all glyphs after
                            startIndex will be used
        @param deltaX       the amount to add to their x-positions
        @param deltaY       the amount to add to their y-positions
    */
    void moveRangeOfGlyphs (int startIndex, int numGlyphs,
                            const float deltaX,
                            const float deltaY) throw();

    /** Removes a set of glyphs from the arrangement.

        @param startIndex   the first glyph to remove
        @param numGlyphs    the number of glyphs to remove; if this is < 0, all glyphs after
                            startIndex will be deleted
    */
    void removeRangeOfGlyphs (int startIndex, int numGlyphs) throw();

    /** Expands or compresses a set of glyphs horizontally.

        @param startIndex               the first glyph to transform
        @param numGlyphs                the number of glyphs to stretch; if this is < 0, all glyphs after
                                        startIndex will be used
        @param horizontalScaleFactor    how much to scale their horizontal width by
    */
    void stretchRangeOfGlyphs (int startIndex, int numGlyphs,
                               const float horizontalScaleFactor) throw();

    /** Justifies a set of glyphs within a given space.

        This moves the glyphs as a block so that the whole thing is located within the
        given rectangle with the specified layout.

        If the Justification::horizontallyJustified flag is specified, each line will
        be stretched out to fill the specified width.
    */
    void justifyGlyphs (const int startIndex, const int numGlyphs,
                        const float x,
                        const float y,
                        const float width,
                        const float height,
                        const Justification& justification) throw();

    juce_UseDebuggingNewOperator

private:
    int numGlyphs, numAllocated;
    PositionedGlyph* glyphs;

    void ensureNumGlyphsAllocated (int minGlyphs) throw();
    void removeLast() throw();
    void appendEllipsis (const Font& font, const float maxXPixels) throw();

    void incGlyphRefCount (const int index) const throw();
    void decGlyphRefCount (const int index) const throw();

    void spreadOutLine (const int start, const int numGlyphs, const float targetWidth) throw();
};

#endif   // __JUCE_GLYPHARRANGEMENT_JUCEHEADER__
/********* End of inlined file: juce_GlyphArrangement.h *********/

#endif
#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__

/********* Start of inlined file: juce_TextLayout.h *********/
#ifndef __JUCE_TEXTLAYOUT_JUCEHEADER__
#define __JUCE_TEXTLAYOUT_JUCEHEADER__

class Graphics;

/**
    A laid-out arrangement of text.

    You can add text in different fonts to a TextLayout object, then call its
    layout() method to word-wrap it into lines. The layout can then be drawn
    using a graphics context.

    It's handy if you've got a message to display, because you can format it,
    measure the extent of the layout, and then create a suitably-sized window
    to show it in.

    @see Font, Graphics::drawFittedText, GlyphArrangement
*/
class JUCE_API  TextLayout
{
public:

    /** Creates an empty text layout.

        Text can then be appended using the appendText() method.
    */
    TextLayout() throw();

    /** Creates a copy of another layout object. */
    TextLayout (const TextLayout& other) throw();

    /** Creates a text layout from an initial string and font. */
    TextLayout (const String& text, const Font& font) throw();

    /** Destructor. */
    ~TextLayout() throw();

    /** Copies another layout onto this one. */
    const TextLayout& operator= (const TextLayout& layoutToCopy) throw();

    /** Clears the layout, removing all its text. */
    void clear() throw();

    /** Adds a string to the end of the arrangement.

        The string will be broken onto new lines wherever it contains
        carriage-returns or linefeeds. After adding it, you can call layout()
        to wrap long lines into a paragraph and justify it.
    */
    void appendText (const String& textToAppend,
                     const Font& fontToUse) throw();

    /** Replaces all the text with a new string.

        This is equivalent to calling clear() followed by appendText().
    */
    void setText (const String& newText,
                  const Font& fontToUse) throw();

    /** Breaks the text up to form a paragraph with the given width.

        @param maximumWidth                 any text wider than this will be split
                                            across multiple lines
        @param justification                how the lines are to be laid-out horizontally
        @param attemptToBalanceLineLengths  if true, it will try to split the lines at a
                                            width that keeps all the lines of text at a
                                            similar length - this is good when you're displaying
                                            a short message and don't want it to get split
                                            onto two lines with only a couple of words on
                                            the second line, which looks untidy.
    */
    void layout (int maximumWidth,
                 const Justification& justification,
                 const bool attemptToBalanceLineLengths) throw();

    /** Returns the overall width of the entire text layout. */
    int getWidth() const throw();

    /** Returns the overall height of the entire text layout. */
    int getHeight() const throw();

    /** Returns the total number of lines of text. */
    int getNumLines() const throw()                 { return totalLines; }

    /** Returns the width of a particular line of text.

        @param lineNumber   the line, from 0 to (getNumLines() - 1)
    */
    int getLineWidth (const int lineNumber) const throw();

    /** Renders the text at a specified position using a graphics context.
    */
    void draw (Graphics& g,
               const int topLeftX,
               const int topLeftY) const throw();

    /** Renders the text within a specified rectangle using a graphics context.

        The justification flags dictate how the block of text should be positioned
        within the rectangle.
    */
    void drawWithin (Graphics& g,
                     int x, int y, int w, int h,
                     const Justification& layoutFlags) const throw();

    juce_UseDebuggingNewOperator

private:
    VoidArray tokens;
    int totalLines;
};

#endif   // __JUCE_TEXTLAYOUT_JUCEHEADER__
/********* End of inlined file: juce_TextLayout.h *********/

#endif
#ifndef __JUCE_TYPEFACE_JUCEHEADER__

#endif
#ifndef __JUCE_EDGETABLE_JUCEHEADER__

/********* Start of inlined file: juce_EdgeTable.h *********/
#ifndef __JUCE_EDGETABLE_JUCEHEADER__
#define __JUCE_EDGETABLE_JUCEHEADER__

class Path;

static const int juce_edgeTableDefaultEdgesPerLine = 10;

/**
    A table of horizontal scan-line segments - used for rasterising Paths.

    @see Path, Graphics
*/
class JUCE_API  EdgeTable
{
public:

    /** Indicates the quality at which the edge table should be generated.

        Higher values will have better quality anti-aliasing, but will take
        longer to generate the edge table and to render it.
    */
    enum OversamplingLevel
    {
        Oversampling_none       = 0,    /**< No vertical anti-aliasing at all. */
        Oversampling_4times     = 2,    /**< Anti-aliased with 4 levels of grey - good enough for normal use. */
        Oversampling_16times    = 4,    /**< Anti-aliased with 16 levels of grey - very good quality. */
        Oversampling_32times    = 5,    /**< Anti-aliased with 32 levels of grey - very good quality but slower. */
        Oversampling_256times   = 8     /**< Anti-aliased with 256 levels of grey - best quality, but too slow for
                                             normal user-interface use. */
    };

    /** Creates an empty edge table ready to have paths added.

        A table is created with a fixed vertical size, and only sections of paths
        which lie within their range will be added to the table.

        @param topY                     the lowest y co-ordinate that the table can contain
        @param height                   the number of horizontal lines it can contain
        @param verticalOversampling     the amount of oversampling used for anti-aliasing
        @param expectedEdgesPerLine     used to optimise the table's internal data usage - it's not
                                        worth changing this except for very special purposes
    */
    EdgeTable (const int topY,
               const int height,
               const OversamplingLevel verticalOversampling = Oversampling_4times,
               const int expectedEdgesPerLine = juce_edgeTableDefaultEdgesPerLine) throw();

    /** Creates a copy of another edge table. */
    EdgeTable (const EdgeTable& other) throw();

    /** Copies from another edge table. */
    const EdgeTable& operator= (const EdgeTable& other) throw();

    /** Destructor. */
    ~EdgeTable() throw();

    /** Adds edges to the table for a path.

        This will add horizontal lines to the edge table for any parts of the path
        which lie within the vertical bounds for which this table was created.

        @param path         the path to add
        @param transform    an optional transform to apply to the path while it's
                            being added
    */
    void addPath (const Path& path,
                  const AffineTransform& transform) throw();

    /** Reduces the amount of space the table has allocated.

        This will shrink the table down to use as little memory as possible - useful for
        read-only tables that get stored and re-used for rendering.
    */
    void optimiseTable() throw();

    /** Iterates the lines in the table, for rendering.

        This function will iterate each line in the table, and call a user-defined class
        to render each pixel or continuous line of pixels that the table contains.

        @param iterationCallback    this templated class must contain the following methods:
                                        @code
                                        inline void setEdgeTableYPos (int y);
                                        inline void handleEdgeTablePixel (int x, int alphaLevel) const;
                                        inline void handleEdgeTableLine (int x, int width, int alphaLevel) const;
                                        @endcode
                                        (these don't necessarily have to be 'const', but it might help it go faster)
        @param clipLeft             the left-hand edge of the rectangle which should be iterated
        @param clipTop              the top edge of the rectangle which should be iterated
        @param clipRight            the right-hand edge of the rectangle which should be iterated
        @param clipBottom           the bottom edge of the rectangle which should be iterated
        @param subPixelXOffset      a fraction of 1 pixel by which to shift the table rightwards, in the range 0 to 255
    */
    template <class EdgeTableIterationCallback>
    void iterate (EdgeTableIterationCallback& iterationCallback,
                  const int clipLeft,
                  int clipTop,
                  const int clipRight,
                  int clipBottom,
                  const int subPixelXOffset) const
    {
        if (clipTop < top)
            clipTop = top;

        if (clipBottom > top + height)
            clipBottom = top + height;

        const int* singleLine = table + lineStrideElements
                                          * ((clipTop - top) << (int) oversampling);

        int mergedLineAllocation = 128;
        MemoryBlock temp (mergedLineAllocation * (2 * sizeof (int)));
        int* mergedLine = (int*) temp.getData();

        const int timesOverSampling = 1 << (int) oversampling;

        for (int y = clipTop; y < clipBottom; ++y)
        {
            int numMergedPoints = 0;

            // sort all the oversampled lines into a single merged line ready to draw..
            for (int over = timesOverSampling; --over >= 0;)
            {
                const int* l = singleLine;
                singleLine += lineStrideElements;

                int num = *l;
                jassert (num >= 0);

                if (num > 0)
                {
                    if (numMergedPoints + num >= mergedLineAllocation)
                    {
                        mergedLineAllocation = (numMergedPoints + num + 0x100) & ~0xff;
                        temp.setSize (mergedLineAllocation * (2 * sizeof (int)), false);
                        mergedLine = (int*) temp.getData();
                    }

                    while (--num >= 0)
                    {
                        const int x = *++l;
                        const int winding = *++l;

                        int n = numMergedPoints << 1;

                        while (n > 0)
                        {
                            const int cx = mergedLine [n - 2];

                            if (cx <= x)
                                break;

                            mergedLine [n] = cx;
                            --n;
                            mergedLine [n + 2] = mergedLine [n];
                            --n;
                        }

                        mergedLine [n] = x;
                        mergedLine [n + 1] = winding;

                        ++numMergedPoints;
                    }
                }
            }

            if (--numMergedPoints > 0)
            {
                const int* line = mergedLine;
                int x = subPixelXOffset + *line;
                int level = *++line;
                int levelAccumulator = 0;

                iterationCallback.setEdgeTableYPos (y);

                while (--numMergedPoints >= 0)
                {
                    const int endX = subPixelXOffset + *++line;
                    jassert (endX >= x);

                    const int absLevel = abs (level);
                    int endOfRun = (endX >> 8);

                    if (endOfRun == (x >> 8))
                    {
                        // small segment within the same pixel, so just save it for the next
                        // time round..
                        levelAccumulator += (endX - x) * absLevel;
                    }
                    else
                    {
                        // plot the fist pixel of this segment, including any accumulated
                        // levels from smaller segments that haven't been drawn yet
                        levelAccumulator += (0xff - (x & 0xff)) * absLevel;

                        levelAccumulator >>= 8;
                        if (levelAccumulator > 0xff)
                            levelAccumulator = 0xff;

                        x >>= 8;

                        if (x >= clipRight)
                        {
                            levelAccumulator = 0;
                            break;
                        }

                        if (x >= clipLeft && x < clipRight && levelAccumulator > 0)
                            iterationCallback.handleEdgeTablePixel (x, levelAccumulator);

                        if (++x >= clipRight)
                        {
                            levelAccumulator = 0;
                            break;
                        }

                        // if there's a segment of solid pixels, do it all in one go..
                        if (absLevel > 0 && endOfRun > x)
                        {
                            if (x < clipLeft)
                                x = clipLeft;

                            if (endOfRun > clipRight)
                                endOfRun = clipRight;

                            const int numPix = endOfRun - x;

                            if (numPix > 0)
                                iterationCallback.handleEdgeTableLine (x, numPix,
                                                                       jmin (absLevel, 0xff));
                        }

                        // save the bit at the end to be drawn next time round the loop.
                        levelAccumulator = (endX & 0xff) * absLevel;
                    }

                    level += *++line;
                    x = endX;
                }

                if (levelAccumulator > 0)
                {
                    levelAccumulator >>= 8;
                    if (levelAccumulator > 0xff)
                        levelAccumulator = 0xff;

                    x >>= 8;
                    if (x >= clipLeft && x < clipRight)
                        iterationCallback.handleEdgeTablePixel (x, levelAccumulator);
                }
            }
        }
    }

    juce_UseDebuggingNewOperator

private:
    // table line format: number of points; point0 x, point0 levelDelta, point1 x, point1 levelDelta, etc
    int* table;
    int top, height, maxEdgesPerLine, lineStrideElements;
    OversamplingLevel oversampling;

    // this will assume that the y co-ord is within bounds, and will avoid checking
    // this for speed.
    void addEdgePoint (const int x, const int y, const int winding) throw();

    void remapTableForNumEdges (const int newNumEdgesPerLine) throw();
};

#endif   // __JUCE_EDGETABLE_JUCEHEADER__
/********* End of inlined file: juce_EdgeTable.h *********/

#endif
#ifndef __JUCE_GRAPHICS_JUCEHEADER__

#endif
#ifndef __JUCE_JUSTIFICATION_JUCEHEADER__

#endif
#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__

/********* Start of inlined file: juce_LowLevelGraphicsContext.h *********/
#ifndef __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__
#define __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__

/**
    Interface class for graphics context objects, used internally by the Graphics class.

    Users are not supposed to create instances of this class directly - do your drawing
    via the Graphics object instead.

    It's a base class for different types of graphics context, that may perform software-based
    or OS-accelerated rendering.

    E.g. the LowLevelGraphicsSoftwareRenderer renders onto an image in memory, but other
    subclasses could render directly to a windows HDC, a Quartz context, or an OpenGL
    context.
*/
class JUCE_API  LowLevelGraphicsContext
{
protected:

    LowLevelGraphicsContext();

public:
    virtual ~LowLevelGraphicsContext();

    /** Returns true if this device is vector-based, e.g. a printer. */
    virtual bool isVectorDevice() const = 0;

    /** Moves the origin to a new position.

        The co-ords are relative to the current origin, and indicate the new position
        of (0, 0).
    */
    virtual void setOrigin (int x, int y) = 0;

    /** Cliping co-ords are relative to the origin. */
    virtual bool reduceClipRegion (int x, int y, int w, int h) = 0;

    /** Cliping co-ords are relative to the origin. */
    virtual bool reduceClipRegion (const RectangleList& clipRegion) = 0;

    /** Cliping co-ords are relative to the origin. */
    virtual void excludeClipRegion (int x, int y, int w, int h) = 0;

    virtual void saveState() = 0;
    virtual void restoreState() = 0;

    virtual bool clipRegionIntersects (int x, int y, int w, int h) = 0;
    virtual const Rectangle getClipBounds() const = 0;
    virtual bool isClipEmpty() const = 0;

    virtual void fillRectWithColour (int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents) = 0;
    virtual void fillRectWithGradient (int x, int y, int w, int h, const ColourGradient& gradient) = 0;

    virtual void fillPathWithColour (const Path& path, const AffineTransform& transform, const Colour& colour, EdgeTable::OversamplingLevel quality) = 0;
    virtual void fillPathWithGradient (const Path& path, const AffineTransform& transform, const ColourGradient& gradient, EdgeTable::OversamplingLevel quality) = 0;
    virtual void fillPathWithImage (const Path& path, const AffineTransform& transform,
                                    const Image& image, int imageX, int imageY, float alpha, EdgeTable::OversamplingLevel quality) = 0;

    virtual void fillAlphaChannelWithColour (const Image& alphaImage, int alphaImageX, int alphaImageY, const Colour& colour) = 0;
    virtual void fillAlphaChannelWithGradient (const Image& alphaImage, int alphaImageX, int alphaImageY, const ColourGradient& gradient) = 0;
    virtual void fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY,
                                            const Image& fillerImage, int fillerImageX, int fillerImageY, float alpha) = 0;

    virtual void blendImage (const Image& sourceImage,
                             int destX, int destY, int destW, int destH, int sourceX, int sourceY,
                             float alpha) = 0;

    virtual void blendImageRescaling (const Image& sourceImage,
                                      int destX, int destY, int destW, int destH,
                                      int sourceX, int sourceY, int sourceW, int sourceH,
                                      float alpha, const Graphics::ResamplingQuality quality) = 0;

    virtual void blendImageWarping (const Image& sourceImage,
                                    int srcClipX, int srcClipY, int srcClipW, int srcClipH,
                                    const AffineTransform& transform,
                                    float alpha, const Graphics::ResamplingQuality quality) = 0;

    virtual void drawLine (double x1, double y1, double x2, double y2, const Colour& colour) = 0;

    virtual void drawVerticalLine (const int x, double top, double bottom, const Colour& col) = 0;
    virtual void drawHorizontalLine (const int y, double left, double right, const Colour& col) = 0;
};

#endif   // __JUCE_LOWLEVELGRAPHICSCONTEXT_JUCEHEADER__
/********* End of inlined file: juce_LowLevelGraphicsContext.h *********/

#endif
#ifndef __JUCE_RECTANGLEPLACEMENT_JUCEHEADER__

#endif
#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__

/********* Start of inlined file: juce_LowLevelGraphicsPostScriptRenderer.h *********/
#ifndef __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__
#define __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__

/**
    An implementation of LowLevelGraphicsContext that turns the drawing operations
    into a PostScript document.

*/
class JUCE_API  LowLevelGraphicsPostScriptRenderer    : public LowLevelGraphicsContext
{
public:

    LowLevelGraphicsPostScriptRenderer (OutputStream& resultingPostScript,
                                        const String& documentTitle,
                                        const int totalWidth,
                                        const int totalHeight);

    ~LowLevelGraphicsPostScriptRenderer();

    bool isVectorDevice() const;
    void setOrigin (int x, int y);

    bool reduceClipRegion (int x, int y, int w, int h);
    bool reduceClipRegion (const RectangleList& clipRegion);
    void excludeClipRegion (int x, int y, int w, int h);

    void saveState();
    void restoreState();

    bool clipRegionIntersects (int x, int y, int w, int h);
    const Rectangle getClipBounds() const;
    bool isClipEmpty() const;

    void fillRectWithColour (int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents);
    void fillRectWithGradient (int x, int y, int w, int h, const ColourGradient& gradient);

    void fillPathWithColour (const Path& path, const AffineTransform& transform, const Colour& colour, EdgeTable::OversamplingLevel quality);
    void fillPathWithGradient (const Path& path, const AffineTransform& transform, const ColourGradient& gradient, EdgeTable::OversamplingLevel quality);
    void fillPathWithImage (const Path& path, const AffineTransform& transform,
                            const Image& image, int imageX, int imageY, float alpha, EdgeTable::OversamplingLevel quality);

    void fillAlphaChannelWithColour (const Image& alphaImage, int imageX, int imageY, const Colour& colour);
    void fillAlphaChannelWithGradient (const Image& alphaImage, int imageX, int imageY, const ColourGradient& gradient);
    void fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY,
                                    const Image& fillerImage, int fillerImageX, int fillerImageY, float alpha);

    void blendImage (const Image& sourceImage, int destX, int destY, int destW, int destH,
                     int sourceX, int sourceY, float alpha);

    void blendImageRescaling (const Image& sourceImage, int destX, int destY, int destW, int destH,
                              int sourceX, int sourceY, int sourceW, int sourceH,
                              float alpha, const Graphics::ResamplingQuality quality);

    void blendImageWarping (const Image& sourceImage, int srcClipX, int srcClipY, int srcClipW, int srcClipH,
                            const AffineTransform& transform,
                            float alpha, const Graphics::ResamplingQuality quality);

    void drawLine (double x1, double y1, double x2, double y2, const Colour& colour);

    void drawVerticalLine (const int x, double top, double bottom, const Colour& col);
    void drawHorizontalLine (const int x, double top, double bottom, const Colour& col);

    juce_UseDebuggingNewOperator

protected:

    OutputStream& out;
    RectangleList* clip;
    int totalWidth, totalHeight, xOffset, yOffset;
    bool needToClip;
    Colour lastColour;

    struct SavedState
    {
        SavedState (RectangleList* const clip, const int xOffset, const int yOffset);
        ~SavedState();

        RectangleList* clip;
        const int xOffset, yOffset;

    private:
        SavedState (const SavedState&);
        const SavedState& operator= (const SavedState&);
    };

    OwnedArray <SavedState> stateStack;

    void writeClip();
    void writeColour (const Colour& colour);
    void writePath (const Path& path) const;
    void writeXY (const float x, const float y) const;
    void writeTransform (const AffineTransform& trans) const;
    void writeImage (const Image& im, const int sx, const int sy, const int maxW, const int maxH) const;

    LowLevelGraphicsPostScriptRenderer (const LowLevelGraphicsPostScriptRenderer& other);
    const LowLevelGraphicsPostScriptRenderer& operator= (const LowLevelGraphicsPostScriptRenderer&);
};

#endif   // __JUCE_LOWLEVELGRAPHICSPOSTSCRIPTRENDERER_JUCEHEADER__
/********* End of inlined file: juce_LowLevelGraphicsPostScriptRenderer.h *********/

#endif
#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__

/********* Start of inlined file: juce_LowLevelGraphicsSoftwareRenderer.h *********/
#ifndef __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__
#define __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__

/**
    A lowest-common-denominator implementation of LowLevelGraphicsContext that does all
    its rendering in memory.

    User code is not supposed to create instances of this class directly - do all your
    rendering via the Graphics class instead.
*/
class JUCE_API  LowLevelGraphicsSoftwareRenderer    : public LowLevelGraphicsContext
{
public:

    LowLevelGraphicsSoftwareRenderer (Image& imageToRenderOn);
    ~LowLevelGraphicsSoftwareRenderer();

    bool isVectorDevice() const;

    void setOrigin (int x, int y);

    bool reduceClipRegion (int x, int y, int w, int h);
    bool reduceClipRegion (const RectangleList& clipRegion);
    void excludeClipRegion (int x, int y, int w, int h);

    void saveState();
    void restoreState();

    bool clipRegionIntersects (int x, int y, int w, int h);
    const Rectangle getClipBounds() const;
    bool isClipEmpty() const;

    void fillRectWithColour (int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents);
    void fillRectWithGradient (int x, int y, int w, int h, const ColourGradient& gradient);

    void fillPathWithColour (const Path& path, const AffineTransform& transform, const Colour& colour, EdgeTable::OversamplingLevel quality);
    void fillPathWithGradient (const Path& path, const AffineTransform& transform, const ColourGradient& gradient, EdgeTable::OversamplingLevel quality);
    void fillPathWithImage (const Path& path, const AffineTransform& transform,
                            const Image& image, int imageX, int imageY, float alpha, EdgeTable::OversamplingLevel quality);

    void fillAlphaChannelWithColour (const Image& alphaImage, int imageX, int imageY, const Colour& colour);
    void fillAlphaChannelWithGradient (const Image& alphaImage, int imageX, int imageY, const ColourGradient& gradient);
    void fillAlphaChannelWithImage (const Image& alphaImage, int alphaImageX, int alphaImageY,
                                    const Image& fillerImage, int fillerImageX, int fillerImageY, float alpha);

    void blendImage (const Image& sourceImage, int destX, int destY, int destW, int destH,
                     int sourceX, int sourceY, float alpha);

    void blendImageRescaling (const Image& sourceImage, int destX, int destY, int destW, int destH,
                              int sourceX, int sourceY, int sourceW, int sourceH,
                              float alpha, const Graphics::ResamplingQuality quality);

    void blendImageWarping (const Image& sourceImage, int srcClipX, int srcClipY, int srcClipW, int srcClipH,
                            const AffineTransform& transform,
                            float alpha, const Graphics::ResamplingQuality quality);

    void drawLine (double x1, double y1, double x2, double y2, const Colour& colour);

    void drawVerticalLine (const int x, double top, double bottom, const Colour& col);
    void drawHorizontalLine (const int x, double top, double bottom, const Colour& col);

    RectangleList* getRawClipRegion() throw()                   { return clip; }

    juce_UseDebuggingNewOperator

protected:

    Image& image;
    RectangleList* clip;
    int xOffset, yOffset;

    struct SavedState
    {
        SavedState (RectangleList* const clip, const int xOffset, const int yOffset);
        ~SavedState();

        RectangleList* clip;
        const int xOffset, yOffset;

    private:
        SavedState (const SavedState&);
        const SavedState& operator= (const SavedState&);
    };

    OwnedArray <SavedState> stateStack;

    void drawVertical (const int x, const double top, const double bottom, const Colour& col);
    void drawHorizontal (const int y, const double top, const double bottom, const Colour& col);

    bool getPathBounds (int clipX, int clipY, int clipW, int clipH,
                        const Path& path, const AffineTransform& transform,
                        int& x, int& y, int& w, int& h) const;

    void clippedFillRectWithColour (const Rectangle& clipRect, int x, int y, int w, int h, const Colour& colour, const bool replaceExistingContents);

    void clippedFillPathWithColour (int clipX, int clipY, int clipW, int clipH, const Path& path, const AffineTransform& transform, const Colour& colour, EdgeTable::OversamplingLevel quality);
    void clippedFillPathWithGradient (int clipX, int clipY, int clipW, int clipH, const Path& path, const AffineTransform& transform, const ColourGradient& gradient, EdgeTable::OversamplingLevel quality);
    void clippedFillPathWithImage (int clipX, int clipY, int clipW, int clipH, const Path& path, const AffineTransform& transform,
                                   const Image& image, int imageX, int imageY, float alpha, EdgeTable::OversamplingLevel quality);

    void clippedFillAlphaChannelWithColour (int clipX, int clipY, int clipW, int clipH, const Image& alphaImage, int alphaImageX, int alphaImageY, const Colour& colour);
    void clippedFillAlphaChannelWithGradient (int clipX, int clipY, int clipW, int clipH, const Image& alphaImage, int alphaImageX, int alphaImageY, const ColourGradient& gradient);
    void clippedFillAlphaChannelWithImage (int clipX, int clipY, int clipW, int clipH, const Image& alphaImage, int alphaImageX, int alphaImageY,
                                           const Image& fillerImage, int fillerImageX, int fillerImageY, float alpha);

    void clippedBlendImage (int clipX, int clipY, int clipW, int clipH, const Image& sourceImage,
                            int destX, int destY, int destW, int destH, int sourceX, int sourceY,
                            float alpha);

    void clippedBlendImageWarping (int clipX, int clipY, int clipW, int clipH, const Image& sourceImage,
                                   int srcClipX, int srcClipY, int srcClipW, int srcClipH,
                                   const AffineTransform& transform,
                                   float alpha, const Graphics::ResamplingQuality quality);

    void clippedDrawLine (int clipX, int clipY, int clipW, int clipH, double x1, double y1, double x2, double y2, const Colour& colour);

    void clippedDrawVerticalLine (int clipX, int clipY, int clipW, int clipH, const int x, double top, double bottom, const Colour& col);
    void clippedDrawHorizontalLine (int clipX, int clipY, int clipW, int clipH, const int x, double top, double bottom, const Colour& col);

    LowLevelGraphicsSoftwareRenderer (const LowLevelGraphicsSoftwareRenderer& other);
    const LowLevelGraphicsSoftwareRenderer& operator= (const LowLevelGraphicsSoftwareRenderer&);
};

#endif   // __JUCE_LOWLEVELGRAPHICSSOFTWARERENDERER_JUCEHEADER__
/********* End of inlined file: juce_LowLevelGraphicsSoftwareRenderer.h *********/

#endif
#ifndef __JUCE_AFFINETRANSFORM_JUCEHEADER__

#endif
#ifndef __JUCE_BORDERSIZE_JUCEHEADER__

#endif
#ifndef __JUCE_LINE_JUCEHEADER__

#endif
#ifndef __JUCE_PATH_JUCEHEADER__

#endif
#ifndef __JUCE_PATHITERATOR_JUCEHEADER__

/********* Start of inlined file: juce_PathIterator.h *********/
#ifndef __JUCE_PATHITERATOR_JUCEHEADER__
#define __JUCE_PATHITERATOR_JUCEHEADER__

/**
    Flattens a Path object into a series of straight-line sections.

    Use one of these to iterate through a Path object, and it will convert
    all the curves into line sections so it's easy to render or perform
    geometric operations on.

    @see Path
*/
class JUCE_API  PathFlatteningIterator
{
public:

    /** Creates a PathFlatteningIterator.

        After creation, use the next() method to initialise the fields in the
        object with the first line's position.

        @param path         the path to iterate along
        @param transform    a transform to apply to each point in the path being iterated
        @param tolerence    the amount by which the curves are allowed to deviate from the
                            lines into which they are being broken down - a higher tolerence
                            is a bit faster, but less smooth.
    */
    PathFlatteningIterator (const Path& path,
                            const AffineTransform& transform = AffineTransform::identity,
                            float tolerence = 9.0f) throw();

    /** Destructor. */
    ~PathFlatteningIterator() throw();

    /** Fetches the next line segment from the path.

        This will update the member variables x1, y1, x2, y2, subPathIndex and closesSubPath
        so that they describe the new line segment.

        @returns false when there are no more lines to fetch.
    */
    bool next() throw();

    /** The x position of the start of the current line segment. */
    float x1;
    /** The y position of the start of the current line segment. */
    float y1;
    /** The x position of the end of the current line segment. */
    float x2;
    /** The y position of the end of the current line segment. */
    float y2;

    /** Indicates whether the current line segment is closing a sub-path.

        If the current line is the one that connects the end of a sub-path
        back to the start again, this will be true.
    */
    bool closesSubPath;

    /** The index of the current line within the current sub-path.

        E.g. you can use this to see whether the line is the first one in the
        subpath by seeing if it's 0.
    */
    int subPathIndex;

    /** Returns true if the current segment is the last in the current sub-path. */
    bool isLastInSubpath() const throw()    { return stackPos == stackBase
                                                      && (index >= path.numElements
                                                           || points [index] == Path::moveMarker); }

    juce_UseDebuggingNewOperator

private:
    const Path& path;
    const AffineTransform transform;
    float* points;
    float tolerence, subPathCloseX, subPathCloseY;
    bool isIdentityTransform;

    float* stackBase;
    float* stackPos;
    int index, stackSize;

    PathFlatteningIterator (const PathFlatteningIterator&);
    const PathFlatteningIterator& operator= (const PathFlatteningIterator&);
};

#endif   // __JUCE_PATHITERATOR_JUCEHEADER__
/********* End of inlined file: juce_PathIterator.h *********/

#endif
#ifndef __JUCE_PATHSTROKETYPE_JUCEHEADER__

#endif
#ifndef __JUCE_POINT_JUCEHEADER__

#endif
#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__

/********* Start of inlined file: juce_PositionedRectangle.h *********/
#ifndef __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__
#define __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__

/**
    A rectangle whose co-ordinates can be defined in terms of absolute or
    proportional distances.

    Designed mainly for storing component positions, this gives you a lot of
    control over how each co-ordinate is stored, either as an absolute position,
    or as a proportion of the size of a parent rectangle.

    It also allows you to define the anchor points by which the rectangle is
    positioned, so for example you could specify that the top right of the
    rectangle should be an absolute distance from its parent's bottom-right corner.

    This object can be stored as a string, which takes the form "x y w h", including
    symbols like '%' and letters to indicate the anchor point. See its toString()
    method for more info.

    Example usage:
    @code
    class MyComponent
    {
        void resized()
        {
            // this will set the child component's x to be 20% of our width, its y
            // to be 30, its width to be 150, and its height to be 50% of our
            // height..
            const PositionedRectangle pos1 ("20% 30 150 50%");
            pos1.applyToComponent (*myChildComponent1);

            // this will inset the child component with a gap of 10 pixels
            // around each of its edges..
            const PositionedRectangle pos2 ("10 10 20M 20M");
            pos2.applyToComponent (*myChildComponent2);
        }
    };
    @endcode
*/
class JUCE_API  PositionedRectangle
{
public:

    /** Creates an empty rectangle with all co-ordinates set to zero.

        The default anchor point is top-left; the default
    */
    PositionedRectangle() throw();

    /** Initialises a PositionedRectangle from a saved string version.

        The string must be in the format generated by toString().
    */
    PositionedRectangle (const String& stringVersion) throw();

    /** Creates a copy of another PositionedRectangle. */
    PositionedRectangle (const PositionedRectangle& other) throw();

    /** Copies another PositionedRectangle. */
    const PositionedRectangle& operator= (const PositionedRectangle& other) throw();

    /** Destructor. */
    ~PositionedRectangle() throw();

    /** Returns a string version of this position, from which it can later be
        re-generated.

        The format is four co-ordinates, "x y w h".

        - If a co-ordinate is absolute, it is stored as an integer, e.g. "100".
        - If a co-ordinate is proportional to its parent's width or height, it is stored
          as a percentage, e.g. "80%".
        - If the X or Y co-ordinate is relative to the parent's right or bottom edge, the
          number has "R" appended to it, e.g. "100R" means a distance of 100 pixels from
          the parent's right-hand edge.
        - If the X or Y co-ordinate is relative to the parent's centre, the number has "C"
          appended to it, e.g. "-50C" would be 50 pixels left of the parent's centre.
        - If the X or Y co-ordinate should be anchored at the component's right or bottom
          edge, then it has "r" appended to it. So "-50Rr" would mean that this component's
          right-hand edge should be 50 pixels left of the parent's right-hand edge.
        - If the X or Y co-ordinate should be anchored at the component's centre, then it
          has "c" appended to it. So "-50Rc" would mean that this component's
          centre should be 50 pixels left of the parent's right-hand edge. "40%c" means that
          this component's centre should be placed 40% across the parent's width.
        - If it's a width or height that should use the parentSizeMinusAbsolute mode, then
          the number has "M" appended to it.

        To reload a stored string, use the constructor that takes a string parameter.
    */
    const String toString() const throw();

    /** Calculates the absolute position, given the size of the space that
        it should go in.

        This will work out any proportional distances and sizes relative to the
        target rectangle, and will return the absolute position.

        @see applyToComponent
    */
    const Rectangle getRectangle (const Rectangle& targetSpaceToBeRelativeTo) const throw();

    /** Same as getRectangle(), but returning the values as doubles rather than ints.
    */
    void getRectangleDouble (const Rectangle& targetSpaceToBeRelativeTo,
                             double& x,
                             double& y,
                             double& width,
                             double& height) const throw();

    /** This sets the bounds of the given component to this position.

        This is equivalent to writing:
        @code
        comp.setBounds (getRectangle (Rectangle (0, 0, comp.getParentWidth(), comp.getParentHeight())));
        @endcode

        @see getRectangle, updateFromComponent
    */
    void applyToComponent (Component& comp) const throw();

    /** Updates this object's co-ordinates to match the given rectangle.

        This will set all co-ordinates based on the given rectangle, re-calculating
        any proportional distances, and using the current anchor points.

        So for example if the x co-ordinate mode is currently proportional, this will
        re-calculate x based on the rectangle's relative position within the target
        rectangle's width.

        If the target rectangle's width or height are zero then it may not be possible
        to re-calculate some proportional co-ordinates. In this case, those co-ordinates
        will not be changed.
    */
    void updateFrom (const Rectangle& newPosition,
                     const Rectangle& targetSpaceToBeRelativeTo) throw();

    /** Same functionality as updateFrom(), but taking doubles instead of ints.
    */
    void updateFromDouble (const double x, const double y,
                           const double width, const double height,
                           const Rectangle& targetSpaceToBeRelativeTo) throw();

    /** Updates this object's co-ordinates to match the bounds of this component.

        This is equivalent to calling updateFrom() with the component's bounds and
        it parent size.

        If the component doesn't currently have a parent, then proportional co-ordinates
        might not be updated because it would need to know the parent's size to do the
        maths for this.
    */
    void updateFromComponent (const Component& comp) throw();

    /** Specifies the point within the rectangle, relative to which it should be positioned. */
    enum AnchorPoint
    {
        anchorAtLeftOrTop              = 1 << 0,    /**< The x or y co-ordinate specifies where the left or top edge of the rectangle should be. */
        anchorAtRightOrBottom          = 1 << 1,    /**< The x or y co-ordinate specifies where the right or bottom edge of the rectangle should be. */
        anchorAtCentre                 = 1 << 2     /**< The x or y co-ordinate specifies where the centre of the rectangle should be. */
    };

    /** Specifies how an x or y co-ordinate should be interpreted. */
    enum PositionMode
    {
        absoluteFromParentTopLeft       = 1 << 3,   /**< The x or y co-ordinate specifies an absolute distance from the parent's top or left edge. */
        absoluteFromParentBottomRight   = 1 << 4,   /**< The x or y co-ordinate specifies an absolute distance from the parent's bottom or right edge. */
        absoluteFromParentCentre        = 1 << 5,   /**< The x or y co-ordinate specifies an absolute distance from the parent's centre. */
        proportionOfParentSize          = 1 << 6    /**< The x or y co-ordinate specifies a proportion of the parent's width or height, measured from the parent's top or left. */
    };

    /** Specifies how the width or height should be interpreted. */
    enum SizeMode
    {
        absoluteSize                    = 1 << 0,   /**< The width or height specifies an absolute size. */
        parentSizeMinusAbsolute         = 1 << 1,   /**< The width or height is an amount that should be subtracted from the parent's width or height. */
        proportionalSize                = 1 << 2,   /**< The width or height specifies a proportion of the parent's width or height. */
    };

    /** Sets all options for all co-ordinates.

        This requires a reference rectangle to be specified, because if you're changing any
        of the modes from proportional to absolute or vice-versa, then it'll need to convert
        the co-ordinates, and will need to know the parent size so it can calculate this.
    */
    void setModes (const AnchorPoint xAnchorMode,
                   const PositionMode xPositionMode,
                   const AnchorPoint yAnchorMode,
                   const PositionMode yPositionMode,
                   const SizeMode widthMode,
                   const SizeMode heightMode,
                   const Rectangle& targetSpaceToBeRelativeTo) throw();

    /** Returns the anchoring mode for the x co-ordinate.
        To change any of the modes, use setModes().
    */
    AnchorPoint getAnchorPointX() const throw();

    /** Returns the positioning mode for the x co-ordinate.
        To change any of the modes, use setModes().
    */
    PositionMode getPositionModeX() const throw();

    /** Returns the raw x co-ordinate.

        If the x position mode is absolute, then this will be the absolute value. If it's
        proportional, then this will be a fractional proportion, where 1.0 means the full
        width of the parent space.
    */
    double getX() const throw()                             { return x; }

    /** Sets the raw value of the x co-ordinate.

        See getX() for the meaning of this value.
    */
    void setX (const double newX) throw()                   { x = newX; }

    /** Returns the anchoring mode for the y co-ordinate.
        To change any of the modes, use setModes().
    */
    AnchorPoint getAnchorPointY() const throw();

    /** Returns the positioning mode for the y co-ordinate.
        To change any of the modes, use setModes().
    */
    PositionMode getPositionModeY() const throw();

    /** Returns the raw y co-ordinate.

        If the y position mode is absolute, then this will be the absolute value. If it's
        proportional, then this will be a fractional proportion, where 1.0 means the full
        height of the parent space.
    */
    double getY() const throw()                             { return y; }

    /** Sets the raw value of the y co-ordinate.

        See getY() for the meaning of this value.
    */
    void setY (const double newY) throw()                   { y = newY; }

    /** Returns the mode used to calculate the width.
        To change any of the modes, use setModes().
    */
    SizeMode getWidthMode() const throw();

    /** Returns the raw width value.

        If the width mode is absolute, then this will be the absolute value. If the mode is
        proportional, then this will be a fractional proportion, where 1.0 means the full
        width of the parent space.
    */
    double getWidth() const throw()                         { return w; }

    /** Sets the raw width value.

        See getWidth() for the details about what this value means.
    */
    void setWidth (const double newWidth) throw()           { w = newWidth; }

    /** Returns the mode used to calculate the height.
        To change any of the modes, use setModes().
    */
    SizeMode getHeightMode() const throw();

    /** Returns the raw height value.

        If the height mode is absolute, then this will be the absolute value. If the mode is
        proportional, then this will be a fractional proportion, where 1.0 means the full
        height of the parent space.
    */
    double getHeight() const throw()                        { return h; }

    /** Sets the raw height value.

        See getHeight() for the details about what this value means.
    */
    void setHeight (const double newHeight) throw()         { h = newHeight; }

    /** If the size and position are constance, and wouldn't be affected by changes
        in the parent's size, then this will return true.
    */
    bool isPositionAbsolute() const throw();

    /** Compares two objects. */
    const bool operator== (const PositionedRectangle& other) const throw();

    /** Compares two objects. */
    const bool operator!= (const PositionedRectangle& other) const throw();

    juce_UseDebuggingNewOperator

private:
    double x, y, w, h;
    uint8 xMode, yMode, wMode, hMode;

    void addPosDescription (String& result, const uint8 mode, const double value) const throw();
    void addSizeDescription (String& result, const uint8 mode, const double value) const throw();
    void decodePosString (const String& s, uint8& mode, double& value) throw();
    void decodeSizeString (const String& s, uint8& mode, double& value) throw();
    void applyPosAndSize (double& xOut, double& wOut, const double x, const double w,
                          const uint8 xMode, const uint8 wMode,
                          const int parentPos, const int parentSize) const throw();
    void updatePosAndSize (double& xOut, double& wOut, double x, const double w,
                           const uint8 xMode, const uint8 wMode,
                           const int parentPos, const int parentSize) const throw();
};

#endif   // __JUCE_POSITIONEDRECTANGLE_JUCEHEADER__
/********* End of inlined file: juce_PositionedRectangle.h *********/

#endif
#ifndef __JUCE_RECTANGLE_JUCEHEADER__

#endif
#ifndef __JUCE_RECTANGLELIST_JUCEHEADER__

#endif
#ifndef __JUCE_IMAGE_JUCEHEADER__

#endif
#ifndef __JUCE_IMAGECACHE_JUCEHEADER__

/********* Start of inlined file: juce_ImageCache.h *********/
#ifndef __JUCE_IMAGECACHE_JUCEHEADER__
#define __JUCE_IMAGECACHE_JUCEHEADER__

/**
    A global cache of images that have been loaded from files or memory.

    If you're loading an image and may need to use the image in more than one
    place, this is used to allow the same image to be shared rather than loading
    multiple copies into memory.

    Another advantage is that after images are released, they will be kept in
    memory for a few seconds before it is actually deleted, so if you're repeatedly
    loading/deleting the same image, it'll reduce the chances of having to reload it
    each time.

    @see Image, ImageFileFormat
*/
class JUCE_API  ImageCache  : private DeletedAtShutdown,
                              private Timer
{
public:

    /** Loads an image from a file, (or just returns the image if it's already cached).

        If the cache already contains an image that was loaded from this file,
        that image will be returned. Otherwise, this method will try to load the
        file, add it to the cache, and return it.

        It's very important not to delete the image that is returned - instead use
        the ImageCache::release() method.

        Also, remember that the image returned is shared, so drawing into it might
        affect other things that are using it!

        @param file     the file to try to load
        @returns        the image, or null if it there was an error loading it
        @see release, getFromMemory, getFromCache, ImageFileFormat::loadFrom
    */
    static Image* getFromFile (const File& file);

    /** Loads an image from an in-memory image file, (or just returns the image if it's already cached).

        If the cache already contains an image that was loaded from this block of memory,
        that image will be returned. Otherwise, this method will try to load the
        file, add it to the cache, and return it.

        It's very important not to delete the image that is returned - instead use
        the ImageCache::release() method.

        Also, remember that the image returned is shared, so drawing into it might
        affect other things that are using it!

        @param imageData    the block of memory containing the image data
        @param dataSize     the data size in bytes
        @returns            the image, or null if it there was an error loading it
        @see release, getFromMemory, getFromCache, ImageFileFormat::loadFrom
    */
    static Image* getFromMemory (const void* imageData,
                                 const int dataSize);

    /** Releases an image that was previously created by the ImageCache.

        If an image has been returned by the getFromFile() or getFromMemory() methods,
        it mustn't be deleted directly, but should be released with this method
        instead.

        @see getFromFile, getFromMemory
    */
    static void release (Image* const imageToRelease);

    /** Checks whether an image is in the cache or not.

        @returns true if the image is currently in the cache
    */
    static bool isImageInCache (Image* const imageToLookFor);

    /** Increments the reference-count for a cached image.

        If the image isn't in the cache, this method won't do anything.
    */
    static void incReferenceCount (Image* const image);

    /** Checks the cache for an image with a particular hashcode.

        If there's an image in the cache with this hashcode, it will be returned,
        otherwise it will return zero.

        If an image is returned, it must be released with the release() method
        when no longer needed, to maintain the correct reference counts.

        @param hashCode the hash code that would have been associated with the
                        image by addImageToCache()
        @see addImageToCache
    */
    static Image* getFromHashCode (const int64 hashCode);

    /** Adds an image to the cache with a user-defined hash-code.

        After calling this, responsibilty for deleting the image will be taken
        by the ImageCache.

        The image will be initially be given a reference count of 1, so call
        the release() method to delete it.

        @param image    the image to add
        @param hashCode the hash-code to associate with it
        @see getFromHashCode
    */
    static void addImageToCache (Image* const image,
                                 const int64 hashCode);

    /** Changes the amount of time before an unused image will be removed from the cache.

        By default this is about 5 seconds.
    */
    static void setCacheTimeout (const int millisecs);

    juce_UseDebuggingNewOperator

private:

    CriticalSection lock;
    VoidArray images;

    ImageCache() throw();
    ImageCache (const ImageCache&);
    const ImageCache& operator= (const ImageCache&);
    ~ImageCache();

    void timerCallback();
};

#endif   // __JUCE_IMAGECACHE_JUCEHEADER__
/********* End of inlined file: juce_ImageCache.h *********/

#endif
#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__

/********* Start of inlined file: juce_ImageConvolutionKernel.h *********/
#ifndef __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__
#define __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__

/**
    Represents a filter kernel to use in convoluting an image.

    @see Image::applyConvolution
*/
class JUCE_API  ImageConvolutionKernel
{
public:

    /** Creates an empty convulution kernel.

        @param size     the length of each dimension of the kernel, so e.g. if the size
                        is 5, it will create a 5x5 kernel
    */
    ImageConvolutionKernel (const int size) throw();

    /** Destructor. */
    ~ImageConvolutionKernel() throw();

    /** Resets all values in the kernel to zero.
    */
    void clear() throw();

    /** Sets the value of a specific cell in the kernel.

        The x and y parameters must be in the range 0 < x < getKernelSize().

        @see setOverallSum
    */
    void setKernelValue (const int x,
                         const int y,
                         const float value) throw();

    /** Rescales all values in the kernel to make the total add up to a fixed value.

        This will multiply all values in the kernel by (desiredTotalSum / currentTotalSum).
    */
    void setOverallSum (const float desiredTotalSum) throw();

    /** Multiplies all values in the kernel by a value. */
    void rescaleAllValues (const float multiplier) throw();

    /** Intialises the kernel for a gaussian blur.

        @param blurRadius   this may be larger or smaller than the kernel's actual
                            size but this will obviously be wasteful or clip at the
                            edges. Ideally the kernel should be just larger than
                            (blurRadius * 2).
    */
    void createGaussianBlur (const float blurRadius) throw();

    /** Returns the size of the kernel.

        E.g. if it's a 3x3 kernel, this returns 3.
    */
    int getKernelSize() const throw()       { return size; }

    /** Returns a 2-dimensional array of the kernel's values.

        The size of each dimension of the array will be getKernelSize().
    */
    float** getValues() const throw()       { return values; }

    /** Applies the kernel to an image.

        @param destImage        the image that will receive the resultant convoluted pixels.
        @param sourceImage      an optional source image to read from - if this is 0, then the
                                destination image will be used as the source. If an image is
                                specified, it must be exactly the same size and type as the destination
                                image.
        @param x                the region of the image to apply the filter to
        @param y                the region of the image to apply the filter to
        @param width            the region of the image to apply the filter to
        @param height           the region of the image to apply the filter to
    */
    void applyToImage (Image& destImage,
                       const Image* sourceImage,
                       int x,
                       int y,
                       int width,
                       int height) const;

    juce_UseDebuggingNewOperator

private:
    float** values;
    int size;

    // no reason not to implement these one day..
    ImageConvolutionKernel (const ImageConvolutionKernel&);
    const ImageConvolutionKernel& operator= (const ImageConvolutionKernel&);
};

#endif   // __JUCE_IMAGECONVOLUTIONKERNEL_JUCEHEADER__
/********* End of inlined file: juce_ImageConvolutionKernel.h *********/

#endif
#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__

/********* Start of inlined file: juce_CameraDevice.h *********/
#ifndef __JUCE_CAMERADEVICE_JUCEHEADER__
#define __JUCE_CAMERADEVICE_JUCEHEADER__

#if JUCE_USE_CAMERA

/**
    Receives callbacks with images from a CameraDevice.

    @see CameraDevice::addListener
*/
class CameraImageListener
{
public:
    CameraImageListener() {}
    virtual ~CameraImageListener() {}

    /** This method is called when a new image arrives.

        This may be called by any thread, so be careful about thread-safety,
        and make sure that you process the data as quickly as possible to
        avoid glitching!
    */
    virtual void imageReceived (Image& image) = 0;
};

/**
    Controls any camera capture devices that might be available.

    Use getAvailableDevices() to list the devices that are attached to the
    system, then call openDevice to open one for use. Once you have a CameraDevice
    object, you can get a viewer component from it, and use its methods to
    stream to a file or capture still-frames.
*/
class JUCE_API  CameraDevice
{
public:
    /** Destructor. */
    virtual ~CameraDevice();

    /** Returns a list of the available cameras on this machine.

        You can open one of these devices by calling openDevice().
    */
    static const StringArray getAvailableDevices();

    /** Opens a camera device.

        The index parameter indicates which of the items returned by getAvailableDevices()
        to open.

        The size constraints allow the method to choose between different resolutions if
        the camera supports this. If the resolution cam't be specified (e.g. on the Mac)
        then these will be ignored.
    */
    static CameraDevice* openDevice (int deviceIndex,
                                     int minWidth = 128, int minHeight = 64,
                                     int maxWidth = 1024, int maxHeight = 768);

    /** Returns the name of this device */
    const String getName() const throw()        { return name; }

    /** Creates a component that can be used to display a preview of the
        video from this camera.
    */
    Component* createViewerComponent();

    /** Starts recording video to the specified file.

        You should use getFileExtension() to find out the correct extension to
        use for your filename.

        If the file exists, it will be deleted before the recording starts.

        This method may not start recording instantly, so if you need to know the
        exact time at which the file begins, you can call getTimeOfFirstRecordedFrame()
        after the recording has finished.
    */
    void startRecordingToFile (const File& file);

    /** Stops recording, after a call to startRecordingToFile().
    */
    void stopRecording();

    /** Returns the file extension that should be used for the files
        that you pass to startRecordingToFile().

        This may be platform-specific, e.g. ".mov" or ".avi".
    */
    static const String getFileExtension();

    /** After calling stopRecording(), this method can be called to return the timestamp
        of the first frame that was written to the file.
    */
    const Time getTimeOfFirstRecordedFrame() const;

    /** Adds a listener to receive images from the camera.

        Be very careful not to delete the listener without first removing it by calling
        removeListener().
    */
    void addListener (CameraImageListener* listenerToAdd);

    /** Removes a listener that was previously added with addListener().
    */
    void removeListener (CameraImageListener* listenerToRemove);

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    CameraDevice (const String& name, int index);

private:
    void* internal;
    bool isRecording;
    String name;

    CameraDevice (const CameraDevice&);
    const CameraDevice& operator= (const CameraDevice&);
};

#endif
#endif   // __JUCE_CAMERADEVICE_JUCEHEADER__
/********* End of inlined file: juce_CameraDevice.h *********/

#endif
#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__

/********* Start of inlined file: juce_ImageFileFormat.h *********/
#ifndef __JUCE_IMAGEFILEFORMAT_JUCEHEADER__
#define __JUCE_IMAGEFILEFORMAT_JUCEHEADER__

/**
    Base-class for codecs that can read and write image file formats such
    as PNG, JPEG, etc.

    This class also contains static methods to make it easy to load images
    from files, streams or from memory.

    @see Image, ImageCache
*/
class JUCE_API  ImageFileFormat
{
protected:

    /** Creates an ImageFormat. */
    ImageFileFormat() throw()           {}

public:
    /** Destructor. */
    virtual ~ImageFileFormat() throw()  {}

    /** Returns a description of this file format.

        E.g. "JPEG", "PNG"
    */
    virtual const String getFormatName() = 0;

    /** Returns true if the given stream seems to contain data that this format
        understands.

        The format class should only read the first few bytes of the stream and sniff
        for header bytes that it understands.

        @see decodeImage
    */
    virtual bool canUnderstand (InputStream& input) = 0;

    /** Tries to decode and return an image from the given stream.

        This will be called for an image format after calling its canUnderStand() method
        to see if it can handle the stream.

        @param input    the stream to read the data from. The stream will be positioned
                        at the start of the image data (but this may not necessarily
                        be position 0)
        @returns        the image that was decoded, or 0 if it fails. It's the
                        caller's responsibility to delete this image when no longer needed.
        @see loadFrom
    */
    virtual Image* decodeImage (InputStream& input) = 0;

    /** Attempts to write an image to a stream.

        To specify extra information like encoding quality, there will be appropriate parameters
        in the subclasses of the specific file types.

        @returns        true if it nothing went wrong.
    */
    virtual bool writeImageToStream (const Image& sourceImage,
                                     OutputStream& destStream) = 0;

    /** Tries the built-in decoders to see if it can find one to read this stream.

        There are currently built-in decoders for PNG, JPEG and GIF formats.

        The object that is returned should not be deleted by the caller.

        @see canUnderstand, decodeImage, loadFrom
    */
    static ImageFileFormat* findImageFormatForStream (InputStream& input);

    /** Tries to load an image from a stream.

        This will use the findImageFormatForStream() method to locate a suitable
        codec, and use that to load the image.

        @returns  the image that was decoded, or 0 if it fails to load one. It's the
                  caller's responsibility to delete this image when no longer needed.
    */
    static Image* loadFrom (InputStream& input);

    /** Tries to load an image from a file.

        This will use the findImageFormatForStream() method to locate a suitable
        codec, and use that to load the image.

        @returns  the image that was decoded, or 0 if it fails to load one. It's the
                  caller's responsibility to delete this image when no longer needed.
    */
    static Image* loadFrom (const File& file);

    /** Tries to load an image from a block of raw image data.

        This will use the findImageFormatForStream() method to locate a suitable
        codec, and use that to load the image.

        @returns  the image that was decoded, or 0 if it fails to load one. It's the
                  caller's responsibility to delete this image when no longer needed.
    */
    static Image* loadFrom (const void* rawData,
                            const int numBytesOfData);

};

/**
    A type of ImageFileFormat for reading and writing PNG files.

    @see ImageFileFormat, JPEGImageFormat
*/
class JUCE_API  PNGImageFormat  : public ImageFileFormat
{
public:

    PNGImageFormat() throw();
    ~PNGImageFormat() throw();

    const String getFormatName();
    bool canUnderstand (InputStream& input);

    Image* decodeImage (InputStream& input);

    bool writeImageToStream (const Image& sourceImage, OutputStream& destStream);
};

/**
    A type of ImageFileFormat for reading and writing JPEG files.

    @see ImageFileFormat, PNGImageFormat
*/
class JUCE_API  JPEGImageFormat  : public ImageFileFormat
{
public:

    JPEGImageFormat() throw();
    ~JPEGImageFormat() throw();

    /** Specifies the quality to be used when writing a JPEG file.

        @param newQuality  a value 0 to 1.0, where 0 is low quality, 1.0 is best, or
                           any negative value is "default" quality
    */
    void setQuality (const float newQuality);

    const String getFormatName();

    bool canUnderstand (InputStream& input);

    Image* decodeImage (InputStream& input);

    bool writeImageToStream (const Image& sourceImage, OutputStream& destStream);

private:
    float quality;
};

#endif   // __JUCE_IMAGEFILEFORMAT_JUCEHEADER__
/********* End of inlined file: juce_ImageFileFormat.h *********/

#endif
#ifndef __JUCE_DRAWABLE_JUCEHEADER__

/********* Start of inlined file: juce_Drawable.h *********/
#ifndef __JUCE_DRAWABLE_JUCEHEADER__
#define __JUCE_DRAWABLE_JUCEHEADER__

/**
    The base class for objects which can draw themselves, e.g. polygons, images, etc.

    @see DrawableComposite, DrawableImage, DrawablePath, DrawableText
*/
class JUCE_API  Drawable
{
protected:

    /** The base class can't be instantiated directly.

        @see DrawableComposite, DrawableImage, DrawablePath, DrawableText
    */
    Drawable();

public:
    /** Destructor. */
    virtual ~Drawable();

    /** Creates a deep copy of this Drawable object.

        Use this to create a new copy of this and any sub-objects in the tree.
    */
    virtual Drawable* createCopy() const = 0;

    /** Renders this Drawable object.

        This is the main rendering method you should call to render a Drawable.

        @see drawWithin
    */
    virtual void draw (Graphics& g,
                       const AffineTransform& transform = AffineTransform::identity) const = 0;

    /** Renders the Drawable at a given offset within the Graphics context.

        The co-ordinates passed-in are used to translate the object relative to its own
        origin before drawing it - this is basically a quick way of saying:

        @code
        draw (g, AffineTransform::translation (x, y)).
        @endcode
    */
    void drawAt (Graphics& g,
                 const float x,
                 const float y) const;

    /** Renders the Drawable within a rectangle, scaling it to fit neatly inside without
        changing its aspect-ratio.

        The object can placed arbitrarily within the rectangle based on a Justification type,
        and can either be made as big as possible, or just reduced to fit.

        @param g                        the graphics context to render onto
        @param destX                    top-left of the target rectangle to fit it into
        @param destY                    top-left of the target rectangle to fit it into
        @param destWidth                size of the target rectangle to fit the image into
        @param destHeight               size of the target rectangle to fit the image into
        @param placement                defines the alignment and rescaling to use to fit
                                        this object within the target rectangle.
    */
    void drawWithin (Graphics& g,
                     const int destX,
                     const int destY,
                     const int destWidth,
                     const int destHeight,
                     const RectanglePlacement& placement) const;

    /** Returns the smallest rectangle that can contain this Drawable object.

        Co-ordinates are relative to the object's own origin.
    */
    virtual void getBounds (float& x, float& y, float& width, float& height) const = 0;

    /** Returns true if the given point is somewhere inside this Drawable.

        Co-ordinates are relative to the object's own origin.
    */
    virtual bool hitTest (float x, float y) const = 0;

    /** Returns the name given to this drawable.
        @see setName
    */
    const String& getName() const throw()               { return name; }

    /** Assigns a name to this drawable. */
    void setName (const String& newName) throw()        { name = newName; }

    /** Tries to turn some kind of image file into a drawable.

        The data could be an image that the ImageFileFormat class understands, or it
        could be SVG.
    */
    static Drawable* createFromImageData (const void* data, const int numBytes);

    /** Tries to turn a stream containing some kind of image data into a drawable.

        The data could be an image that the ImageFileFormat class understands, or it
        could be SVG.
    */
    static Drawable* createFromImageDataStream (InputStream& dataSource);

    /** Tries to turn a file containing some kind of image data into a drawable.

        The data could be an image that the ImageFileFormat class understands, or it
        could be SVG.
    */
    static Drawable* createFromImageFile (const File& file);

    /** Attempts to parse an SVG (Scalable Vector Graphics) document, and to turn this
        into a Drawable tree.

        The object returned must be deleted by the caller. If something goes wrong
        while parsing, it may return 0.

        SVG is a pretty large and complex spec, and this doesn't aim to be a full
        implementation, but it can return the basic vector objects.
    */
    static Drawable* createFromSVG (const XmlElement& svgDocument);

    juce_UseDebuggingNewOperator

private:
    Drawable (const Drawable&);
    const Drawable& operator= (const Drawable&);

    String name;
};

#endif   // __JUCE_DRAWABLE_JUCEHEADER__
/********* End of inlined file: juce_Drawable.h *********/

#endif
#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__

/********* Start of inlined file: juce_DrawableComposite.h *********/
#ifndef __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__
#define __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__

/**
    A drawable object which acts as a container for a set of other Drawables.

    @see Drawable
*/
class JUCE_API  DrawableComposite  : public Drawable
{
public:

    /** Creates a composite Drawable.
    */
    DrawableComposite();

    /** Destructor. */
    virtual ~DrawableComposite();

    /** Adds a new sub-drawable to this one.

        This passes in a Drawable pointer for this object to look after. To add a copy
        of a drawable, use the form of this method that takes a Drawable reference instead.

        @param drawable         the object to add - this will be deleted automatically
                                when no longer needed, so the caller mustn't keep any
                                pointers to it.
        @param transform        the transform to apply to this drawable when it's being
                                drawn
        @param index            where to insert it in the list of drawables. 0 is the back,
                                -1 is the front, or any value from 0 and getNumDrawables()
                                can be used
        @see removeDrawable
    */
    void insertDrawable (Drawable* drawable,
                         const AffineTransform& transform = AffineTransform::identity,
                         const int index = -1);

    /** Adds a new sub-drawable to this one.

        This takes a copy of a Drawable and adds it to this object. To pass in a Drawable
        for this object to look after, use the form of this method that takes a Drawable
        pointer instead.

        @param drawable         the object to add - an internal copy will be made of this object
        @param transform        the transform to apply to this drawable when it's being
                                drawn
        @param index            where to insert it in the list of drawables. 0 is the back,
                                -1 is the front, or any value from 0 and getNumDrawables()
                                can be used
        @see removeDrawable
    */
    void insertDrawable (const Drawable& drawable,
                         const AffineTransform& transform = AffineTransform::identity,
                         const int index = -1);

    /** Deletes one of the Drawable objects.

        @param index    the index of the drawable to delete, between 0
                        and (getNumDrawables() - 1).
        @see insertDrawable, getNumDrawables
    */
    void removeDrawable (const int index);

    /** Returns the number of drawables contained inside this one.

        @see getDrawable
    */
    int getNumDrawables() const throw()                         { return drawables.size(); }

    /** Returns one of the drawables that are contained in this one.

        Each drawable also has a transform associated with it - you can use getDrawableTransform()
        to find it.

        The pointer returned is managed by this object and will be deleted when no longer
        needed, so be careful what you do with it.

        @see getNumDrawables
    */
    Drawable* getDrawable (const int index) const throw()                           { return drawables [index]; }

    /** Returns the transform that applies to one of the drawables that are contained in this one.

        The pointer returned is managed by this object and will be deleted when no longer
        needed, so be careful what you do with it.

        @see getNumDrawables
    */
    const AffineTransform* getDrawableTransform (const int index) const throw()     { return transforms [index]; }

    /** Brings one of the Drawables to the front.

        @param index    the index of the drawable to move, between 0
                        and (getNumDrawables() - 1).
        @see insertDrawable, getNumDrawables
    */
    void bringToFront (const int index);

    /** @internal */
    void draw (Graphics& g, const AffineTransform& transform) const;
    /** @internal */
    void getBounds (float& x, float& y, float& width, float& height) const;
    /** @internal */
    bool hitTest (float x, float y) const;
    /** @internal */
    Drawable* createCopy() const;

    juce_UseDebuggingNewOperator

private:
    OwnedArray <Drawable> drawables;
    OwnedArray <AffineTransform> transforms;

    DrawableComposite (const DrawableComposite&);
    const DrawableComposite& operator= (const DrawableComposite&);
};

#endif   // __JUCE_DRAWABLECOMPOSITE_JUCEHEADER__
/********* End of inlined file: juce_DrawableComposite.h *********/

#endif
#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__

/********* Start of inlined file: juce_DrawableImage.h *********/
#ifndef __JUCE_DRAWABLEIMAGE_JUCEHEADER__
#define __JUCE_DRAWABLEIMAGE_JUCEHEADER__

/**
    A drawable object which is a bitmap image.

    @see Drawable
*/
class JUCE_API  DrawableImage  : public Drawable
{
public:

    DrawableImage();

    /** Destructor. */
    virtual ~DrawableImage();

    /** Sets the image that this drawable will render.

        An internal copy is made of the image passed-in. If you want to provide an
        image that this object can take charge of without needing to create a copy,
        use the other setImage() method.
    */
    void setImage (const Image& imageToCopy);

    /** Sets the image that this drawable will render.

        An internal copy of this will not be made, so the caller mustn't delete
        the image while it's still being used by this object.

        A good way to use this is with the ImageCache - if you create an image
        with ImageCache and pass it in here with releaseWhenNotNeeded = true, then
        it'll be released neatly with its reference count being decreased.

        @param imageToUse               the image to render
        @param releaseWhenNotNeeded     if false, a simple pointer is kept to the image; if true,
                                        then the image will be deleted when this object no longer
                                        needs it - unless the image was created by the ImageCache,
                                        in which case it will be released with ImageCache::release().
    */
    void setImage (Image* imageToUse,
                   const bool releaseWhenNotNeeded);

    /** Returns the current image. */
    Image* getImage() const throw()                             { return image; }

    /** Clears (and possibly deletes) the currently set image. */
    void clearImage();

    /** Sets the opacity to use when drawing the image. */
    void setOpacity (const float newOpacity);

    /** Returns the image's opacity. */
    float getOpacity() const throw()                            { return opacity; }

    /** Sets a colour to draw over the image's alpha channel.

        By default this is transparent so isn't drawn, but if you set a non-transparent
        colour here, then it will be overlaid on the image, using the image's alpha
        channel as a mask.

        This is handy for doing things like darkening or lightening an image by overlaying
        it with semi-transparent black or white.
    */
    void setOverlayColour (const Colour& newOverlayColour);

    /** Returns the overlay colour. */
    const Colour& getOverlayColour() const throw()              { return overlayColour; }

    /** @internal */
    void draw (Graphics& g, const AffineTransform& transform) const;
    /** @internal */
    void getBounds (float& x, float& y, float& width, float& height) const;
    /** @internal */
    bool hitTest (float x, float y) const;
    /** @internal */
    Drawable* createCopy() const;

    juce_UseDebuggingNewOperator

private:
    Image* image;
    bool canDeleteImage;
    float opacity;
    Colour overlayColour;

    DrawableImage (const DrawableImage&);
    const DrawableImage& operator= (const DrawableImage&);
};

#endif   // __JUCE_DRAWABLEIMAGE_JUCEHEADER__
/********* End of inlined file: juce_DrawableImage.h *********/

#endif
#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__

/********* Start of inlined file: juce_DrawablePath.h *********/
#ifndef __JUCE_DRAWABLEPATH_JUCEHEADER__
#define __JUCE_DRAWABLEPATH_JUCEHEADER__

/**
    A drawable object which renders a filled or outlined shape.

    @see Drawable
*/
class JUCE_API  DrawablePath  : public Drawable
{
public:

    /** Creates a DrawablePath.
    */
    DrawablePath();

    /** Destructor. */
    virtual ~DrawablePath();

    /** Changes the path that will be drawn.

        @see setSolidFill, setOutline
    */
    void setPath (const Path& newPath);

    /** Returns the current path. */
    const Path& getPath() const throw()                         { return path; }

    /** Sets a colour to fill the path with.

        This colour is used to fill the path - if you don't want the path to be
        filled (e.g. if you're just drawing an outline), set this colour to be
        transparent.

        @see setPath, setOutline
    */
    void setSolidFill (const Colour& newColour);

    /** Sets a custom brush to use to fill the path.

        @see setSolidFill
    */
    void setFillBrush (const Brush& newBrush);

    /** Returns the brush currently being used to fill the shape. */
    Brush* getCurrentBrush() const throw()                      { return fillBrush; }

    /** Changes the properties of the outline that will be drawn around the path.

        If the thickness value is 0, no outline will be drawn. If one is drawn, the
        colour passed-in here will be used for it.

        @see setPath, setSolidFill
    */
    void setOutline (const float thickness,
                     const Colour& outlineColour);

    /** Changes the properties of the outline that will be drawn around the path.

        If the stroke type has 0 thickness, no outline will be drawn.

        @see setPath, setSolidFill
    */
    void setOutline (const PathStrokeType& strokeType,
                     const Brush& strokeBrush);

    /** Returns the current outline style. */
    const PathStrokeType& getOutlineStroke() const throw()      { return strokeType; }

    /** Returns the brush currently being used to draw the outline. */
    Brush* getOutlineBrush() const throw()                      { return strokeBrush; }

    /** @internal */
    void draw (Graphics& g, const AffineTransform& transform) const;
    /** @internal */
    void getBounds (float& x, float& y, float& width, float& height) const;
    /** @internal */
    bool hitTest (float x, float y) const;
    /** @internal */
    Drawable* createCopy() const;

    juce_UseDebuggingNewOperator

private:
    Path path, outline;
    Brush* fillBrush;
    Brush* strokeBrush;
    PathStrokeType strokeType;

    void updateOutline();

    DrawablePath (const DrawablePath&);
    const DrawablePath& operator= (const DrawablePath&);
};

#endif   // __JUCE_DRAWABLEPATH_JUCEHEADER__
/********* End of inlined file: juce_DrawablePath.h *********/

#endif
#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__

/********* Start of inlined file: juce_DrawableText.h *********/
#ifndef __JUCE_DRAWABLETEXT_JUCEHEADER__
#define __JUCE_DRAWABLETEXT_JUCEHEADER__

/**
    A drawable object which renders a line of text.

    @see Drawable
*/
class JUCE_API  DrawableText  : public Drawable
{
public:

    /** Creates a DrawableText object. */
    DrawableText();

    /** Destructor. */
    virtual ~DrawableText();

    /** Sets the block of text to render */
    void setText (const GlyphArrangement& newText);

    /** Sets a single line of text to render.

        This is a convenient method of adding a single line - for
        more complex text, use the setText() that takes a
        GlyphArrangement instead.
    */
    void setText (const String& newText, const Font& fontToUse);

    /** Returns the text arrangement that was set with setText(). */
    const GlyphArrangement& getText() const throw()         { return text; }

    /** Sets the colour of the text. */
    void setColour (const Colour& newColour);

    /** Returns the current text colour. */
    const Colour& getColour() const throw()                 { return colour; }

    /** @internal */
    void draw (Graphics& g, const AffineTransform& transform) const;
    /** @internal */
    void getBounds (float& x, float& y, float& width, float& height) const;
    /** @internal */
    bool hitTest (float x, float y) const;
    /** @internal */
    Drawable* createCopy() const;

    juce_UseDebuggingNewOperator

private:
    GlyphArrangement text;
    Colour colour;

    DrawableText (const DrawableText&);
    const DrawableText& operator= (const DrawableText&);
};

#endif   // __JUCE_DRAWABLETEXT_JUCEHEADER__
/********* End of inlined file: juce_DrawableText.h *********/

#endif
#ifndef __JUCE_COMPONENTDELETIONWATCHER_JUCEHEADER__

#endif
#ifndef __JUCE_COMPONENTLISTENER_JUCEHEADER__

#endif
#ifndef __JUCE_DESKTOP_JUCEHEADER__

#endif
#ifndef __JUCE_COMPONENT_JUCEHEADER__

#endif
#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__

/********* Start of inlined file: juce_ArrowButton.h *********/
#ifndef __JUCE_ARROWBUTTON_JUCEHEADER__
#define __JUCE_ARROWBUTTON_JUCEHEADER__

/********* Start of inlined file: juce_DropShadowEffect.h *********/
#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__
#define __JUCE_DROPSHADOWEFFECT_JUCEHEADER__

/**
    An effect filter that adds a drop-shadow behind the image's content.

    (This will only work on images/components that aren't opaque, of course).

    When added to a component, this effect will draw a soft-edged
    shadow based on what gets drawn inside it. The shadow will also
    be applied to the component's children.

    For speed, this doesn't use a proper gaussian blur, but cheats by
    using a simple bilinear filter. If you need a really high-quality
    shadow, check out ImageConvolutionKernel::createGaussianBlur()

    @see Component::setComponentEffect
*/
class JUCE_API  DropShadowEffect  : public ImageEffectFilter
{
public:

    /** Creates a default drop-shadow effect.

        To customise the shadow's appearance, use the setShadowProperties()
        method.
    */
    DropShadowEffect();

    /** Destructor. */
    ~DropShadowEffect();

    /** Sets up parameters affecting the shadow's appearance.

        @param newRadius        the (approximate) radius of the blur used
        @param newOpacity       the opacity with which the shadow is rendered
        @param newShadowOffsetX allows the shadow to be shifted in relation to the
                                component's contents
        @param newShadowOffsetY allows the shadow to be shifted in relation to the
                                component's contents
    */
    void setShadowProperties (const float newRadius,
                              const float newOpacity,
                              const int newShadowOffsetX,
                              const int newShadowOffsetY);

    /** @internal */
    void applyEffect (Image& sourceImage, Graphics& destContext);

    juce_UseDebuggingNewOperator

private:
    int offsetX, offsetY;
    float radius, opacity;
};

#endif   // __JUCE_DROPSHADOWEFFECT_JUCEHEADER__
/********* End of inlined file: juce_DropShadowEffect.h *********/

/**
    A button with an arrow in it.

    @see Button
*/
class JUCE_API  ArrowButton  : public Button
{
public:

    /** Creates an ArrowButton.

        @param buttonName       the name to give the button
        @param arrowDirection   the direction the arrow should point in, where 0.0 is
                                pointing right, 0.25 is down, 0.5 is left, 0.75 is up
        @param arrowColour      the colour to use for the arrow
    */
    ArrowButton (const String& buttonName,
                 float arrowDirection,
                 const Colour& arrowColour);

    /** Destructor. */
    ~ArrowButton();

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paintButton (Graphics& g,
                      bool isMouseOverButton,
                      bool isButtonDown);

    /** @internal */
    void buttonStateChanged();

private:

    Colour colour;
    DropShadowEffect shadow;
    Path path;
    int offset;

    ArrowButton (const ArrowButton&);
    const ArrowButton& operator= (const ArrowButton&);
};

#endif   // __JUCE_ARROWBUTTON_JUCEHEADER__
/********* End of inlined file: juce_ArrowButton.h *********/

#endif
#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__

/********* Start of inlined file: juce_DrawableButton.h *********/
#ifndef __JUCE_DRAWABLEBUTTON_JUCEHEADER__
#define __JUCE_DRAWABLEBUTTON_JUCEHEADER__

/**
    A button that displays a Drawable.

    Up to three Drawable objects can be given to this button, to represent the
    'normal', 'over' and 'down' states.

    @see Button
*/
class JUCE_API  DrawableButton  : public Button
{
public:

    enum ButtonStyle
    {
        ImageFitted,                /**< The button will just display the images, but will resize and centre them to fit inside it. */
        ImageRaw,                   /**< The button will just display the images in their normal size and position.
                                         This leaves it up to the caller to make sure the images are the correct size and position for the button. */
        ImageAboveTextLabel,        /**< Draws the button as a text label across the bottom with the image resized and scaled to fit above it. */
        ImageOnButtonBackground     /**< Draws the button as a standard rounded-rectangle button with the image on top. */
    };

    /** Creates a DrawableButton.

        After creating one of these, use setImages() to specify the drawables to use.

        @param buttonName           the name to give the component
        @param buttonStyle          the layout to use

        @see ButtonStyle, setButtonStyle, setImages
    */
    DrawableButton (const String& buttonName,
                    const ButtonStyle buttonStyle);

    /** Destructor. */
    ~DrawableButton();

    /** Sets up the images to draw for the various button states.

        The button will keep its own internal copies of these drawables.

        @param normalImage      the thing to draw for the button's 'normal' state. An internal copy
                                will be made of the object passed-in if it is non-zero.
        @param overImage        the thing to draw for the button's 'over' state - if this is
                                zero, the button's normal image will be used when the mouse is
                                over it. An internal copy will be made of the object passed-in
                                if it is non-zero.
        @param downImage        the thing to draw for the button's 'down' state - if this is
                                zero, the 'over' image will be used instead (or the normal image
                                as a last resort). An internal copy will be made of the object
                                passed-in if it is non-zero.
        @param disabledImage    an image to draw when the button is disabled. If this is zero,
                                the normal image will be drawn with a reduced opacity instead.
                                An internal copy will be made of the object passed-in if it is
                                non-zero.
        @param normalImageOn    same as the normalImage, but this is used when the button's toggle
                                state is 'on'. If this is 0, the normal image is used instead
        @param overImageOn      same as the overImage, but this is used when the button's toggle
                                state is 'on'. If this is 0, the normalImageOn is drawn instead
        @param downImageOn      same as the downImage, but this is used when the button's toggle
                                state is 'on'. If this is 0, the overImageOn is drawn instead
        @param disabledImageOn  same as the disabledImage, but this is used when the button's toggle
                                state is 'on'. If this is 0, the normal image will be drawn instead
                                with a reduced opacity
    */
    void setImages (const Drawable* normalImage,
                    const Drawable* overImage = 0,
                    const Drawable* downImage = 0,
                    const Drawable* disabledImage = 0,
                    const Drawable* normalImageOn = 0,
                    const Drawable* overImageOn = 0,
                    const Drawable* downImageOn = 0,
                    const Drawable* disabledImageOn = 0);

    /** Changes the button's style.

        @see ButtonStyle
    */
    void setButtonStyle (const ButtonStyle newStyle);

    /** Changes the button's background colours.

        The toggledOffColour is the colour to use when the button's toggle state
        is off, and toggledOnColour when it's on.

        For an ImageOnly or ImageAboveTextLabel style, the background colour is
        used to fill the background of the component.

        For an ImageOnButtonBackground style, the colour is used to draw the
        button's lozenge shape and exactly how the colour's used will depend
        on the LookAndFeel.
    */
    void setBackgroundColours (const Colour& toggledOffColour,
                               const Colour& toggledOnColour);

    /** Returns the current background colour being used.

        @see setBackgroundColour
    */
    const Colour& getBackgroundColour() const throw();

    /** Gives the button an optional amount of space around the edge of the drawable.

        This will only apply to ImageFitted or ImageRaw styles, it won't affect the
        ones on a button background. If the button is too small for the given gap, a
        smaller gap will be used.

        By default there's a gap of about 3 pixels.
    */
    void setEdgeIndent (const int numPixelsIndent);

    /** Returns the image that the button is currently displaying. */
    const Drawable* getCurrentImage() const throw();
    const Drawable* getNormalImage() const throw();
    const Drawable* getOverImage() const throw();
    const Drawable* getDownImage() const throw();

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paintButton (Graphics& g,
                      bool isMouseOverButton,
                      bool isButtonDown);

private:

    ButtonStyle style;
    Drawable* normalImage;
    Drawable* overImage;
    Drawable* downImage;
    Drawable* disabledImage;
    Drawable* normalImageOn;
    Drawable* overImageOn;
    Drawable* downImageOn;
    Drawable* disabledImageOn;
    Colour backgroundOff, backgroundOn;
    int edgeIndent;

    void deleteImages();
    DrawableButton (const DrawableButton&);
    const DrawableButton& operator= (const DrawableButton&);
};

#endif   // __JUCE_DRAWABLEBUTTON_JUCEHEADER__
/********* End of inlined file: juce_DrawableButton.h *********/

#endif
#ifndef __JUCE_HYPERLINKBUTTON_JUCEHEADER__

/********* Start of inlined file: juce_HyperlinkButton.h *********/
#ifndef __JUCE_HYPERLINKBUTTON_JUCEHEADER__
#define __JUCE_HYPERLINKBUTTON_JUCEHEADER__

/**
    A button showing an underlined weblink, that will launch the link
    when it's clicked.

    @see Button
*/
class JUCE_API  HyperlinkButton  : public Button
{
public:

    /** Creates a HyperlinkButton.

        @param linkText     the text that will be displayed in the button - this is
                            also set as the Component's name, but the text can be
                            changed later with the Button::getButtonText() method
        @param linkURL      the URL to launch when the user clicks the button
    */
    HyperlinkButton (const String& linkText,
                     const URL& linkURL);

    /** Destructor. */
    ~HyperlinkButton();

    /** Changes the font to use for the text.

        If resizeToMatchComponentHeight is true, the font's height will be adjusted
        to match the size of the component.
    */
    void setFont (const Font& newFont,
                  const bool resizeToMatchComponentHeight,
                  const Justification& justificationType = Justification::horizontallyCentred);

    /** A set of colour IDs to use to change the colour of various aspects of the link.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        textColourId             = 0x1001f00, /**< The colour to use for the URL text. */
    };

    /** Changes the URL that the button will trigger. */
    void setURL (const URL& newURL) throw();

    /** Returns the URL that the button will trigger. */
    const URL& getURL() const throw()                           { return url; }

    /** Resizes the button horizontally to fit snugly around the text.

        This won't affect the button's height.
    */
    void changeWidthToFitText();

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void clicked();
    /** @internal */
    void colourChanged();
    /** @internal */
    void paintButton (Graphics& g,
                      bool isMouseOverButton,
                      bool isButtonDown);

private:
    URL url;
    Font font;
    bool resizeFont;
    Justification justification;

    const Font getFontToUse() const;

    HyperlinkButton (const HyperlinkButton&);
    const HyperlinkButton& operator= (const HyperlinkButton&);
};

#endif   // __JUCE_HYPERLINKBUTTON_JUCEHEADER__
/********* End of inlined file: juce_HyperlinkButton.h *********/

#endif
#ifndef __JUCE_IMAGEBUTTON_JUCEHEADER__

/********* Start of inlined file: juce_ImageButton.h *********/
#ifndef __JUCE_IMAGEBUTTON_JUCEHEADER__
#define __JUCE_IMAGEBUTTON_JUCEHEADER__

/**
    As the title suggests, this is a button containing an image.

    The colour and transparency of the image can be set to vary when the
    button state changes.

    @see Button, ShapeButton, TextButton
*/
class JUCE_API  ImageButton  : public Button
{
public:

    /** Creates an ImageButton.

        Use setImage() to specify the image to use. The colours and opacities that
        are specified here can be changed later using setDrawingOptions().

        @param name                 the name to give the component
    */
    ImageButton (const String& name);

    /** Destructor. */
    ~ImageButton();

    /** Sets up the images to draw in various states.

        Important! Bear in mind that if you pass the same image in for more than one of
        these parameters, this button will delete it (or release from the ImageCache)
        multiple times!

        @param resizeButtonNowToFitThisImage        if true, the button will be immediately
                                                    resized to the same dimensions as the normal image
        @param rescaleImagesWhenButtonSizeChanges   if true, the image will be rescaled to fit the
                                                    button when the button's size changes
        @param preserveImageProportions             if true then any rescaling of the image to fit
                                                    the button will keep the image's x and y proportions
                                                    correct - i.e. it won't distort its shape, although
                                                    this might create gaps around the edges
        @param normalImage                          the image to use when the button is in its normal state. The
                                                    image passed in will be deleted (or released if it
                                                    was created by the ImageCache class) when the
                                                    button no longer needs it.
        @param imageOpacityWhenNormal               the opacity to use when drawing the normal image.
        @param overlayColourWhenNormal              an overlay colour to use to fill the alpha channel of the
                                                    normal image - if this colour is transparent, no overlay
                                                    will be drawn. The overlay will be drawn over the top of the
                                                    image, so you can basically add a solid or semi-transparent
                                                    colour to the image to brighten or darken it
        @param overImage                            the image to use when the mouse is over the button. If
                                                    you want to use the same image as was set in the normalImage
                                                    parameter, this value can be 0. As for normalImage, it
                                                    will be deleted or released by the button when no longer
                                                    needed
        @param imageOpacityWhenOver                 the opacity to use when drawing the image when the mouse
                                                    is over the button
        @param overlayColourWhenOver                an overlay colour to use to fill the alpha channel of the
                                                    image when the mouse is over - if this colour is transparent,
                                                    no overlay will be drawn
        @param downImage                            an image to use when the button is pressed down. If set
                                                    to zero, the 'over' image will be drawn instead (or the
                                                    normal image if there isn't an 'over' image either). This
                                                    image will be deleted or released by the button when no
                                                    longer needed
        @param imageOpacityWhenDown                 the opacity to use when drawing the image when the button
                                                    is pressed
        @param overlayColourWhenDown                an overlay colour to use to fill the alpha channel of the
                                                    image when the button is pressed down - if this colour is
                                                    transparent, no overlay will be drawn
        @param hitTestAlphaThreshold                if set to zero, the mouse is considered to be over the button
                                                    whenever it's inside the button's bounding rectangle. If
                                                    set to values higher than 0, the mouse will only be
                                                    considered to be over the image when the value of the
                                                    image's alpha channel at that position is greater than
                                                    this level.
    */
    void setImages (const bool resizeButtonNowToFitThisImage,
                    const bool rescaleImagesWhenButtonSizeChanges,
                    const bool preserveImageProportions,
                    Image* const normalImage,
                    const float imageOpacityWhenNormal,
                    const Colour& overlayColourWhenNormal,
                    Image* const overImage,
                    const float imageOpacityWhenOver,
                    const Colour& overlayColourWhenOver,
                    Image* const downImage,
                    const float imageOpacityWhenDown,
                    const Colour& overlayColourWhenDown,
                    const float hitTestAlphaThreshold = 0.0f);

    /** Returns the currently set 'normal' image. */
    Image* getNormalImage() const throw();

    /** Returns the image that's drawn when the mouse is over the button.

        If an 'over' image has been set, this will return it; otherwise it'll
        just return the normal image.
    */
    Image* getOverImage() const throw();

    /** Returns the image that's drawn when the button is held down.

        If a 'down' image has been set, this will return it; otherwise it'll
        return the 'over' image or normal image, depending on what's available.
    */
    Image* getDownImage() const throw();

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    bool hitTest (int x, int y);
    /** @internal */
    void paintButton (Graphics& g,
                      bool isMouseOverButton,
                      bool isButtonDown);

private:

    bool scaleImageToFit, preserveProportions;
    unsigned char alphaThreshold;
    int imageX, imageY, imageW, imageH;
    Image* normalImage;
    Image* overImage;
    Image* downImage;
    float normalOpacity, overOpacity, downOpacity;
    Colour normalOverlay, overOverlay, downOverlay;

    Image* getCurrentImage() const;
    void deleteImages();

    ImageButton (const ImageButton&);
    const ImageButton& operator= (const ImageButton&);
};

#endif   // __JUCE_IMAGEBUTTON_JUCEHEADER__
/********* End of inlined file: juce_ImageButton.h *********/

#endif
#ifndef __JUCE_BUTTON_JUCEHEADER__

#endif
#ifndef __JUCE_SHAPEBUTTON_JUCEHEADER__

/********* Start of inlined file: juce_ShapeButton.h *********/
#ifndef __JUCE_SHAPEBUTTON_JUCEHEADER__
#define __JUCE_SHAPEBUTTON_JUCEHEADER__

/**
    A button that contains a filled shape.

    @see Button, ImageButton, TextButton, ArrowButton
*/
class JUCE_API  ShapeButton  : public Button
{
public:

    /** Creates a ShapeButton.

        @param name             a name to give the component - see Component::setName()
        @param normalColour     the colour to fill the shape with when the mouse isn't over
        @param overColour       the colour to use when the mouse is over the shape
        @param downColour       the colour to use when the button is in the pressed-down state
    */
    ShapeButton (const String& name,
                 const Colour& normalColour,
                 const Colour& overColour,
                 const Colour& downColour);

    /** Destructor. */
    ~ShapeButton();

    /** Sets the shape to use.

        @param newShape                 the shape to use
        @param resizeNowToFitThisShape  if true, the button will be resized to fit the shape's bounds
        @param maintainShapeProportions if true, the shape's proportions will be kept fixed when
                                        the button is resized
        @param hasDropShadow            if true, the button will be given a drop-shadow effect
    */
    void setShape (const Path& newShape,
                   const bool resizeNowToFitThisShape,
                   const bool maintainShapeProportions,
                   const bool hasDropShadow);

    /** Set the colours to use for drawing the shape.

        @param normalColour     the colour to fill the shape with when the mouse isn't over
        @param overColour       the colour to use when the mouse is over the shape
        @param downColour       the colour to use when the button is in the pressed-down state
    */
    void setColours (const Colour& normalColour,
                     const Colour& overColour,
                     const Colour& downColour);

    /** Sets up an outline to draw around the shape.

        @param outlineColour        the colour to use
        @param outlineStrokeWidth   the thickness of line to draw
    */
    void setOutline (const Colour& outlineColour,
                     const float outlineStrokeWidth);

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paintButton (Graphics& g,
                      bool isMouseOverButton,
                      bool isButtonDown);

private:
    Colour normalColour, overColour, downColour, outlineColour;
    DropShadowEffect shadow;
    Path shape;
    bool maintainShapeProportions;
    float outlineWidth;

    ShapeButton (const ShapeButton&);
    const ShapeButton& operator= (const ShapeButton&);
};

#endif   // __JUCE_SHAPEBUTTON_JUCEHEADER__
/********* End of inlined file: juce_ShapeButton.h *********/

#endif
#ifndef __JUCE_TEXTBUTTON_JUCEHEADER__

#endif
#ifndef __JUCE_TOGGLEBUTTON_JUCEHEADER__

/********* Start of inlined file: juce_ToggleButton.h *********/
#ifndef __JUCE_TOGGLEBUTTON_JUCEHEADER__
#define __JUCE_TOGGLEBUTTON_JUCEHEADER__

/**
    A button that can be toggled on/off.

    All buttons can be toggle buttons, but this lets you create one of the
    standard ones which has a tick-box and a text label next to it.

    @see Button, DrawableButton, TextButton
*/
class JUCE_API  ToggleButton  : public Button
{
public:

    /** Creates a ToggleButton.

        @param buttonText   the text to put in the button (the component's name is also
                            initially set to this string, but these can be changed later
                            using the setName() and setButtonText() methods)
    */
    ToggleButton (const String& buttonText);

    /** Destructor. */
    ~ToggleButton();

    /** Resizes the button to fit neatly around its current text.

        The button's height won't be affected, only its width.
    */
    void changeWidthToFitText();

    /** A set of colour IDs to use to change the colour of various aspects of the button.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        textColourId                    = 0x1006501   /**< The colour to use for the button's text. */
    };

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paintButton (Graphics& g,
                      bool isMouseOverButton,
                      bool isButtonDown);

    /** @internal */
    void colourChanged();

private:

    ToggleButton (const ToggleButton&);
    const ToggleButton& operator= (const ToggleButton&);
};

#endif   // __JUCE_TOGGLEBUTTON_JUCEHEADER__
/********* End of inlined file: juce_ToggleButton.h *********/

#endif
#ifndef __JUCE_TOOLBARBUTTON_JUCEHEADER__

/********* Start of inlined file: juce_ToolbarButton.h *********/
#ifndef __JUCE_TOOLBARBUTTON_JUCEHEADER__
#define __JUCE_TOOLBARBUTTON_JUCEHEADER__

/********* Start of inlined file: juce_ToolbarItemComponent.h *********/
#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__
#define __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_Toolbar.h *********/
#ifndef __JUCE_TOOLBAR_JUCEHEADER__
#define __JUCE_TOOLBAR_JUCEHEADER__

/********* Start of inlined file: juce_DragAndDropContainer.h *********/
#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__
#define __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__

/********* Start of inlined file: juce_DragAndDropTarget.h *********/
#ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__
#define __JUCE_DRAGANDDROPTARGET_JUCEHEADER__

/**
    Components derived from this class can have things dropped onto them by a DragAndDropContainer.

    To create a component that can receive things drag-and-dropped by a DragAndDropContainer,
    derive your component from this class, and make sure that it is somewhere inside a
    DragAndDropContainer component.

    Note: If all that you need to do is to respond to files being drag-and-dropped from
    the operating system onto your component, you don't need any of these classes: instead
    see the FileDragAndDropTarget class.

    @see DragAndDropContainer, FileDragAndDropTarget
*/
class JUCE_API  DragAndDropTarget
{
public:
    /** Destructor. */
    virtual ~DragAndDropTarget()  {}

    /** Callback to check whether this target is interested in the type of object being
        dragged.

        @param sourceDescription    the description string passed into DragAndDropContainer::startDragging()
        @param sourceComponent      the component that was passed into DragAndDropContainer::startDragging()
        @returns                    true if this component wants to receive the other callbacks regarging this
                                    type of object; if it returns false, no other callbacks will be made.
    */
    virtual bool isInterestedInDragSource (const String& sourceDescription,
                                           Component* sourceComponent) = 0;

    /** Callback to indicate that something is being dragged over this component.

        This gets called when the user moves the mouse into this component while dragging
        something.

        Use this callback as a trigger to make your component repaint itself to give the
        user feedback about whether the item can be dropped here or not.

        @param sourceDescription    the description string passed into DragAndDropContainer::startDragging()
        @param sourceComponent      the component that was passed into DragAndDropContainer::startDragging()
        @param x                    the mouse x position, relative to this component
        @param y                    the mouse y position, relative to this component
        @see itemDragExit
    */
    virtual void itemDragEnter (const String& sourceDescription,
                                Component* sourceComponent,
                                int x,
                                int y);

    /** Callback to indicate that the user is dragging something over this component.

        This gets called when the user moves the mouse over this component while dragging
        something. Normally overriding itemDragEnter() and itemDragExit() are enough, but
        this lets you know what happens in-between.

        @param sourceDescription    the description string passed into DragAndDropContainer::startDragging()
        @param sourceComponent      the component that was passed into DragAndDropContainer::startDragging()
        @param x                    the mouse x position, relative to this component
        @param y                    the mouse y position, relative to this component
    */
    virtual void itemDragMove (const String& sourceDescription,
                               Component* sourceComponent,
                               int x,
                               int y);

    /** Callback to indicate that something has been dragged off the edge of this component.

        This gets called when the user moves the mouse out of this component while dragging
        something.

        If you've used itemDragEnter() to repaint your component and give feedback, use this
        as a signal to repaint it in its normal state.

        @param sourceDescription    the description string passed into DragAndDropContainer::startDragging()
        @param sourceComponent      the component that was passed into DragAndDropContainer::startDragging()
        @see itemDragEnter
    */
    virtual void itemDragExit (const String& sourceDescription,
                               Component* sourceComponent);

    /** Callback to indicate that the user has dropped something onto this component.

        When the user drops an item this get called, and you can use the description to
        work out whether your object wants to deal with it or not.

        Note that after this is called, the itemDragExit method may not be called, so you should
        clean up in here if there's anything you need to do when the drag finishes.

        @param sourceDescription    the description string passed into DragAndDropContainer::startDragging()
        @param sourceComponent      the component that was passed into DragAndDropContainer::startDragging()
        @param x                    the mouse x position, relative to this component
        @param y                    the mouse y position, relative to this component
    */
    virtual void itemDropped (const String& sourceDescription,
                              Component* sourceComponent,
                              int x,
                              int y) = 0;

    /** Overriding this allows the target to tell the drag container whether to
        draw the drag image while the cursor is over it.

        By default it returns true, but if you return false, then the normal drag
        image will not be shown when the cursor is over this target.
    */
    virtual bool shouldDrawDragImageWhenOver();
};

#endif   // __JUCE_DRAGANDDROPTARGET_JUCEHEADER__
/********* End of inlined file: juce_DragAndDropTarget.h *********/

/**
    Enables drag-and-drop behaviour for a component and all its sub-components.

    For a component to be able to make or receive drag-and-drop events, one of its parent
    components must derive from this class. It's probably best for the top-level
    component to implement it.

    Then to start a drag operation, any sub-component can just call the startDragging()
    method, and this object will take over, tracking the mouse and sending appropriate
    callbacks to any child components derived from DragAndDropTarget which the mouse
    moves over.

    Note: If all that you need to do is to respond to files being drag-and-dropped from
    the operating system onto your component, you don't need any of these classes: you can do this
    simply by overriding Component::filesDropped().

    @see DragAndDropTarget
*/
class JUCE_API  DragAndDropContainer
{
public:

    /** Creates a DragAndDropContainer.

        The object that derives from this class must also be a Component.
    */
    DragAndDropContainer();

    /** Destructor. */
    virtual ~DragAndDropContainer();

    /** Begins a drag-and-drop operation.

        This starts a drag-and-drop operation - call it when the user drags the
        mouse in your drag-source component, and this object will track mouse
        movements until the user lets go of the mouse button, and will send
        appropriate messages to DragAndDropTarget objects that the mouse moves
        over.

        findParentDragContainerFor() is a handy method to call to find the
        drag container to use for a component.

        @param sourceDescription    a string to use as the description of the thing being
                                    dragged - this will be passed to the objects that might be
                                    dropped-onto so they can decide if they want to handle it or
                                    not
        @param sourceComponent      the component that is being dragged
        @param dragImage            the image to drag around underneath the mouse. If this is
                                    zero, a snapshot of the sourceComponent will be used instead. An
                                    image passed-in will be deleted by this object when no longer
                                    needed.
        @param allowDraggingToOtherJuceWindows   if true, the dragged component will appear as a desktop
                                    window, and can be dragged to DragAndDropTargets that are the
                                    children of components other than this one.
    */
    void startDragging (const String& sourceDescription,
                        Component* sourceComponent,
                        Image* dragImage = 0,
                        const bool allowDraggingToOtherJuceWindows = false);

    /** Returns true if something is currently being dragged. */
    bool isDragAndDropActive() const;

    /** Returns the description of the thing that's currently being dragged.

        If nothing's being dragged, this will return an empty string, otherwise it's the
        string that was passed into startDragging().

        @see startDragging
    */
    const String getCurrentDragDescription() const;

    /** Utility to find the DragAndDropContainer for a given Component.

        This will search up this component's parent hierarchy looking for the first
        parent component which is a DragAndDropContainer.

        It's useful when a component wants to call startDragging but doesn't know
        the DragAndDropContainer it should to use.

        Obviously this may return 0 if it doesn't find a suitable component.
    */
    static DragAndDropContainer* findParentDragContainerFor (Component* childComponent);

    /** This performs a synchronous drag-and-drop of a set of files to some external
        application.

        You can call this function in response to a mouseDrag callback, and it will
        block, running its own internal message loop and tracking the mouse, while it
        uses a native operating system drag-and-drop operation to move or copy some
        files to another application.

        @param files            a list of filenames to drag
        @param canMoveFiles     if true, the app that receives the files is allowed to move the files to a new location
                                (if this is appropriate). If false, the receiver is expected to make a copy of them.
        @returns        true if the files were successfully dropped somewhere, or false if it
                        was interrupted
        @see performExternalDragDropOfText
    */
    static bool performExternalDragDropOfFiles (const StringArray& files, const bool canMoveFiles);

    /** This performs a synchronous drag-and-drop of a block of text to some external
        application.

        You can call this function in response to a mouseDrag callback, and it will
        block, running its own internal message loop and tracking the mouse, while it
        uses a native operating system drag-and-drop operation to move or copy some
        text to another application.

        @param text     the text to copy
        @returns        true if the text was successfully dropped somewhere, or false if it
                        was interrupted
        @see performExternalDragDropOfFiles
    */
    static bool performExternalDragDropOfText (const String& text);

    juce_UseDebuggingNewOperator

protected:
    /** Override this if you want to be able to perform an external drag a set of files
        when the user drags outside of this container component.

        This method will be called when a drag operation moves outside the Juce-based window,
        and if you want it to then perform a file drag-and-drop, add the filenames you want
        to the array passed in, and return true.

        @param dragSourceDescription        the description passed into the startDrag() call when the drag began
        @param dragSourceComponent          the component passed into the startDrag() call when the drag began
        @param files                        on return, the filenames you want to drag
        @param canMoveFiles                 on return, true if it's ok for the receiver to move the files; false if
                                            it must make a copy of them (see the performExternalDragDropOfFiles()
                                            method)
        @see performExternalDragDropOfFiles
    */
    virtual bool shouldDropFilesWhenDraggedExternally (const String& dragSourceDescription,
                                                       Component* dragSourceComponent,
                                                       StringArray& files,
                                                       bool& canMoveFiles);

private:
    friend class DragImageComponent;
    Component* dragImageComponent;
    String currentDragDesc;
};

#endif   // __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__
/********* End of inlined file: juce_DragAndDropContainer.h *********/

/********* Start of inlined file: juce_ComponentAnimator.h *********/
#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__
#define __JUCE_COMPONENTANIMATOR_JUCEHEADER__

/**
    Animates a set of components, moving it to a new position.

    To use this, create a ComponentAnimator, and use its animateComponent() method
    to tell it to move components to destination positions. Any number of
    components can be animated by one ComponentAnimator object (if you've got a
    lot of components to move, it's much more efficient to share a single animator
    than to have many animators running at once).

    You'll need to make sure the animator object isn't deleted before it finishes
    moving the components.

    The class is a ChangeBroadcaster and sends a notification when any components
    start or finish being animated.
*/
class JUCE_API  ComponentAnimator  : public ChangeBroadcaster,
                                     private Timer
{
public:

    /** Creates a ComponentAnimator. */
    ComponentAnimator();

    /** Destructor. */
    ~ComponentAnimator();

    /** Starts a component moving from its current position to a specified position.

        If the component is already in the middle of an animation, that will be abandoned,
        and a new animation will begin, moving the component from its current location.

        The start and end speed parameters let you apply some acceleration to the component's
        movement.

        @param component            the component to move
        @param finalPosition        the destination position and size to move it to
        @param millisecondsToSpendMoving    how long, in milliseconds, it should take
                                    to arrive at its destination
        @param startSpeed           a value to indicate the relative start speed of the
                                    animation. If this is 0, the component will start
                                    by accelerating from rest; higher values mean that it
                                    will have an initial speed greater than zero. If the
                                    value if greater than 1, it will decelerate towards the
                                    middle of its journey. To move the component at a constant
                                    rate for its entire animation, set both the start and
                                    end speeds to 1.0
        @param endSpeed             a relative speed at which the component should be moving
                                    when the animation finishes. If this is 0, the component
                                    will decelerate to a standstill at its final position; higher
                                    values mean the component will still be moving when it stops.
                                    To move the component at a constant rate for its entire
                                    animation, set both the start and end speeds to 1.0
    */
    void animateComponent (Component* const component,
                           const Rectangle& finalPosition,
                           const int millisecondsToSpendMoving,
                           const double startSpeed = 1.0,
                           const double endSpeed = 1.0);

    /** Stops a component if it's currently being animated.

        If moveComponentToItsFinalPosition is true, then the component will
        be immediately moved to its destination position and size. If false, it will be
        left in whatever location it currently occupies.
    */
    void cancelAnimation (Component* const component,
                          const bool moveComponentToItsFinalPosition);

    /** Clears all of the active animations.

        If moveComponentsToTheirFinalPositions is true, all the components will
        be immediately set to their final positions. If false, they will be
        left in whatever locations they currently occupy.
    */
    void cancelAllAnimations (const bool moveComponentsToTheirFinalPositions);

    /** Returns the destination position for a component.

        If the component is being animated, this will return the target position that
        was specified when animateComponent() was called.

        If the specified component isn't currently being animated, this method will just
        return its current position.
    */
    const Rectangle getComponentDestination (Component* const component);

    /** Returns true if the specified component is currently being animated.
    */
    bool isAnimating (Component* component) const;

    juce_UseDebuggingNewOperator

private:
    VoidArray tasks;
    uint32 lastTime;

    void* findTaskFor (Component* const component) const;
    void timerCallback();
};

#endif   // __JUCE_COMPONENTANIMATOR_JUCEHEADER__
/********* End of inlined file: juce_ComponentAnimator.h *********/

class ToolbarItemComponent;
class ToolbarItemFactory;
class MissingItemsComponent;

/**
    A toolbar component.

    A toolbar contains a horizontal or vertical strip of ToolbarItemComponents,
    and looks after their order and layout.

    Items (icon buttons or other custom components) are added to a toolbar using a
    ToolbarItemFactory - each type of item is given a unique ID number, and a
    toolbar might contain more than one instance of a particular item type.

    Toolbars can be interactively customised, allowing the user to drag the items
    around, and to drag items onto or off the toolbar, using the ToolbarItemPalette
    component as a source of new items.

    @see ToolbarItemFactory, ToolbarItemComponent, ToolbarItemPalette
*/
class JUCE_API  Toolbar   : public Component,
                            public DragAndDropContainer,
                            public DragAndDropTarget,
                            private ButtonListener
{
public:

    /** Creates an empty toolbar component.

        To add some icons or other components to your toolbar, you'll need to
        create a ToolbarItemFactory class that can create a suitable set of
        ToolbarItemComponents.

        @see ToolbarItemFactory, ToolbarItemComponents
    */
    Toolbar();

    /** Destructor.

        Any items on the bar will be deleted when the toolbar is deleted.
    */
    ~Toolbar();

    /** Changes the bar's orientation.
        @see isVertical
    */
    void setVertical (const bool shouldBeVertical);

    /** Returns true if the bar is set to be vertical, or false if it's horizontal.

        You can change the bar's orientation with setVertical().
    */
    bool isVertical() const throw()                  { return vertical; }

    /** Returns the depth of the bar.

        If the bar is horizontal, this will return its height; if it's vertical, it
        will return its width.

        @see getLength
    */
    int getThickness() const throw();

    /** Returns the length of the bar.

        If the bar is horizontal, this will return its width; if it's vertical, it
        will return its height.

        @see getThickness
    */
    int getLength() const throw();

    /** Deletes all items from the bar.
    */
    void clear();

    /** Adds an item to the toolbar.

        The factory's ToolbarItemFactory::createItem() will be called by this method
        to create the component that will actually be added to the bar.

        The new item will be inserted at the specified index (if the index is -1, it
        will be added to the right-hand or bottom end of the bar).

        Once added, the component will be automatically deleted by this object when it
        is no longer needed.

        @see ToolbarItemFactory
    */
    void addItem (ToolbarItemFactory& factory,
                  const int itemId,
                  const int insertIndex = -1);

    /** Deletes one of the items from the bar.
    */
    void removeToolbarItem (const int itemIndex);

    /** Returns the number of items currently on the toolbar.

        @see getItemId, getItemComponent
    */
    int getNumItems() const throw();

    /** Returns the ID of the item with the given index.

        If the index is less than zero or greater than the number of items,
        this will return 0.

        @see getNumItems
    */
    int getItemId (const int itemIndex) const throw();

    /** Returns the component being used for the item with the given index.

        If the index is less than zero or greater than the number of items,
        this will return 0.

        @see getNumItems
    */
    ToolbarItemComponent* getItemComponent (const int itemIndex) const throw();

    /** Clears this toolbar and adds to it the default set of items that the specified
        factory creates.

        @see ToolbarItemFactory::getDefaultItemSet
    */
    void addDefaultItems (ToolbarItemFactory& factoryToUse);

    /** Options for the way items should be displayed.
        @see setStyle, getStyle
    */
    enum ToolbarItemStyle
    {
        iconsOnly,       /**< Means that the toolbar should just contain icons. */
        iconsWithText,   /**< Means that the toolbar should have text labels under each icon. */
        textOnly         /**< Means that the toolbar only display text labels for each item. */
    };

    /** Returns the toolbar's current style.
        @see ToolbarItemStyle, setStyle
    */
    ToolbarItemStyle getStyle() const throw()                { return toolbarStyle; }

    /** Changes the toolbar's current style.
        @see ToolbarItemStyle, getStyle, ToolbarItemComponent::setStyle
    */
    void setStyle (const ToolbarItemStyle& newStyle);

    /** Flags used by the showCustomisationDialog() method. */
    enum CustomisationFlags
    {
        allowIconsOnlyChoice            = 1,    /**< If this flag is specified, the customisation dialog can
                                                     show the "icons only" option on its choice of toolbar styles. */
        allowIconsWithTextChoice        = 2,    /**< If this flag is specified, the customisation dialog can
                                                     show the "icons with text" option on its choice of toolbar styles. */
        allowTextOnlyChoice             = 4,    /**< If this flag is specified, the customisation dialog can
                                                     show the "text only" option on its choice of toolbar styles. */
        showResetToDefaultsButton       = 8,    /**< If this flag is specified, the customisation dialog can
                                                     show a button to reset the toolbar to its default set of items. */

        allCustomisationOptionsEnabled = (allowIconsOnlyChoice | allowIconsWithTextChoice | allowTextOnlyChoice | showResetToDefaultsButton)
    };

    /** Pops up a modal dialog box that allows this toolbar to be customised by the user.

        The dialog contains a ToolbarItemPalette and various controls for editing other
        aspects of the toolbar. This method will block and run the dialog box modally,
        returning when the user closes it.

        The factory is used to determine the set of items that will be shown on the
        palette.

        The optionFlags parameter is a bitwise-or of values from the CustomisationFlags
        enum.

        @see ToolbarItemPalette
    */
    void showCustomisationDialog (ToolbarItemFactory& factory,
                                  const int optionFlags = allCustomisationOptionsEnabled);

    /** Turns on or off the toolbar's editing mode, in which its items can be
        rearranged by the user.

        (In most cases it's easier just to use showCustomisationDialog() instead of
        trying to enable editing directly).

        @see ToolbarItemPalette
    */
    void setEditingActive (const bool editingEnabled);

    /** A set of colour IDs to use to change the colour of various aspects of the toolbar.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId          = 0x1003200,  /**< A colour to use to fill the toolbar's background. For
                                                       more control over this, override LookAndFeel::paintToolbarBackground(). */
        separatorColourId           = 0x1003210,  /**< A colour to use to draw the separator lines. */

        buttonMouseOverBackgroundColourId = 0x1003220,  /**< A colour used to paint the background of buttons when the mouse is
                                                             over them. */
        buttonMouseDownBackgroundColourId = 0x1003230,  /**< A colour used to paint the background of buttons when the mouse is
                                                             held down on them. */

        labelTextColourId           = 0x1003240,        /**< A colour to use for drawing the text under buttons
                                                             when the style is set to iconsWithText or textOnly. */

        editingModeOutlineColourId  = 0x1003250   /**< A colour to use for an outline around buttons when
                                                       the customisation dialog is active and the mouse moves over them. */
    };

    /** Returns a string that represents the toolbar's current set of items.

        This lets you later restore the same item layout using restoreFromString().

        @see restoreFromString
    */
    const String toString() const;

    /** Restores a set of items that was previously stored in a string by the toString()
        method.

        The factory object is used to create any item components that are needed.

        @see toString
    */
    bool restoreFromString (ToolbarItemFactory& factoryToUse,
                            const String& savedVersion);

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void buttonClicked (Button*);
    /** @internal */
    void mouseDown (const MouseEvent&);
    /** @internal */
    bool isInterestedInDragSource (const String&, Component*);
    /** @internal */
    void itemDragMove (const String&, Component*, int, int);
    /** @internal */
    void itemDragExit (const String&, Component*);
    /** @internal */
    void itemDropped (const String&, Component*, int, int);
    /** @internal */
    void updateAllItemPositions (const bool animate);
    /** @internal */
    static ToolbarItemComponent* createItem (ToolbarItemFactory&, const int itemId);

    juce_UseDebuggingNewOperator

private:
    Button* missingItemsButton;
    bool vertical, isEditingActive;
    ToolbarItemStyle toolbarStyle;
    ComponentAnimator animator;
    friend class MissingItemsComponent;
    Array <ToolbarItemComponent*> items;

    friend class ItemDragAndDropOverlayComponent;
    static const tchar* const toolbarDragDescriptor;

    void addItemInternal (ToolbarItemFactory& factory, const int itemId, const int insertIndex);

    ToolbarItemComponent* getNextActiveComponent (int index, const int delta) const;

    Toolbar (const Toolbar&);
    const Toolbar& operator= (const Toolbar&);
};

#endif   // __JUCE_TOOLBAR_JUCEHEADER__
/********* End of inlined file: juce_Toolbar.h *********/

class ItemDragAndDropOverlayComponent;

/**
    A component that can be used as one of the items in a Toolbar.

    Each of the items on a toolbar must be a component derived from ToolbarItemComponent,
    and these objects are always created by a ToolbarItemFactory - see the ToolbarItemFactory
    class for further info about creating them.

    The ToolbarItemComponent class is actually a button, but can be used to hold non-button
    components too. To do this, set the value of isBeingUsedAsAButton to false when
    calling the constructor, and override contentAreaChanged(), in which you can position
    any sub-components you need to add.

    To add basic buttons without writing a special subclass, have a look at the
    ToolbarButton class.

    @see ToolbarButton, Toolbar, ToolbarItemFactory
*/
class JUCE_API  ToolbarItemComponent  : public Button
{
public:

    /** Constructor.

        @param itemId       the ID of the type of toolbar item which this represents
        @param labelText    the text to display if the toolbar's style is set to
                            Toolbar::iconsWithText or Toolbar::textOnly
        @param isBeingUsedAsAButton     set this to false if you don't want the button
                            to draw itself with button over/down states when the mouse
                            moves over it or clicks
    */
    ToolbarItemComponent (const int itemId,
                          const String& labelText,
                          const bool isBeingUsedAsAButton);

    /** Destructor. */
    ~ToolbarItemComponent();

    /** Returns the item type ID that this component represents.
        This value is in the constructor.
    */
    int getItemId() const throw()                                       { return itemId; }

    /** Returns the toolbar that contains this component, or 0 if it's not currently
        inside one.
    */
    Toolbar* getToolbar() const;

    /** Returns true if this component is currently inside a toolbar which is vertical.
        @see Toolbar::isVertical
    */
    bool isToolbarVertical() const;

    /** Returns the current style setting of this item.

        Styles are listed in the Toolbar::ToolbarItemStyle enum.
        @see setStyle, Toolbar::getStyle
    */
    Toolbar::ToolbarItemStyle getStyle() const throw()                  { return toolbarStyle; }

    /** Changes the current style setting of this item.

        Styles are listed in the Toolbar::ToolbarItemStyle enum, and are automatically updated
        by the toolbar that holds this item.

        @see setStyle, Toolbar::setStyle
    */
    virtual void setStyle (const Toolbar::ToolbarItemStyle& newStyle);

    /** Returns the area of the component that should be used to display the button image or
        other contents of the item.

        This content area may change when the item's style changes, and may leave a space around the
        edge of the component where the text label can be shown.

        @see contentAreaChanged
    */
    const Rectangle getContentArea() const throw()                      { return contentArea; }

    /** This method must return the size criteria for this item, based on a given toolbar
        size and orientation.

        The preferredSize, minSize and maxSize values must all be set by your implementation
        method. If the toolbar is horizontal, these will be the width of the item; for a vertical
        toolbar, they refer to the item's height.

        The preferredSize is the size that the component would like to be, and this must be
        between the min and max sizes. For a fixed-size item, simply set all three variables to
        the same value.

        The toolbarThickness parameter tells you the depth of the toolbar - the same as calling
        Toolbar::getThickness().

        The isToolbarVertical parameter tells you whether the bar is oriented horizontally or
        vertically.
    */
    virtual bool getToolbarItemSizes (int toolbarThickness,
                                      bool isToolbarVertical,
                                      int& preferredSize,
                                      int& minSize,
                                      int& maxSize) = 0;

    /** Your subclass should use this method to draw its content area.

        The graphics object that is passed-in will have been clipped and had its origin
        moved to fit the content area as specified get getContentArea(). The width and height
        parameters are the width and height of the content area.

        If the component you're writing isn't a button, you can just do nothing in this method.
    */
    virtual void paintButtonArea (Graphics& g,
                                  int width, int height,
                                  bool isMouseOver, bool isMouseDown) = 0;

    /** Callback to indicate that the content area of this item has changed.

        This might be because the component was resized, or because the style changed and
        the space needed for the text label is different.

        See getContentArea() for a description of what the area is.
    */
    virtual void contentAreaChanged (const Rectangle& newBounds) = 0;

    /** Editing modes.
        These are used by setEditingMode(), but will be rarely needed in user code.
    */
    enum ToolbarEditingMode
    {
        normalMode = 0,     /**< Means that the component is active, inside a toolbar. */
        editableOnToolbar,  /**< Means that the component is on a toolbar, but the toolbar is in
                                 customisation mode, and the items can be dragged around. */
        editableOnPalette   /**< Means that the component is on an new-item palette, so it can be
                                 dragged onto a toolbar to add it to that bar.*/
    };

    /** Changes the editing mode of this component.

        This is used by the ToolbarItemPalette and related classes for making the items draggable,
        and is unlikely to be of much use in end-user-code.
    */
    void setEditingMode (const ToolbarEditingMode newMode);

    /** Returns the current editing mode of this component.

        This is used by the ToolbarItemPalette and related classes for making the items draggable,
        and is unlikely to be of much use in end-user-code.
    */
    ToolbarEditingMode getEditingMode() const throw()                   { return mode; }

    /** @internal */
    void paintButton (Graphics& g, bool isMouseOver, bool isMouseDown);
    /** @internal */
    void resized();

    juce_UseDebuggingNewOperator

private:
    friend class Toolbar;
    friend class ItemDragAndDropOverlayComponent;
    const int itemId;
    ToolbarEditingMode mode;
    Toolbar::ToolbarItemStyle toolbarStyle;
    Component* overlayComp;
    int dragOffsetX, dragOffsetY;
    bool isActive, isBeingDragged, isBeingUsedAsAButton;
    Rectangle contentArea;

    ToolbarItemComponent (const ToolbarItemComponent&);
    const ToolbarItemComponent& operator= (const ToolbarItemComponent&);
};

#endif   // __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_ToolbarItemComponent.h *********/

/**
    A type of button designed to go on a toolbar.

    This simple button can have two Drawable objects specified - one for normal
    use and another one (optionally) for the button's "on" state if it's a
    toggle button.

    @see Toolbar, ToolbarItemFactory, ToolbarItemComponent, Drawable, Button
*/
class JUCE_API  ToolbarButton   : public ToolbarItemComponent
{
public:

    /** Creates a ToolbarButton.

        @param itemId       the ID for this toolbar item type. This is passed through to the
                            ToolbarItemComponent constructor
        @param labelText    the text to display on the button (if the toolbar is using a style
                            that shows text labels). This is passed through to the
                            ToolbarItemComponent constructor
        @param normalImage  a drawable object that the button should use as its icon. The object
                            that is passed-in here will be kept by this object and will be
                            deleted when no longer needed or when this button is deleted.
        @param toggledOnImage  a drawable object that the button can use as its icon if the button
                            is in a toggled-on state (see the Button::getToggleState() method). If
                            0 is passed-in here, then the normal image will be used instead, regardless
                            of the toggle state. The object that is passed-in here will be kept by
                            this object and will be deleted when no longer needed or when this button
                            is deleted.
    */
    ToolbarButton (const int itemId,
                   const String& labelText,
                   Drawable* const normalImage,
                   Drawable* const toggledOnImage);

    /** Destructor. */
    ~ToolbarButton();

    /** @internal */
    bool getToolbarItemSizes (int toolbarDepth, bool isToolbarVertical, int& preferredSize,
                              int& minSize, int& maxSize);
    /** @internal */
    void paintButtonArea (Graphics& g, int width, int height, bool isMouseOver, bool isMouseDown);
    /** @internal */
    void contentAreaChanged (const Rectangle& newBounds);

    juce_UseDebuggingNewOperator

private:
    Drawable* const normalImage;
    Drawable* const toggledOnImage;

    ToolbarButton (const ToolbarButton&);
    const ToolbarButton& operator= (const ToolbarButton&);
};

#endif   // __JUCE_TOOLBARBUTTON_JUCEHEADER__
/********* End of inlined file: juce_ToolbarButton.h *********/

#endif
#ifndef __JUCE_DROPSHADOWEFFECT_JUCEHEADER__

#endif
#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__

/********* Start of inlined file: juce_GlowEffect.h *********/
#ifndef __JUCE_GLOWEFFECT_JUCEHEADER__
#define __JUCE_GLOWEFFECT_JUCEHEADER__

/**
    A component effect that adds a coloured blur around the component's contents.

    (This will only work on non-opaque components).

    @see Component::setComponentEffect, DropShadowEffect
*/
class JUCE_API  GlowEffect  : public ImageEffectFilter
{
public:

    /** Creates a default 'glow' effect.

        To customise its appearance, use the setGlowProperties() method.
    */
    GlowEffect();

    /** Destructor. */
    ~GlowEffect();

    /** Sets the glow's radius and colour.

        The radius is how large the blur should be, and the colour is
        used to render it (for a less intense glow, lower the colour's
        opacity).
    */
    void setGlowProperties (const float newRadius,
                            const Colour& newColour);

    /** @internal */
    void applyEffect (Image& sourceImage, Graphics& destContext);

    juce_UseDebuggingNewOperator

private:
    float radius;
    Colour colour;
};

#endif   // __JUCE_GLOWEFFECT_JUCEHEADER__
/********* End of inlined file: juce_GlowEffect.h *********/

#endif
#ifndef __JUCE_IMAGEEFFECTFILTER_JUCEHEADER__

#endif
#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__

/********* Start of inlined file: juce_ReduceOpacityEffect.h *********/
#ifndef __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__
#define __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__

/**
    An effect filter that reduces the image's opacity.

    This can be used to make a component (and its child components) more
    transparent.

    @see Component::setComponentEffect
*/
class JUCE_API  ReduceOpacityEffect  : public ImageEffectFilter
{
public:

    /** Creates the effect object.

        The opacity of the component to which the effect is applied will be
        scaled by the given factor (in the range 0 to 1.0f).
    */
    ReduceOpacityEffect (const float opacity = 1.0f);

    /** Destructor. */
    ~ReduceOpacityEffect();

    /** Sets how much to scale the component's opacity.

        @param newOpacity   should be between 0 and 1.0f
    */
    void setOpacity (const float newOpacity);

    /** @internal */
    void applyEffect (Image& sourceImage, Graphics& destContext);

    juce_UseDebuggingNewOperator

private:
    float opacity;
};

#endif   // __JUCE_REDUCEOPACITYEFFECT_JUCEHEADER__
/********* End of inlined file: juce_ReduceOpacityEffect.h *********/

#endif
#ifndef __JUCE_KEYBOARDFOCUSTRAVERSER_JUCEHEADER__

#endif
#ifndef __JUCE_KEYPRESS_JUCEHEADER__

#endif
#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_KeyMappingEditorComponent.h *********/
#ifndef __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__
#define __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_KeyPressMappingSet.h *********/
#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__
#define __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__

/**
    Manages and edits a list of keypresses, which it uses to invoke the appropriate
    command in a ApplicationCommandManager.

    Normally, you won't actually create a KeyPressMappingSet directly, because
    each ApplicationCommandManager contains its own KeyPressMappingSet, so typically
    you'd create yourself an ApplicationCommandManager, and call its
    ApplicationCommandManager::getKeyMappings() method to get a pointer to its
    KeyPressMappingSet.

    For one of these to actually use keypresses, you'll need to add it as a KeyListener
    to the top-level component for which you want to handle keystrokes. So for example:

    @code
    class MyMainWindow  : public Component
    {
        ApplicationCommandManager* myCommandManager;

    public:
        MyMainWindow()
        {
            myCommandManager = new ApplicationCommandManager();

            // first, make sure the command manager has registered all the commands that its
            // targets can perform..
            myCommandManager->registerAllCommandsForTarget (myCommandTarget1);
            myCommandManager->registerAllCommandsForTarget (myCommandTarget2);

            // this will use the command manager to initialise the KeyPressMappingSet with
            // the default keypresses that were specified when the targets added their commands
            // to the manager.
            myCommandManager->getKeyMappings()->resetToDefaultMappings();

            // having set up the default key-mappings, you might now want to load the last set
            // of mappings that the user configured.
            myCommandManager->getKeyMappings()->restoreFromXml (lastSavedKeyMappingsXML);

            // Now tell our top-level window to send any keypresses that arrive to the
            // KeyPressMappingSet, which will use them to invoke the appropriate commands.
            addKeyListener (myCommandManager->getKeyMappings());
        }

        ...
    }
    @endcode

    KeyPressMappingSet derives from ChangeBroadcaster so that interested parties can
    register to be told when a command or mapping is added, removed, etc.

    There's also a UI component called KeyMappingEditorComponent that can be used
    to easily edit the key mappings.

    @see Component::addKeyListener(), KeyMappingEditorComponent, ApplicationCommandManager
*/
class JUCE_API  KeyPressMappingSet  : public KeyListener,
                                      public ChangeBroadcaster,
                                      public FocusChangeListener
{
public:

    /** Creates a KeyPressMappingSet for a given command manager.

        Normally, you won't actually create a KeyPressMappingSet directly, because
        each ApplicationCommandManager contains its own KeyPressMappingSet, so the
        best thing to do is to create your ApplicationCommandManager, and use the
        ApplicationCommandManager::getKeyMappings() method to access its mappings.

        When a suitable keypress happens, the manager's invoke() method will be
        used to invoke the appropriate command.

        @see ApplicationCommandManager
    */
    KeyPressMappingSet (ApplicationCommandManager* const commandManager) throw();

    /** Creates an copy of a KeyPressMappingSet. */
    KeyPressMappingSet (const KeyPressMappingSet& other) throw();

    /** Destructor. */
    ~KeyPressMappingSet();

    ApplicationCommandManager* getCommandManager() const throw()        { return commandManager; }

    /** Returns a list of keypresses that are assigned to a particular command.

        @param commandID        the command's ID
    */
    const Array <KeyPress> getKeyPressesAssignedToCommand (const CommandID commandID) const throw();

    /** Assigns a keypress to a command.

        If the keypress is already assigned to a different command, it will first be
        removed from that command, to avoid it triggering multiple functions.

        @param commandID    the ID of the command that you want to add a keypress to. If
                            this is 0, the keypress will be removed from anything that it
                            was previously assigned to, but not re-assigned
        @param newKeyPress  the new key-press
        @param insertIndex  if this is less than zero, the key will be appended to the
                            end of the list of keypresses; otherwise the new keypress will
                            be inserted into the existing list at this index
    */
    void addKeyPress (const CommandID commandID,
                      const KeyPress& newKeyPress,
                      int insertIndex = -1) throw();

    /** Reset all mappings to the defaults, as dictated by the ApplicationCommandManager.

        @see resetToDefaultMapping
    */
    void resetToDefaultMappings() throw();

    /** Resets all key-mappings to the defaults for a particular command.

        @see resetToDefaultMappings
    */
    void resetToDefaultMapping (const CommandID commandID) throw();

    /** Removes all keypresses that are assigned to any commands. */
    void clearAllKeyPresses() throw();

    /** Removes all keypresses that are assigned to a particular command. */
    void clearAllKeyPresses (const CommandID commandID) throw();

    /** Removes one of the keypresses that are assigned to a command.

        See the getKeyPressesAssignedToCommand() for the list of keypresses to
        which the keyPressIndex refers.
    */
    void removeKeyPress (const CommandID commandID,
                         const int keyPressIndex) throw();

    /** Removes a keypress from any command that it may be assigned to.
    */
    void removeKeyPress (const KeyPress& keypress) throw();

    /** Returns true if the given command is linked to this key. */
    bool containsMapping (const CommandID commandID,
                          const KeyPress& keyPress) const throw();

    /** Looks for a command that corresponds to a keypress.

        @returns the UID of the command or 0 if none was found
    */
    CommandID findCommandForKeyPress (const KeyPress& keyPress) const throw();

    /** Tries to recreate the mappings from a previously stored state.

        The XML passed in must have been created by the createXml() method.

        If the stored state makes any reference to commands that aren't
        currently available, these will be ignored.

        If the set of mappings being loaded was a set of differences (using createXml (true)),
        then this will call resetToDefaultMappings() and then merge the saved mappings
        on top. If the saved set was created with createXml (false), then this method
        will first clear all existing mappings and load the saved ones as a complete set.

        @returns true if it manages to load the XML correctly
        @see createXml
    */
    bool restoreFromXml (const XmlElement& xmlVersion);

    /** Creates an XML representation of the current mappings.

        This will produce a lump of XML that can be later reloaded using
        restoreFromXml() to recreate the current mapping state.

        The object that is returned must be deleted by the caller.

        @param saveDifferencesFromDefaultSet    if this is false, then all keypresses
                            will be saved into the XML. If it's true, then the XML will
                            only store the differences between the current mappings and
                            the default mappings you'd get from calling resetToDefaultMappings().
                            The advantage of saving a set of differences from the default is that
                            if you change the default mappings (in a new version of your app, for
                            example), then these will be merged into a user's saved preferences.

        @see restoreFromXml
    */
    XmlElement* createXml (const bool saveDifferencesFromDefaultSet) const;

    /** @internal */
    bool keyPressed (const KeyPress& key, Component* originatingComponent);
    /** @internal */
    bool keyStateChanged (const bool isKeyDown, Component* originatingComponent);
    /** @internal */
    void globalFocusChanged (Component* focusedComponent);

    juce_UseDebuggingNewOperator

private:

    ApplicationCommandManager* commandManager;

    struct CommandMapping
    {
        CommandID commandID;
        Array <KeyPress> keypresses;
        bool wantsKeyUpDownCallbacks;
    };

    OwnedArray <CommandMapping> mappings;

    struct KeyPressTime
    {
        KeyPress key;
        uint32 timeWhenPressed;
    };

    OwnedArray <KeyPressTime> keysDown;

    void handleMessage (const Message& message);

    void invokeCommand (const CommandID commandID,
                        const KeyPress& keyPress,
                        const bool isKeyDown,
                        const int millisecsSinceKeyPressed,
                        Component* const originatingComponent) const;

    const KeyPressMappingSet& operator= (const KeyPressMappingSet&);
};

#endif   // __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__
/********* End of inlined file: juce_KeyPressMappingSet.h *********/

/********* Start of inlined file: juce_TreeView.h *********/
#ifndef __JUCE_TREEVIEW_JUCEHEADER__
#define __JUCE_TREEVIEW_JUCEHEADER__

class TreeView;

/**
    An item in a treeview.

    A TreeViewItem can either be a leaf-node in the tree, or it can contain its
    own sub-items.

    To implement an item that contains sub-items, override the itemOpennessChanged()
    method so that when it is opened, it adds the new sub-items to itself using the
    addSubItem method. Depending on the nature of the item it might choose to only
    do this the first time it's opened, or it might want to refresh itself each time.
    It also has the option of deleting its sub-items when it is closed, or leaving them
    in place.
*/
class JUCE_API  TreeViewItem
{
public:

    /** Constructor. */
    TreeViewItem();

    /** Destructor. */
    virtual ~TreeViewItem();

    /** Returns the number of sub-items that have been added to this item.

        Note that this doesn't mean much if the node isn't open.

        @see getSubItem, mightContainSubItems, addSubItem
    */
    int getNumSubItems() const throw();

    /** Returns one of the item's sub-items.

        Remember that the object returned might get deleted at any time when its parent
        item is closed or refreshed, depending on the nature of the items you're using.

        @see getNumSubItems
    */
    TreeViewItem* getSubItem (const int index) const throw();

    /** Removes any sub-items. */
    void clearSubItems();

    /** Adds a sub-item.

        @param newItem  the object to add to the item's sub-item list. Once added, these can be
                        found using getSubItem(). When the items are later removed with
                        removeSubItem() (or when this item is deleted), they will be deleted.
        @param insertPosition   the index which the new item should have when it's added. If this
                                value is less than 0, the item will be added to the end of the list.
    */
    void addSubItem (TreeViewItem* const newItem,
                     const int insertPosition = -1);

    /** Removes one of the sub-items.

        @param index        the item to remove
        @param deleteItem   if true, the item that is removed will also be deleted.
    */
    void removeSubItem (const int index,
                        const bool deleteItem = true);

    /** Returns the TreeView to which this item belongs. */
    TreeView* getOwnerView() const throw()              { return ownerView; }

    /** Returns the item within which this item is contained. */
    TreeViewItem* getParentItem() const throw()         { return parentItem; }

    /** True if this item is currently open in the treeview. */
    bool isOpen() const throw();

    /** Opens or closes the item.

        When opened or closed, the item's itemOpennessChanged() method will be called,
        and a subclass should use this callback to create and add any sub-items that
        it needs to.

        @see itemOpennessChanged, mightContainSubItems
    */
    void setOpen (const bool shouldBeOpen);

    /** True if this item is currently selected.

        Use this when painting the node, to decide whether to draw it as selected or not.
    */
    bool isSelected() const throw();

    /** Selects or deselects the item.

        This will cause a callback to itemSelectionChanged()
    */
    void setSelected (const bool shouldBeSelected,
                      const bool deselectOtherItemsFirst);

    /** Returns the rectangle that this item occupies.

        If relativeToTreeViewTopLeft is true, the co-ordinates are relative to the
        top-left of the TreeView comp, so this will depend on the scroll-position of
        the tree. If false, it is relative to the top-left of the topmost item in the
        tree (so this would be unaffected by scrolling the view).
    */
    const Rectangle getItemPosition (const bool relativeToTreeViewTopLeft) const throw();

    /** Sends a signal to the treeview to make it refresh itself.

        Call this if your items have changed and you want the tree to update to reflect
        this.
    */
    void treeHasChanged() const throw();

    /** Sends a repaint message to redraw just this item.

        Note that you should only call this if you want to repaint a superficial change. If
        you're altering the tree's nodes, you should instead call treeHasChanged().
    */
    void repaintItem() const;

    /** Returns the row number of this item in the tree.

        The row number of an item will change according to which items are open.

        @see TreeView::getNumRowsInTree(), TreeView::getItemOnRow()
    */
    int getRowNumberInTree() const throw();

    /** Returns true if all the item's parent nodes are open.

        This is useful to check whether the item might actually be visible or not.
    */
    bool areAllParentsOpen() const throw();

    /** Changes whether lines are drawn to connect any sub-items to this item.

        By default, line-drawing is turned on.
    */
    void setLinesDrawnForSubItems (const bool shouldDrawLines) throw();

    /** Tells the tree whether this item can potentially be opened.

        If your item could contain sub-items, this should return true; if it returns
        false then the tree will not try to open the item. This determines whether or
        not the item will be drawn with a 'plus' button next to it.
    */
    virtual bool mightContainSubItems() = 0;

    /** Returns a string to uniquely identify this item.

        If you're planning on using the TreeView::getOpennessState() method, then
        these strings will be used to identify which nodes are open. The string
        should be unique amongst the item's sibling items, but it's ok for there
        to be duplicates at other levels of the tree.

        If you're not going to store the state, then it's ok not to bother implementing
        this method.
    */
    virtual const String getUniqueName() const;

    /** Called when an item is opened or closed.

        When setOpen() is called and the item has specified that it might
        have sub-items with the mightContainSubItems() method, this method
        is called to let the item create or manage its sub-items.

        So when this is called with isNowOpen set to true (i.e. when the item is being
        opened), a subclass might choose to use clearSubItems() and addSubItem() to
        refresh its sub-item list.

        When this is called with isNowOpen set to false, the subclass might want
        to use clearSubItems() to save on space, or it might choose to leave them,
        depending on the nature of the tree.

        You could also use this callback as a trigger to start a background process
        which asynchronously creates sub-items and adds them, if that's more
        appropriate for the task in hand.

        @see mightContainSubItems
    */
    virtual void itemOpennessChanged (bool isNowOpen);

    /** Must return the width required by this item.

        If your item needs to have a particular width in pixels, return that value; if
        you'd rather have it just fill whatever space is available in the treeview,
        return -1.

        If all your items return -1, no horizontal scrollbar will be shown, but if any
        items have fixed widths and extend beyond the width of the treeview, a
        scrollbar will appear.

        Each item can be a different width, but if they change width, you should call
        treeHasChanged() to update the tree.
    */
    virtual int getItemWidth() const                                { return -1; }

    /** Must return the height required by this item.

        This is the height in pixels that the item will take up. Items in the tree
        can be different heights, but if they change height, you should call
        treeHasChanged() to update the tree.
    */
    virtual int getItemHeight() const                               { return 20; }

    /** You can override this method to return false if you don't want to allow the
        user to select this item.
    */
    virtual bool canBeSelected() const                              { return true; }

    /** Creates a component that will be used to represent this item.

        You don't have to implement this method - if it returns 0 then no component
        will be used for the item, and you can just draw it using the paintItem()
        callback. But if you do return a component, it will be positioned in the
        treeview so that it can be used to represent this item.

        The component returned will be managed by the treeview, so always return
        a new component, and don't keep a reference to it, as the treeview will
        delete it later when it goes off the screen or is no longer needed. Also
        bear in mind that if the component keeps a reference to the item that
        created it, that item could be deleted before the component. Its position
        and size will be completely managed by the tree, so don't attempt to move it
        around.

        Something you may want to do with your component is to give it a pointer to
        the TreeView that created it. This is perfectly safe, and there's no danger
        of it becoming a dangling pointer because the TreeView will always delete
        the component before it is itself deleted.

        As long as you stick to these rules you can return whatever kind of
        component you like. It's most useful if you're doing things like drag-and-drop
        of items, or want to use a Label component to edit item names, etc.
    */
    virtual Component* createItemComponent()                        { return 0; }

    /** Draws the item's contents.

        You can choose to either implement this method and draw each item, or you
        can use createItemComponent() to create a component that will represent the
        item.

        If all you need in your tree is to be able to draw the items and detect when
        the user selects or double-clicks one of them, it's probably enough to
        use paintItem(), itemClicked() and itemDoubleClicked(). If you need more
        complicated interactions, you may need to use createItemComponent() instead.

        @param g        the graphics context to draw into
        @param width    the width of the area available for drawing
        @param height   the height of the area available for drawing
    */
    virtual void paintItem (Graphics& g, int width, int height);

    /** Draws the item's open/close button.

        If you don't implement this method, the default behaviour is to
        call LookAndFeel::drawTreeviewPlusMinusBox(), but you can override
        it for custom effects.
    */
    virtual void paintOpenCloseButton (Graphics& g, int width, int height, bool isMouseOver);

    /** Called when the user clicks on this item.

        If you're using createItemComponent() to create a custom component for the
        item, the mouse-clicks might not make it through to the treeview, but this
        is how you find out about clicks when just drawing each item individually.

        The associated mouse-event details are passed in, so you can find out about
        which button, where it was, etc.

        @see itemDoubleClicked
    */
    virtual void itemClicked (const MouseEvent& e);

    /** Called when the user double-clicks on this item.

        If you're using createItemComponent() to create a custom component for the
        item, the mouse-clicks might not make it through to the treeview, but this
        is how you find out about clicks when just drawing each item individually.

        The associated mouse-event details are passed in, so you can find out about
        which button, where it was, etc.

        If not overridden, the base class method here will open or close the item as
        if the 'plus' button had been clicked.

        @see itemClicked
    */
    virtual void itemDoubleClicked (const MouseEvent& e);

    /** Called when the item is selected or deselected.

        Use this if you want to do something special when the item's selectedness
        changes. By default it'll get repainted when this happens.
    */
    virtual void itemSelectionChanged (bool isNowSelected);

    /** The item can return a tool tip string here if it wants to.
        @see TooltipClient
    */
    virtual const String getTooltip();

    /** To allow items from your treeview to be dragged-and-dropped, implement this method.

        If this returns a non-empty name then when the user drags an item, the treeview will
        try to find a DragAndDropContainer in its parent hierarchy, and will use it to trigger
        a drag-and-drop operation, using this string as the source description, with the treeview
        itself as the source component.

        If you need more complex drag-and-drop behaviour, you can use custom components for
        the items, and use those to trigger the drag.

        @see DragAndDropContainer::startDragging
    */
    virtual const String getDragSourceDescription();

    /** Sets a flag to indicate that the item wants to be allowed
        to draw all the way across to the left edge of the treeview.

        By default this is false, which means that when the paintItem()
        method is called, its graphics context is clipped to only allow
        drawing within the item's rectangle. If this flag is set to true,
        then the graphics context isn't clipped on its left side, so it
        can draw all the way across to the left margin. Note that the
        context will still have its origin in the same place though, so
        the coordinates of anything to its left will be negative. It's
        mostly useful if you want to draw a wider bar behind the
        highlighted item.
    */
    void setDrawsInLeftMargin (bool canDrawInLeftMargin) throw();

    juce_UseDebuggingNewOperator

private:
    TreeView* ownerView;
    TreeViewItem* parentItem;
    OwnedArray <TreeViewItem> subItems;
    int y, itemHeight, totalHeight, itemWidth, totalWidth;
    int uid;
    bool selected           : 1;
    bool redrawNeeded       : 1;
    bool drawLinesInside    : 1;
    bool drawsInLeftMargin  : 1;
    unsigned int openness   : 2;

    friend class TreeView;
    friend class TreeViewContentComponent;

    void updatePositions (int newY);
    int getIndentX() const throw();
    void setOwnerView (TreeView* const newOwner) throw();
    void paintRecursively (Graphics& g, int width);
    TreeViewItem* findItemRecursively (int y) throw();
    TreeViewItem* getDeepestOpenParentItem() throw();
    void restoreFromXml (const XmlElement& e);
    XmlElement* createXmlOpenness() const;
    bool isLastOfSiblings() const throw();
    TreeViewItem* getTopLevelItem() throw();
    int getNumRows() const throw();
    TreeViewItem* getItemOnRow (int index) throw();
    void deselectAllRecursively();
    int countSelectedItemsRecursively() const throw();
    TreeViewItem* getSelectedItemWithIndex (int index) throw();
    TreeViewItem* getNextVisibleItem (const bool recurse) const throw();

    TreeViewItem (const TreeViewItem&);
    const TreeViewItem& operator= (const TreeViewItem&);
};

/**
    A tree-view component.

    Use one of these to hold and display a structure of TreeViewItem objects.

*/
class JUCE_API  TreeView  : public Component,
                            public SettableTooltipClient,
                            private AsyncUpdater
{
public:

    /** Creates an empty treeview.

        Once you've got a treeview component, you'll need to give it something to
        display, using the setRootItem() method.
    */
    TreeView (const String& componentName = String::empty);

    /** Destructor. */
    ~TreeView();

    /** Sets the item that is displayed in the treeview.

        A tree has a single root item which contains as many sub-items as it needs. If
        you want the tree to contain a number of root items, you should still use a single
        root item above these, but hide it using setRootItemVisible().

        You can pass in 0 to this method to clear the tree and remove its current root item.

        The object passed in will not be deleted by the treeview, it's up to the caller
        to delete it when no longer needed. BUT make absolutely sure that you don't delete
        this item until you've removed it from the tree, either by calling setRootItem (0),
        or by deleting the tree first. You can also use deleteRootItem() as a quick way
        to delete it.
    */
    void setRootItem (TreeViewItem* const newRootItem);

    /** Returns the tree's root item.

        This will be the last object passed to setRootItem(), or 0 if none has been set.
    */
    TreeViewItem* getRootItem() const throw()                       { return rootItem; }

    /** This will remove and delete the current root item.

        It's a convenient way of deleting the item and calling setRootItem (0).
    */
    void deleteRootItem();

    /** Changes whether the tree's root item is shown or not.

        If the root item is hidden, only its sub-items will be shown in the treeview - this
        lets you make the tree look as if it's got many root items. If it's hidden, this call
        will also make sure the root item is open (otherwise the treeview would look empty).
    */
    void setRootItemVisible (const bool shouldBeVisible);

    /** Returns true if the root item is visible.

        @see setRootItemVisible
    */
    bool isRootItemVisible() const throw()                          { return rootItemVisible; }

    /** Sets whether items are open or closed by default.

        Normally, items are closed until the user opens them, but you can use this
        to make them default to being open until explicitly closed.

        @see areItemsOpenByDefault
    */
    void setDefaultOpenness (const bool isOpenByDefault);

    /** Returns true if the tree's items default to being open.

        @see setDefaultOpenness
    */
    bool areItemsOpenByDefault() const throw()                      { return defaultOpenness; }

    /** This sets a flag to indicate that the tree can be used for multi-selection.

        You can always select multiple items internally by calling the
        TreeViewItem::setSelected() method, but this flag indicates whether the user
        is allowed to multi-select by clicking on the tree.

        By default it is disabled.

        @see isMultiSelectEnabled
    */
    void setMultiSelectEnabled (const bool canMultiSelect);

    /** Returns whether multi-select has been enabled for the tree.

        @see setMultiSelectEnabled
    */
    bool isMultiSelectEnabled() const throw()                       { return multiSelectEnabled; }

    /** Sets a flag to indicate whether to hide the open/close buttons.

        @see areOpenCloseButtonsVisible
    */
    void setOpenCloseButtonsVisible (const bool shouldBeVisible);

    /** Returns whether open/close buttons are shown.

        @see setOpenCloseButtonsVisible
    */
    bool areOpenCloseButtonsVisible() const throw()                 { return openCloseButtonsVisible; }

    /** Deselects any items that are currently selected. */
    void clearSelectedItems();

    /** Returns the number of items that are currently selected.

        @see getSelectedItem, clearSelectedItems
    */
    int getNumSelectedItems() const throw();

    /** Returns one of the selected items in the tree.

        @param index    the index, 0 to (getNumSelectedItems() - 1)
    */
    TreeViewItem* getSelectedItem (const int index) const throw();

    /** Returns the number of rows the tree is using.

        This will depend on which items are open.

        @see TreeViewItem::getRowNumberInTree()
    */
    int getNumRowsInTree() const;

    /** Returns the item on a particular row of the tree.

        If the index is out of range, this will return 0.

        @see getNumRowsInTree, TreeViewItem::getRowNumberInTree()
    */
    TreeViewItem* getItemOnRow (int index) const;

    /** Tries to scroll the tree so that this item is on-screen somewhere. */
    void scrollToKeepItemVisible (TreeViewItem* item);

    /** Returns the treeview's Viewport object. */
    Viewport* getViewport() const throw()                           { return viewport; }

    /** Returns the number of pixels by which each nested level of the tree is indented.
        @see setIndentSize
    */
    int getIndentSize() const throw()                               { return indentSize; }

    /** Changes the distance by which each nested level of the tree is indented.
        @see getIndentSize
    */
    void setIndentSize (const int newIndentSize);

    /** Saves the current state of open/closed nodes so it can be restored later.

        This takes a snapshot of which nodes have been explicitly opened or closed,
        and records it as XML. To identify node objects it uses the
        TreeViewItem::getUniqueName() method to create named paths. This
        means that the same state of open/closed nodes can be restored to a
        completely different instance of the tree, as long as it contains nodes
        whose unique names are the same.

        The caller is responsible for deleting the object that is returned.

        @param alsoIncludeScrollPosition    if this is true, the state will also
                                            include information about where the
                                            tree has been scrolled to vertically,
                                            so this can also be restored
        @see restoreOpennessState
    */
    XmlElement* getOpennessState (const bool alsoIncludeScrollPosition) const;

    /** Restores a previously saved arrangement of open/closed nodes.

        This will try to restore a snapshot of the tree's state that was created by
        the getOpennessState() method. If any of the nodes named in the original
        XML aren't present in this tree, they will be ignored.

        @see getOpennessState
    */
    void restoreOpennessState (const XmlElement& newState);

    /** A set of colour IDs to use to change the colour of various aspects of the treeview.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId      = 0x1000500,    /**< A background colour to fill the component with. */
        linesColourId           = 0x1000501     /**< The colour to draw the lines with.*/
    };

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    bool keyPressed (const KeyPress& key);
    /** @internal */
    void colourChanged();
    /** @internal */
    void enablementChanged();

    juce_UseDebuggingNewOperator

private:
    friend class TreeViewItem;
    friend class TreeViewContentComponent;
    Viewport* viewport;
    CriticalSection nodeAlterationLock;
    TreeViewItem* rootItem;
    int indentSize;
    bool defaultOpenness : 1;
    bool needsRecalculating : 1;
    bool rootItemVisible : 1;
    bool multiSelectEnabled : 1;
    bool openCloseButtonsVisible : 1;

    void itemsChanged() throw();
    void handleAsyncUpdate();
    void moveSelectedRow (int delta);
    void updateButtonUnderMouse (const MouseEvent& e);

    TreeView (const TreeView&);
    const TreeView& operator= (const TreeView&);
};

#endif   // __JUCE_TREEVIEW_JUCEHEADER__
/********* End of inlined file: juce_TreeView.h *********/

/**
    A component to allow editing of the keymaps stored by a KeyPressMappingSet
    object.

    @see KeyPressMappingSet
*/
class JUCE_API  KeyMappingEditorComponent  : public Component,
                                             public TreeViewItem,
                                             public ChangeListener,
                                             private ButtonListener
{
public:

    /** Creates a KeyMappingEditorComponent.

        @param mappingSet   this is the set of mappings to display and
                            edit. Make sure the mappings object is not
                            deleted before this component!
        @param showResetToDefaultButton     if true, then at the bottom of the
                            list, the component will include a 'reset to
                            defaults' button.
    */
    KeyMappingEditorComponent (KeyPressMappingSet* const mappingSet,
                               const bool showResetToDefaultButton);

    /** Destructor. */
    virtual ~KeyMappingEditorComponent();

    /** Sets up the colours to use for parts of the component.

        @param mainBackground       colour to use for most of the background
        @param textColour           colour to use for the text
    */
    void setColours (const Colour& mainBackground,
                     const Colour& textColour);

    /** Returns the KeyPressMappingSet that this component is acting upon.
    */
    KeyPressMappingSet* getMappings() const throw()                 { return mappings; }

    /** Can be overridden if some commands need to be excluded from the list.

        By default this will use the KeyPressMappingSet's shouldCommandBeVisibleInEditor()
        method to decide what to return, but you can override it to handle special cases.
    */
    virtual bool shouldCommandBeIncluded (const CommandID commandID);

    /** Can be overridden to indicate that some commands are shown as read-only.

        By default this will use the KeyPressMappingSet's shouldCommandBeReadOnlyInEditor()
        method to decide what to return, but you can override it to handle special cases.
    */
    virtual bool isCommandReadOnly (const CommandID commandID);

    /** This can be overridden to let you change the format of the string used
        to describe a keypress.

        This is handy if you're using non-standard KeyPress objects, e.g. for custom
        keys that are triggered by something else externally. If you override the
        method, be sure to let the base class's method handle keys you're not
        interested in.
    */
    virtual const String getDescriptionForKeyPress (const KeyPress& key);

    /** @internal */
    void parentHierarchyChanged();
    /** @internal */
    void resized();
    /** @internal */
    void changeListenerCallback (void*);
    /** @internal */
    bool mightContainSubItems();
    /** @internal */
    const String getUniqueName() const;
    /** @internal */
    void buttonClicked (Button* button);

    juce_UseDebuggingNewOperator

private:

    KeyPressMappingSet* mappings;
    TreeView* tree;
    friend class KeyMappingTreeViewItem;
    friend class KeyCategoryTreeViewItem;
    friend class KeyMappingItemComponent;
    friend class KeyMappingChangeButton;
    Colour backgroundColour, textColour;
    TextButton* resetButton;

    void assignNewKey (const CommandID commandID, int index);

    KeyMappingEditorComponent (const KeyMappingEditorComponent&);
    const KeyMappingEditorComponent& operator= (const KeyMappingEditorComponent&);
};

#endif   // __JUCE_KEYMAPPINGEDITORCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_KeyMappingEditorComponent.h *********/

#endif
#ifndef __JUCE_MODIFIERKEYS_JUCEHEADER__

#endif
#ifndef __JUCE_KEYLISTENER_JUCEHEADER__

#endif
#ifndef __JUCE_KEYPRESSMAPPINGSET_JUCEHEADER__

#endif
#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_MenuBarComponent.h *********/
#ifndef __JUCE_MENUBARCOMPONENT_JUCEHEADER__
#define __JUCE_MENUBARCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_MenuBarModel.h *********/
#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__
#define __JUCE_MENUBARMODEL_JUCEHEADER__

class MenuBarModel;

/**
    A class to receive callbacks when a MenuBarModel changes.

    @see MenuBarModel::addListener, MenuBarModel::removeListener, MenuBarModel::menuItemsChanged
*/
class JUCE_API  MenuBarModelListener
{
public:
    /** Destructor. */
    virtual ~MenuBarModelListener() {}

    /** This callback is made when items are changed in the menu bar model.
    */
    virtual void menuBarItemsChanged (MenuBarModel* menuBarModel) = 0;

    /** This callback is made when an application command is invoked that
        is represented by one of the items in the menu bar model.
    */
    virtual void menuCommandInvoked (MenuBarModel* menuBarModel,
                                     const ApplicationCommandTarget::InvocationInfo& info) = 0;
};

/**
    A class for controlling MenuBar components.

    This class is used to tell a MenuBar what menus to show, and to respond
    to a menu being selected.

    @see MenuBarModelListener, MenuBarComponent, PopupMenu
*/
class JUCE_API  MenuBarModel      : private AsyncUpdater,
                                    private ApplicationCommandManagerListener
{
public:

    MenuBarModel() throw();

    /** Destructor. */
    virtual ~MenuBarModel();

    /** Call this when some of your menu items have changed.

        This method will cause a callback to any MenuBarListener objects that
        are registered with this model.

        If this model is displaying items from an ApplicationCommandManager, you
        can use the setApplicationCommandManagerToWatch() method to cause
        change messages to be sent automatically when the ApplicationCommandManager
        is changed.

        @see addListener, removeListener, MenuBarListener
    */
    void menuItemsChanged();

    /** Tells the menu bar to listen to the specified command manager, and to update
        itself when the commands change.

        This will also allow it to flash a menu name when a command from that menu
        is invoked using a keystroke.
    */
    void setApplicationCommandManagerToWatch (ApplicationCommandManager* const manager) throw();

    /** Registers a listener for callbacks when the menu items in this model change.

        The listener object will get callbacks when this object's menuItemsChanged()
        method is called.

        @see removeListener
    */
    void addListener (MenuBarModelListener* const listenerToAdd) throw();

    /** Removes a listener.

        @see addListener
    */
    void removeListener (MenuBarModelListener* const listenerToRemove) throw();

    /** This method must return a list of the names of the menus. */
    virtual const StringArray getMenuBarNames() = 0;

    /** This should return the popup menu to display for a given top-level menu.

        @param topLevelMenuIndex    the index of the top-level menu to show
        @param menuName             the name of the top-level menu item to show
    */
    virtual const PopupMenu getMenuForIndex (int topLevelMenuIndex,
                                             const String& menuName) = 0;

    /** This is called when a menu item has been clicked on.

        @param menuItemID           the item ID of the PopupMenu item that was selected
        @param topLevelMenuIndex    the index of the top-level menu from which the item was
                                    chosen (just in case you've used duplicate ID numbers
                                    on more than one of the popup menus)
    */
    virtual void menuItemSelected (int menuItemID,
                                   int topLevelMenuIndex) = 0;

#if JUCE_MAC || DOXYGEN
    /** MAC ONLY - Sets the model that is currently being shown as the main
        menu bar at the top of the screen on the Mac.

        You can pass 0 to stop the current model being displayed. Be careful
        not to delete a model while it is being used.

        An optional extra menu can be specified, containing items to add to the top of
        the apple menu. (Confusingly, the 'apple' menu isn't the one with a picture of
        an apple, it's the one next to it, with your application's name at the top
        and the services menu etc on it). When one of these items is selected, the
        menu bar model will be used to invoke it, and in the menuItemSelected() callback
        the topLevelMenuIndex parameter will be -1. If you pass in an extraAppleMenuItems
        object then newMenuBarModel must be non-null.
    */
    static void setMacMainMenu (MenuBarModel* newMenuBarModel,
                                const PopupMenu* extraAppleMenuItems = 0) throw();

    /** MAC ONLY - Returns the menu model that is currently being shown as
        the main menu bar.
    */
    static MenuBarModel* getMacMainMenu() throw();

#endif

    /** @internal */
    void applicationCommandInvoked (const ApplicationCommandTarget::InvocationInfo& info);
    /** @internal */
    void applicationCommandListChanged();
    /** @internal */
    void handleAsyncUpdate();

    juce_UseDebuggingNewOperator

private:
    ApplicationCommandManager* manager;
    SortedSet <void*> listeners;

    MenuBarModel (const MenuBarModel&);
    const MenuBarModel& operator= (const MenuBarModel&);
};

#endif   // __JUCE_MENUBARMODEL_JUCEHEADER__
/********* End of inlined file: juce_MenuBarModel.h *********/

/**
    A menu bar component.

    @see MenuBarModel
*/
class JUCE_API  MenuBarComponent  : public Component,
                                    private MenuBarModelListener,
                                    private Timer
{
public:

    /** Creates a menu bar.

        @param model        the model object to use to control this bar. You can
                            pass 0 into this if you like, and set the model later
                            using the setModel() method
    */
    MenuBarComponent (MenuBarModel* const model);

    /** Destructor. */
    ~MenuBarComponent();

    /** Changes the model object to use to control the bar.

        This can be 0, in which case the bar will be empty. Don't delete the object
        that is passed-in while it's still being used by this MenuBar.
    */
    void setModel (MenuBarModel* const newModel);

    /** Pops up one of the menu items.

        This lets you manually open one of the menus - it could be triggered by a
        key shortcut, for example.
    */
    void showMenu (const int menuIndex);

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void mouseEnter (const MouseEvent& e);
    /** @internal */
    void mouseExit (const MouseEvent& e);
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    void mouseUp (const MouseEvent& e);
    /** @internal */
    void mouseMove (const MouseEvent& e);
    /** @internal */
    void inputAttemptWhenModal();
    /** @internal */
    void handleCommandMessage (int commandId);
    /** @internal */
    bool keyPressed (const KeyPress& key);
    /** @internal */
    void menuBarItemsChanged (MenuBarModel* menuBarModel);
    /** @internal */
    void menuCommandInvoked (MenuBarModel* menuBarModel,
                             const ApplicationCommandTarget::InvocationInfo& info);

    juce_UseDebuggingNewOperator

private:
    MenuBarModel* model;

    StringArray menuNames;
    Array <int> xPositions;
    int itemUnderMouse, currentPopupIndex, topLevelIndexClicked, indexToShowAgain;
    int lastMouseX, lastMouseY;
    bool inModalState;
    Component* currentPopup;

    int getItemAt (int x, int y);
    void updateItemUnderMouse (const int x, const int y);
    void hideCurrentMenu();
    void timerCallback();
    void repaintMenuItem (int index);

    MenuBarComponent (const MenuBarComponent&);
    const MenuBarComponent& operator= (const MenuBarComponent&);
};

#endif   // __JUCE_MENUBARCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_MenuBarComponent.h *********/

#endif
#ifndef __JUCE_MENUBARMODEL_JUCEHEADER__

#endif
#ifndef __JUCE_POPUPMENU_JUCEHEADER__

#endif
#ifndef __JUCE_POPUPMENUCUSTOMCOMPONENT_JUCEHEADER__

#endif
#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__

/********* Start of inlined file: juce_ComponentDragger.h *********/
#ifndef __JUCE_COMPONENTDRAGGER_JUCEHEADER__
#define __JUCE_COMPONENTDRAGGER_JUCEHEADER__

/********* Start of inlined file: juce_ComponentBoundsConstrainer.h *********/
#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__
#define __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__

/**
    A class that imposes restrictions on a Component's size or position.

    This is used by classes such as ResizableCornerComponent,
    ResizableBorderComponent and ResizableWindow.

    The base class can impose some basic size and position limits, but you can
    also subclass this for custom uses.

    @see ResizableCornerComponent, ResizableBorderComponent, ResizableWindow
*/
class JUCE_API  ComponentBoundsConstrainer
{
public:

    /** When first created, the object will not impose any restrictions on the components. */
    ComponentBoundsConstrainer() throw();

    /** Destructor. */
    virtual ~ComponentBoundsConstrainer();

    /** Imposes a minimum width limit. */
    void setMinimumWidth (const int minimumWidth) throw();

    /** Returns the current minimum width. */
    int getMinimumWidth() const throw()                         { return minW; }

    /** Imposes a maximum width limit. */
    void setMaximumWidth (const int maximumWidth) throw();

    /** Returns the current maximum width. */
    int getMaximumWidth() const throw()                         { return maxW; }

    /** Imposes a minimum height limit. */
    void setMinimumHeight (const int minimumHeight) throw();

    /** Returns the current minimum height. */
    int getMinimumHeight() const throw()                        { return minH; }

    /** Imposes a maximum height limit. */
    void setMaximumHeight (const int maximumHeight) throw();

    /** Returns the current maximum height. */
    int getMaximumHeight() const throw()                        { return maxH; }

    /** Imposes a minimum width and height limit. */
    void setMinimumSize (const int minimumWidth,
                         const int minimumHeight) throw();

    /** Imposes a maximum width and height limit. */
    void setMaximumSize (const int maximumWidth,
                         const int maximumHeight) throw();

    /** Set all the maximum and minimum dimensions. */
    void setSizeLimits (const int minimumWidth,
                        const int minimumHeight,
                        const int maximumWidth,
                        const int maximumHeight) throw();

    /** Sets the amount by which the component is allowed to go off-screen.

        The values indicate how many pixels must remain on-screen when dragged off
        one of its parent's edges, so e.g. if minimumWhenOffTheTop is set to 10, then
        when the component goes off the top of the screen, its y-position will be
        clipped so that there are always at least 10 pixels on-screen. In other words,
        the lowest y-position it can take would be (10 - the component's height).

        If you pass 0 or less for one of these amounts, the component is allowed
        to move beyond that edge completely, with no restrictions at all.

        If you pass a very large number (i.e. larger that the dimensions of the
        component itself), then the component won't be allowed to overlap that
        edge at all. So e.g. setting minimumWhenOffTheLeft to 0xffffff will mean that
        the component will bump into the left side of the screen and go no further.
    */
    void setMinimumOnscreenAmounts (const int minimumWhenOffTheTop,
                                    const int minimumWhenOffTheLeft,
                                    const int minimumWhenOffTheBottom,
                                    const int minimumWhenOffTheRight) throw();

    /** Specifies a width-to-height ratio that the resizer should always maintain.

        If the value is 0, no aspect ratio is enforced. If it's non-zero, the width
        will always be maintained as this multiple of the height.

        @see setResizeLimits
    */
    void setFixedAspectRatio (const double widthOverHeight) throw();

    /** Returns the aspect ratio that was set with setFixedAspectRatio().

        If no aspect ratio is being enforced, this will return 0.
    */
    double getFixedAspectRatio() const throw();

    /** This callback changes the given co-ordinates to impose whatever the current
        constraints are set to be.

        @param x                the x position that should be examined and adjusted
        @param y                the y position that should be examined and adjusted
        @param w                the width that should be examined and adjusted
        @param h                the height that should be examined and adjusted
        @param previousBounds   the component's current size
        @param limits           the region in which the component can be positioned
        @param isStretchingTop      whether the top edge of the component is being resized
        @param isStretchingLeft     whether the left edge of the component is being resized
        @param isStretchingBottom   whether the bottom edge of the component is being resized
        @param isStretchingRight    whether the right edge of the component is being resized
    */
    virtual void checkBounds (int& x, int& y, int& w, int& h,
                              const Rectangle& previousBounds,
                              const Rectangle& limits,
                              const bool isStretchingTop,
                              const bool isStretchingLeft,
                              const bool isStretchingBottom,
                              const bool isStretchingRight);

    /** This callback happens when the resizer is about to start dragging. */
    virtual void resizeStart();

    /** This callback happens when the resizer has finished dragging. */
    virtual void resizeEnd();

    /** Checks the given bounds, and then sets the component to the corrected size. */
    void setBoundsForComponent (Component* const component,
                                int x, int y, int w, int h,
                                const bool isStretchingTop,
                                const bool isStretchingLeft,
                                const bool isStretchingBottom,
                                const bool isStretchingRight);

    /** Performs a check on the current size of a component, and moves or resizes
        it if it fails the constraints.
    */
    void checkComponentBounds (Component* component);

    /** Called by setBoundsForComponent() to apply a new constrained size to a
        component.

        By default this just calls setBounds(), but it virtual in case it's needed for
        extremely cunning purposes.
    */
    virtual void applyBoundsToComponent (Component* component,
                                         int x, int y, int w, int h);

    juce_UseDebuggingNewOperator

private:
    int minW, maxW, minH, maxH;
    int minOffTop, minOffLeft, minOffBottom, minOffRight;
    double aspectRatio;

    ComponentBoundsConstrainer (const ComponentBoundsConstrainer&);
    const ComponentBoundsConstrainer& operator= (const ComponentBoundsConstrainer&);
};

#endif   // __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__
/********* End of inlined file: juce_ComponentBoundsConstrainer.h *********/

/**
    An object to take care of the logic for dragging components around with the mouse.

    Very easy to use - in your mouseDown() callback, call startDraggingComponent(),
    then in your mouseDrag() callback, call dragComponent().

    When starting a drag, you can give it a ComponentBoundsConstrainer to use
    to limit the component's position and keep it on-screen.

    e.g. @code
    class MyDraggableComp
    {
        ComponentDragger myDragger;

        void mouseDown (const MouseEvent& e)
        {
            myDragger.startDraggingComponent (this, 0);
        }

        void mouseDrag (const MouseEvent& e)
        {
            myDragger.dragComponent (this, e);
        }
    };
    @endcode
*/
class JUCE_API  ComponentDragger
{
public:

    /** Creates a ComponentDragger. */
    ComponentDragger();

    /** Destructor. */
    virtual ~ComponentDragger();

    /** Call this from your component's mouseDown() method, to prepare for dragging.

        @param componentToDrag      the component that you want to drag
        @param constrainer          a constrainer object to use to keep the component
                                    from going offscreen
        @see dragComponent
    */
    void startDraggingComponent (Component* const componentToDrag,
                                 ComponentBoundsConstrainer* constrainer);

    /** Call this from your mouseDrag() callback to move the component.

        This will move the component, but will first check the validity of the
        component's new position using the checkPosition() method, which you
        can override if you need to enforce special positioning limits on the
        component.

        @param componentToDrag      the component that you want to drag
        @param e                    the current mouse-drag event
        @see dragComponent
    */
    void dragComponent (Component* const componentToDrag,
                        const MouseEvent& e);

    juce_UseDebuggingNewOperator

private:
    ComponentBoundsConstrainer* constrainer;
    int originalX, originalY;
};

#endif   // __JUCE_COMPONENTDRAGGER_JUCEHEADER__
/********* End of inlined file: juce_ComponentDragger.h *********/

#endif
#ifndef __JUCE_DRAGANDDROPCONTAINER_JUCEHEADER__

#endif
#ifndef __JUCE_DRAGANDDROPTARGET_JUCEHEADER__

#endif
#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__

/********* Start of inlined file: juce_FileDragAndDropTarget.h *********/
#ifndef __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__
#define __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__

/**
    Components derived from this class can have files dropped onto them by an external application.

    @see DragAndDropContainer
*/
class JUCE_API  FileDragAndDropTarget
{
public:
    /** Destructor. */
    virtual ~FileDragAndDropTarget()  {}

    /** Callback to check whether this target is interested in the set of files being offered.

        Note that this will be called repeatedly when the user is dragging the mouse around over your
        component, so don't do anything time-consuming in here, like opening the files to have a look
        inside them!

        @param files        the set of (absolute) pathnames of the files that the user is dragging
        @returns            true if this component wants to receive the other callbacks regarging this
                            type of object; if it returns false, no other callbacks will be made.
    */
    virtual bool isInterestedInFileDrag (const StringArray& files) = 0;

    /** Callback to indicate that some files are being dragged over this component.

        This gets called when the user moves the mouse into this component while dragging.

        Use this callback as a trigger to make your component repaint itself to give the
        user feedback about whether the files can be dropped here or not.

        @param files        the set of (absolute) pathnames of the files that the user is dragging
        @param x            the mouse x position, relative to this component
        @param y            the mouse y position, relative to this component
    */
    virtual void fileDragEnter (const StringArray& files, int x, int y);

    /** Callback to indicate that the user is dragging some files over this component.

        This gets called when the user moves the mouse over this component while dragging.
        Normally overriding itemDragEnter() and itemDragExit() are enough, but
        this lets you know what happens in-between.

        @param files        the set of (absolute) pathnames of the files that the user is dragging
        @param x            the mouse x position, relative to this component
        @param y            the mouse y position, relative to this component
    */
    virtual void fileDragMove (const StringArray& files, int x, int y);

    /** Callback to indicate that the mouse has moved away from this component.

        This gets called when the user moves the mouse out of this component while dragging
        the files.

        If you've used fileDragEnter() to repaint your component and give feedback, use this
        as a signal to repaint it in its normal state.

        @param files        the set of (absolute) pathnames of the files that the user is dragging
    */
    virtual void fileDragExit (const StringArray& files);

    /** Callback to indicate that the user has dropped the files onto this component.

        When the user drops the files, this get called, and you can use the files in whatever
        way is appropriate.

        Note that after this is called, the fileDragExit method may not be called, so you should
        clean up in here if there's anything you need to do when the drag finishes.

        @param files        the set of (absolute) pathnames of the files that the user is dragging
        @param x            the mouse x position, relative to this component
        @param y            the mouse y position, relative to this component
    */
    virtual void filesDropped (const StringArray& files, int x, int y) = 0;
};

#endif   // __JUCE_FILEDRAGANDDROPTARGET_JUCEHEADER__
/********* End of inlined file: juce_FileDragAndDropTarget.h *********/

#endif
#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_LassoComponent.h *********/
#ifndef __JUCE_LASSOCOMPONENT_JUCEHEADER__
#define __JUCE_LASSOCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_SelectedItemSet.h *********/
#ifndef __JUCE_SELECTEDITEMSET_JUCEHEADER__
#define __JUCE_SELECTEDITEMSET_JUCEHEADER__

/** Manages a list of selectable items.

    Use one of these to keep a track of things that the user has highlighted, like
    icons or things in a list.

    The class is templated so that you can use it to hold either a set of pointers
    to objects, or a set of ID numbers or handles, for cases where each item may
    not always have a corresponding object.

    To be informed when items are selected/deselected, register a ChangeListener with
    this object.

    @see SelectableObject
*/
template <class SelectableItemType>
class JUCE_API  SelectedItemSet   : public ChangeBroadcaster
{
public:

    /** Creates an empty set. */
    SelectedItemSet()
    {
    }

    /** Creates a set based on an array of items. */
    SelectedItemSet (const Array <SelectableItemType>& items)
        : selectedItems (items)
    {
    }

    /** Creates a copy of another set. */
    SelectedItemSet (const SelectedItemSet& other)
        : selectedItems (other.selectedItems)
    {
    }

    /** Creates a copy of another set. */
    const SelectedItemSet& operator= (const SelectedItemSet& other)
    {
        if (selectedItems != other.selectedItems)
        {
            selectedItems = other.selectedItems;
            changed();
        }

        return *this;
    }

    /** Destructor. */
    ~SelectedItemSet()
    {
    }

    /** Clears any other currently selected items, and selects this item.

        If this item is already the only thing selected, no change notification
        will be sent out.

        @see addToSelection, addToSelectionBasedOnModifiers
    */
    void selectOnly (SelectableItemType item)
    {
        if (isSelected (item))
        {
            for (int i = selectedItems.size(); --i >= 0;)
            {
                if (selectedItems.getUnchecked(i) != item)
                {
                    deselect (selectedItems.getUnchecked(i));
                    i = jmin (i, selectedItems.size());
                }
            }
        }
        else
        {
            deselectAll();
            changed();

            selectedItems.add (item);
            itemSelected (item);
        }
    }

    /** Selects an item.

        If the item is already selected, no change notification will be sent out.

        @see selectOnly, addToSelectionBasedOnModifiers
    */
    void addToSelection (SelectableItemType item)
    {
        if (! isSelected (item))
        {
            changed();

            selectedItems.add (item);
            itemSelected (item);
        }
    }

    /** Selects or deselects an item.

        This will use the modifier keys to decide whether to deselect other items
        first.

        So if the shift key is held down, the item will be added without deselecting
        anything (same as calling addToSelection() )

        If no modifiers are down, the current selection will be cleared first (same
        as calling selectOnly() )

        If the ctrl (or command on the Mac) key is held down, the item will be toggled -
        so it'll be added to the set unless it's already there, in which case it'll be
        deselected.

        If the items that you're selecting can also be dragged, you may need to use the
        addToSelectionOnMouseDown() and addToSelectionOnMouseUp() calls to handle the
        subtleties of this kind of usage.

        @see selectOnly, addToSelection, addToSelectionOnMouseDown, addToSelectionOnMouseUp
    */
    void addToSelectionBasedOnModifiers (SelectableItemType item,
                                         const ModifierKeys& modifiers)
    {
        if (modifiers.isShiftDown())
        {
            addToSelection (item);
        }
        else if (modifiers.isCommandDown())
        {
            if (isSelected (item))
                deselect (item);
            else
                addToSelection (item);
        }
        else
        {
            selectOnly (item);
        }
    }

    /** Selects or deselects items that can also be dragged, based on a mouse-down event.

        If you call addToSelectionOnMouseDown() at the start of your mouseDown event,
        and then call addToSelectionOnMouseUp() at the end of your mouseUp event, this
        makes it easy to handle multiple-selection of sets of objects that can also
        be dragged.

        For example, if you have several items already selected, and you click on
        one of them (without dragging), then you'd expect this to deselect the other, and
        just select the item you clicked on. But if you had clicked on this item and
        dragged it, you'd have expected them all to stay selected.

        When you call this method, you'll need to store the boolean result, because the
        addToSelectionOnMouseUp() method will need to be know this value.

        @see addToSelectionOnMouseUp, addToSelectionBasedOnModifiers
    */
    bool addToSelectionOnMouseDown (SelectableItemType item,
                                    const ModifierKeys& modifiers)
    {
        if (isSelected (item))
        {
            return ! modifiers.isPopupMenu();
        }
        else
        {
            addToSelectionBasedOnModifiers (item, modifiers);
            return false;
        }
    }

    /** Selects or deselects items that can also be dragged, based on a mouse-up event.

        Call this during a mouseUp callback, when you have previously called the
        addToSelectionOnMouseDown() method during your mouseDown event.

        See addToSelectionOnMouseDown() for more info

        @param item             the item to select (or deselect)
        @param modifiers        the modifiers from the mouse-up event
        @param wasItemDragged   true if your item was dragged during the mouse click
        @param resultOfMouseDownSelectMethod    this is the boolean return value that came
                                back from the addToSelectionOnMouseDown() call that you
                                should have made during the matching mouseDown event
    */
    void addToSelectionOnMouseUp (SelectableItemType item,
                                  const ModifierKeys& modifiers,
                                  const bool wasItemDragged,
                                  const bool resultOfMouseDownSelectMethod)
    {
        if (resultOfMouseDownSelectMethod && ! wasItemDragged)
            addToSelectionBasedOnModifiers (item, modifiers);
    }

    /** Deselects an item. */
    void deselect (SelectableItemType item)
    {
        const int i = selectedItems.indexOf (item);

        if (i >= 0)
        {
            changed();
            itemDeselected (selectedItems.remove (i));
        }
    }

    /** Deselects all items. */
    void deselectAll()
    {
        if (selectedItems.size() > 0)
        {
            changed();

            for (int i = selectedItems.size(); --i >= 0;)
            {
                itemDeselected (selectedItems.remove (i));
                i = jmin (i, selectedItems.size());
            }
        }
    }

    /** Returns the number of currently selected items.

        @see getSelectedItem
    */
    int getNumSelected() const throw()
    {
        return selectedItems.size();
    }

    /** Returns one of the currently selected items.

        Returns 0 if the index is out-of-range.

        @see getNumSelected
    */
    SelectableItemType getSelectedItem (const int index) const throw()
    {
        return selectedItems [index];
    }

    /** True if this item is currently selected. */
    bool isSelected (const SelectableItemType item) const throw()
    {
        return selectedItems.contains (item);
    }

    const Array <SelectableItemType>& getItemArray() const throw()          { return selectedItems; }

    /** Can be overridden to do special handling when an item is selected.

        For example, if the item is an object, you might want to call it and tell
        it that it's being selected.
    */
    virtual void itemSelected (SelectableItemType item)                     {}

    /** Can be overridden to do special handling when an item is deselected.

        For example, if the item is an object, you might want to call it and tell
        it that it's being deselected.
    */
    virtual void itemDeselected (SelectableItemType item)                   {}

    /** Used internally, but can be called to force a change message to be sent to the ChangeListeners.
    */
    void changed (const bool synchronous = false)
    {
        if (synchronous)
            sendSynchronousChangeMessage (this);
        else
            sendChangeMessage (this);
    }

    juce_UseDebuggingNewOperator

private:
    Array <SelectableItemType> selectedItems;
};

#endif   // __JUCE_SELECTEDITEMSET_JUCEHEADER__
/********* End of inlined file: juce_SelectedItemSet.h *********/

/**
    A class used by the LassoComponent to manage the things that it selects.

    This allows the LassoComponent to find out which items are within the lasso,
    and to change the list of selected items.

    @see LassoComponent, SelectedItemSet
*/
template <class SelectableItemType>
class LassoSource
{
public:
    /** Destructor. */
    virtual ~LassoSource() {}

    /** Returns the set of items that lie within a given lassoable region.

        Your implementation of this method must find all the relevent items that lie
        within the given rectangle. and add them to the itemsFound array.

        The co-ordinates are relative to the top-left of the lasso component's parent
        component. (i.e. they are the same as the size and position of the lasso
        component itself).
    */
    virtual void findLassoItemsInArea (Array <SelectableItemType>& itemsFound,
                                       int x, int y, int width, int height) = 0;

    /** Returns the SelectedItemSet that the lasso should update.

        This set will be continuously updated by the LassoComponent as it gets
        dragged around, so make sure that you've got a ChangeListener attached to
        the set so that your UI objects will know when the selection changes and
        be able to update themselves appropriately.
    */
    virtual SelectedItemSet <SelectableItemType>& getLassoSelection() = 0;
};

/**
    A component that acts as a rectangular selection region, which you drag with
    the mouse to select groups of objects (in conjunction with a SelectedItemSet).

    To use one of these:

    - In your mouseDown or mouseDrag event, add the LassoComponent to your parent
      component, and call its beginLasso() method, giving it a
      suitable LassoSource object that it can use to find out which items are in
      the active area.

    - Each time your parent component gets a mouseDrag event, call dragLasso()
      to update the lasso's position - it will use its LassoSource to calculate and
      update the current selection.

    - After the drag has finished and you get a mouseUp callback, you should call
      endLasso() to clean up. This will make the lasso component invisible, and you
      can remove it from the parent component, or delete it.

    The class takes into account the modifier keys that are being held down while
    the lasso is being dragged, so if shift is pressed, then any lassoed items will
    be added to the original selection; if ctrl or command is pressed, they will be
    xor'ed with any previously selected items.

    @see LassoSource, SelectedItemSet
*/
template <class SelectableItemType>
class LassoComponent  : public Component
{
public:

    /** Creates a Lasso component.

        The fill colour is used to fill the lasso'ed rectangle, and the outline
        colour is used to draw a line around its edge.
    */
    LassoComponent (const int outlineThickness_ = 1)
        : source (0),
          outlineThickness (outlineThickness_)
    {
    }

    /** Destructor. */
    ~LassoComponent()
    {
    }

    /** Call this in your mouseDown event, to initialise a drag.

        Pass in a suitable LassoSource object which the lasso will use to find
        the items and change the selection.

        After using this method to initialise the lasso, repeatedly call dragLasso()
        in your component's mouseDrag callback.

        @see dragLasso, endLasso, LassoSource
    */
    void beginLasso (const MouseEvent& e,
                     LassoSource <SelectableItemType>* const lassoSource)
    {
        jassert (source == 0);  // this suggests that you didn't call endLasso() after the last drag...
        jassert (lassoSource != 0); // the source can't be null!
        jassert (getParentComponent() != 0);  // you need to add this to a parent component for it to work!

        source = lassoSource;

        if (lassoSource != 0)
            originalSelection = lassoSource->getLassoSelection().getItemArray();

        setSize (0, 0);
    }

    /** Call this in your mouseDrag event, to update the lasso's position.

        This must be repeatedly calling when the mouse is dragged, after you've
        first initialised the lasso with beginLasso().

        This method takes into account the modifier keys that are being held down, so
        if shift is pressed, then the lassoed items will be added to any that were
        previously selected; if ctrl or command is pressed, then they will be xor'ed
        with previously selected items.

        @see beginLasso, endLasso
    */
    void dragLasso (const MouseEvent& e)
    {
        if (source != 0)
        {
            const int x1 = e.getMouseDownX();
            const int y1 = e.getMouseDownY();

            setBounds (jmin (x1, e.x), jmin (y1, e.y), abs (e.x - x1), abs (e.y - y1));
            setVisible (true);

            Array <SelectableItemType> itemsInLasso;
            source->findLassoItemsInArea (itemsInLasso, getX(), getY(), getWidth(), getHeight());

            if (e.mods.isShiftDown())
            {
                itemsInLasso.removeValuesIn (originalSelection); //  to avoid duplicates
                itemsInLasso.addArray (originalSelection);
            }
            else if (e.mods.isCommandDown() || e.mods.isAltDown())
            {
                Array <SelectableItemType> originalMinusNew (originalSelection);
                originalMinusNew.removeValuesIn (itemsInLasso);

                itemsInLasso.removeValuesIn (originalSelection);
                itemsInLasso.addArray (originalMinusNew);
            }

            source->getLassoSelection() = SelectedItemSet <SelectableItemType> (itemsInLasso);
        }
    }

    /** Call this in your mouseUp event, after the lasso has been dragged.

        @see beginLasso, dragLasso
    */
    void endLasso()
    {
        source = 0;
        originalSelection.clear();
        setVisible (false);
    }

    /** A set of colour IDs to use to change the colour of various aspects of the label.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        Note that you can also use the constants from TextEditor::ColourIds to change the
        colour of the text editor that is opened when a label is editable.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        lassoFillColourId       = 0x1000440, /**< The colour to fill the lasso rectangle with. */
        lassoOutlineColourId    = 0x1000441, /**< The colour to draw the outline with. */
    };

    /** @internal */
    void paint (Graphics& g)
    {
        g.fillAll (findColour (lassoFillColourId));

        g.setColour (findColour (lassoOutlineColourId));
        g.drawRect (0, 0, getWidth(), getHeight(), outlineThickness);

        // this suggests that you've left a lasso comp lying around after the
        // mouse drag has finished.. Be careful to call endLasso() when you get a
        // mouse-up event.
        jassert (isMouseButtonDownAnywhere());
    }

    /** @internal */
    bool hitTest (int x, int y)         { return false; }

    juce_UseDebuggingNewOperator

private:
    Array <SelectableItemType> originalSelection;
    LassoSource <SelectableItemType>* source;
    int outlineThickness;
};

#endif   // __JUCE_LASSOCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_LassoComponent.h *********/

#endif
#ifndef __JUCE_MOUSECURSOR_JUCEHEADER__

#endif
#ifndef __JUCE_MOUSEEVENT_JUCEHEADER__

#endif
#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__

/********* Start of inlined file: juce_MouseHoverDetector.h *********/
#ifndef __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__
#define __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__

/**
    Monitors a component for mouse activity, and triggers a callback
    when the mouse hovers in one place for a specified length of time.

    To use a hover-detector, just create one and call its setHoverComponent()
    method to start it watching a component. You can call setHoverComponent (0)
    to make it inactive.

    (Be careful not to delete a component that's being monitored without first
    stopping or deleting the hover detector).
*/
class JUCE_API  MouseHoverDetector
{
public:

    /** Creates a hover detector.

        Initially the object is inactive, and you need to tell it which component
        to monitor, using the setHoverComponent() method.

        @param hoverTimeMillisecs   the number of milliseconds for which the mouse
                                    needs to stay still before the mouseHovered() method
                                    is invoked. You can change this setting later with
                                    the setHoverTimeMillisecs() method
    */
    MouseHoverDetector (const int hoverTimeMillisecs = 400);

    /** Destructor. */
    virtual ~MouseHoverDetector();

    /** Changes the time for which the mouse has to stay still before it's considered
        to be hovering.
    */
    void setHoverTimeMillisecs (const int newTimeInMillisecs);

    /** Changes the component that's being monitored for hovering.

        Be careful not to delete a component that's being monitored without first
        stopping or deleting the hover detector.
    */
    void setHoverComponent (Component* const newSourceComponent);

protected:

    /** Called back when the mouse hovers.

        After the mouse has stayed still over the component for the length of time
        specified by setHoverTimeMillisecs(), this method will be invoked.

        When the mouse is first moved after this callback has occurred, the
        mouseMovedAfterHover() method will be called.

        @param mouseX   the mouse's X position relative to the component being monitored
        @param mouseY   the mouse's Y position relative to the component being monitored
    */
    virtual void mouseHovered (int mouseX,
                               int mouseY) = 0;

    /** Called when the mouse is moved away after just having hovered. */
    virtual void mouseMovedAfterHover() = 0;

private:

    class JUCE_API  HoverDetectorInternal  : public MouseListener,
                                             public Timer
    {
    public:
        MouseHoverDetector* owner;
        int lastX, lastY;

        void timerCallback();
        void mouseEnter (const MouseEvent&);
        void mouseExit (const MouseEvent&);
        void mouseDown (const MouseEvent&);
        void mouseUp (const MouseEvent&);
        void mouseMove (const MouseEvent&);
        void mouseWheelMove (const MouseEvent&, float, float);

    } internalTimer;

    friend class HoverDetectorInternal;

    Component* source;
    int hoverTimeMillisecs;
    bool hasJustHovered;

    void hoverTimerCallback();
    void checkJustHoveredCallback();
};

#endif   // __JUCE_MOUSEHOVERDETECTOR_JUCEHEADER__
/********* End of inlined file: juce_MouseHoverDetector.h *********/

#endif
#ifndef __JUCE_MOUSELISTENER_JUCEHEADER__

#endif
#ifndef __JUCE_TOOLTIPCLIENT_JUCEHEADER__

#endif
#ifndef __JUCE_LABEL_JUCEHEADER__

#endif
#ifndef __JUCE_PROGRESSBAR_JUCEHEADER__

/********* Start of inlined file: juce_ProgressBar.h *********/
#ifndef __JUCE_PROGRESSBAR_JUCEHEADER__
#define __JUCE_PROGRESSBAR_JUCEHEADER__

/**
    A progress bar component.

    To use this, just create one and make it visible. It'll run its own timer
    to keep an eye on a variable that you give it, and will automatically
    redraw itself when the variable changes.

    For an easy way of running a background task with a dialog box showing its
    progress, see the ThreadWithProgressWindow class.

    @see ThreadWithProgressWindow
*/
class JUCE_API  ProgressBar  : public Component,
                               public SettableTooltipClient,
                               private Timer
{
public:

    /** Creates a ProgressBar.

        @param progress     pass in a reference to a double that you're going to
                            update with your task's progress. The ProgressBar will
                            monitor the value of this variable and will redraw itself
                            when the value changes. The range is from 0 to 1.0. Obviously
                            you'd better be careful not to delete this variable while the
                            ProgressBar still exists!
    */
    ProgressBar (double& progress);

    /** Destructor. */
    ~ProgressBar();

    /** Turns the percentage display on or off.

        By default this is on, and the progress bar will display a text string showing
        its current percentage.
    */
    void setPercentageDisplay (const bool shouldDisplayPercentage);

    /** Gives the progress bar a string to display inside it.

        If you call this, it will turn off the percentage display.
        @see setPercentageDisplay
    */
    void setTextToDisplay (const String& text);

    /** A set of colour IDs to use to change the colour of various aspects of the bar.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId              = 0x1001900,    /**< The background colour, behind the bar. */
        foregroundColourId              = 0x1001a00,    /**< The colour to use to draw the bar itself. LookAndFeel
                                                             classes will probably use variations on this colour. */
    };

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void lookAndFeelChanged();
    /** @internal */
    void visibilityChanged();
    /** @internal */
    void colourChanged();

private:
    double& progress;
    double currentValue;
    bool displayPercentage;
    String displayedMessage, currentMessage;
    uint32 lastCallbackTime;

    void timerCallback();

    ProgressBar (const ProgressBar&);
    const ProgressBar& operator= (const ProgressBar&);
};

#endif   // __JUCE_PROGRESSBAR_JUCEHEADER__
/********* End of inlined file: juce_ProgressBar.h *********/

#endif
#ifndef __JUCE_SLIDER_JUCEHEADER__

/********* Start of inlined file: juce_Slider.h *********/
#ifndef __JUCE_SLIDER_JUCEHEADER__
#define __JUCE_SLIDER_JUCEHEADER__

/********* Start of inlined file: juce_SliderListener.h *********/
#ifndef __JUCE_SLIDERLISTENER_JUCEHEADER__
#define __JUCE_SLIDERLISTENER_JUCEHEADER__

class Slider;

/**
    A class for receiving callbacks from a Slider.

    To be told when a slider's value changes, you can register a SliderListener
    object using Slider::addListener().

    @see Slider::addListener, Slider::removeListener
*/
class JUCE_API  SliderListener
{
public:

    /** Destructor. */
    virtual ~SliderListener() {}

    /** Called when the slider's value is changed.

        This may be caused by dragging it, or by typing in its text entry box,
        or by a call to Slider::setValue().

        You can find out the new value using Slider::getValue().

        @see Slider::valueChanged
    */
    virtual void sliderValueChanged (Slider* slider) = 0;

    /** Called when the slider is about to be dragged.

        This is called when a drag begins, then it's followed by multiple calls
        to sliderValueChanged(), and then sliderDragEnded() is called after the
        user lets go.

        @see sliderDragEnded, Slider::startedDragging
    */
    virtual void sliderDragStarted (Slider* slider);

    /** Called after a drag operation has finished.

        @see sliderDragStarted, Slider::stoppedDragging
    */
    virtual void sliderDragEnded (Slider* slider);
};

#endif   // __JUCE_SLIDERLISTENER_JUCEHEADER__
/********* End of inlined file: juce_SliderListener.h *********/

/**
    A slider control for changing a value.

    The slider can be horizontal, vertical, or rotary, and can optionally have
    a text-box inside it to show an editable display of the current value.

    To use it, create a Slider object and use the setSliderStyle() method
    to set up the type you want. To set up the text-entry box, use setTextBoxStyle().

    To define the values that it can be set to, see the setRange() and setValue() methods.

    There are also lots of custom tweaks you can do by subclassing and overriding
    some of the virtual methods, such as changing the scaling, changing the format of
    the text display, custom ways of limiting the values, etc.

    You can register SliderListeners with a slider, which will be informed when the value
    changes, or a subclass can override valueChanged() to be informed synchronously.

    @see SliderListener
*/
class JUCE_API  Slider  : public Component,
                          public SettableTooltipClient,
                          private AsyncUpdater,
                          private ButtonListener,
                          private LabelListener
{
public:

    /** Creates a slider.

        When created, you'll need to set up the slider's style and range with setSliderStyle(),
        setRange(), etc.
    */
    Slider (const String& componentName);

    /** Destructor. */
    ~Slider();

    /** The types of slider available.

        @see setSliderStyle, setRotaryParameters
    */
    enum SliderStyle
    {
        LinearHorizontal,       /**< A traditional horizontal slider. */
        LinearVertical,         /**< A traditional vertical slider. */
        LinearBar,              /**< A horizontal bar slider with the text label drawn on top of it. */
        Rotary,                 /**< A rotary control that you move by dragging the mouse in a circular motion, like a knob.
                                     @see setRotaryParameters */
        RotaryHorizontalDrag,   /**< A rotary control that you move by dragging the mouse left-to-right.
                                     @see setRotaryParameters */
        RotaryVerticalDrag,     /**< A rotary control that you move by dragging the mouse up-and-down.
                                     @see setRotaryParameters */
        IncDecButtons,          /**< A pair of buttons that increment or decrement the slider's value by the increment set in setRange(). */

        TwoValueHorizontal,     /**< A horizontal slider that has two thumbs instead of one, so it can show a minimum and maximum value.
                                     @see setMinValue, setMaxValue */
        TwoValueVertical,       /**< A vertical slider that has two thumbs instead of one, so it can show a minimum and maximum value.
                                     @see setMinValue, setMaxValue */

        ThreeValueHorizontal,   /**< A horizontal slider that has three thumbs instead of one, so it can show a minimum and maximum
                                     value, with the current value being somewhere between them.
                                     @see setMinValue, setMaxValue */
        ThreeValueVertical,     /**< A vertical slider that has three thumbs instead of one, so it can show a minimum and maximum
                                     value, with the current value being somewhere between them.
                                     @see setMinValue, setMaxValue */
    };

    /** Changes the type of slider interface being used.

        @param newStyle         the type of interface
        @see setRotaryParameters, setVelocityBasedMode,
    */
    void setSliderStyle (const SliderStyle newStyle);

    /** Returns the slider's current style.

        @see setSliderStyle
    */
    SliderStyle getSliderStyle() const throw()                                  { return style; }

    /** Changes the properties of a rotary slider.

        @param startAngleRadians        the angle (in radians, clockwise from the top) at which
                                        the slider's minimum value is represented
        @param endAngleRadians          the angle (in radians, clockwise from the top) at which
                                        the slider's maximum value is represented. This must be
                                        greater than startAngleRadians
        @param stopAtEnd                if true, then when the slider is dragged around past the
                                        minimum or maximum, it'll stop there; if false, it'll wrap
                                        back to the opposite value
    */
    void setRotaryParameters (const float startAngleRadians,
                              const float endAngleRadians,
                              const bool stopAtEnd);

    /** Sets the distance the mouse has to move to drag the slider across
        the full extent of its range.

        This only applies when in modes like RotaryHorizontalDrag, where it's using
        relative mouse movements to adjust the slider.
    */
    void setMouseDragSensitivity (const int distanceForFullScaleDrag);

    /** Changes the way the the mouse is used when dragging the slider.

        If true, this will turn on velocity-sensitive dragging, so that
        the faster the mouse moves, the bigger the movement to the slider. This
        helps when making accurate adjustments if the slider's range is quite large.

        If false, the slider will just try to snap to wherever the mouse is.
    */
    void setVelocityBasedMode (const bool isVelocityBased) throw();

    /** Changes aspects of the scaling used when in velocity-sensitive mode.

        These apply when you've used setVelocityBasedMode() to turn on velocity mode,
        or if you're holding down ctrl.

        @param sensitivity      higher values than 1.0 increase the range of acceleration used
        @param threshold        the minimum number of pixels that the mouse needs to move for it
                                to be treated as a movement
        @param offset           values greater than 0.0 increase the minimum speed that will be used when
                                the threshold is reached
        @param userCanPressKeyToSwapMode    if true, then the user can hold down the ctrl or command
                                key to toggle velocity-sensitive mode
    */
    void setVelocityModeParameters (const double sensitivity = 1.0,
                                    const int threshold = 1,
                                    const double offset = 0.0,
                                    const bool userCanPressKeyToSwapMode = true) throw();

    /** Sets up a skew factor to alter the way values are distributed.

        You may want to use a range of values on the slider where more accuracy
        is required towards one end of the range, so this will logarithmically
        spread the values across the length of the slider.

        If the factor is < 1.0, the lower end of the range will fill more of the
        slider's length; if the factor is > 1.0, the upper end of the range
        will be expanded instead. A factor of 1.0 doesn't skew it at all.

        To set the skew position by using a mid-point, use the setSkewFactorFromMidPoint()
        method instead.

        @see getSkewFactor, setSkewFactorFromMidPoint
    */
    void setSkewFactor (const double factor) throw();

    /** Sets up a skew factor to alter the way values are distributed.

        This allows you to specify the slider value that should appear in the
        centre of the slider's visible range.

        @see setSkewFactor, getSkewFactor
     */
    void setSkewFactorFromMidPoint (const double sliderValueToShowAtMidPoint) throw();

    /** Returns the current skew factor.

        See setSkewFactor for more info.

        @see setSkewFactor, setSkewFactorFromMidPoint
    */
    double getSkewFactor() const throw()                        { return skewFactor; }

    /** Used by setIncDecButtonsMode().
    */
    enum IncDecButtonMode
    {
        incDecButtonsNotDraggable,
        incDecButtonsDraggable_AutoDirection,
        incDecButtonsDraggable_Horizontal,
        incDecButtonsDraggable_Vertical
    };

    /** When the style is IncDecButtons, this lets you turn on a mode where the mouse
        can be dragged on the buttons to drag the values.

        By default this is turned off. When enabled, clicking on the buttons still works
        them as normal, but by holding down the mouse on a button and dragging it a little
        distance, it flips into a mode where the value can be dragged. The drag direction can
        either be set explicitly to be vertical or horizontal, or can be set to
        incDecButtonsDraggable_AutoDirection so that it depends on whether the buttons
        are side-by-side or above each other.
    */
    void setIncDecButtonsMode (const IncDecButtonMode mode);

    /** The position of the slider's text-entry box.

        @see setTextBoxStyle
    */
    enum TextEntryBoxPosition
    {
        NoTextBox,              /**< Doesn't display a text box.  */
        TextBoxLeft,            /**< Puts the text box to the left of the slider, vertically centred.  */
        TextBoxRight,           /**< Puts the text box to the right of the slider, vertically centred.  */
        TextBoxAbove,           /**< Puts the text box above the slider, horizontally centred.  */
        TextBoxBelow            /**< Puts the text box below the slider, horizontally centred.  */
    };

    /** Changes the location and properties of the text-entry box.

        @param newPosition          where it should go (or NoTextBox to not have one at all)
        @param isReadOnly           if true, it's a read-only display
        @param textEntryBoxWidth    the width of the text-box in pixels. Make sure this leaves enough
                                    room for the slider as well!
        @param textEntryBoxHeight   the height of the text-box in pixels. Make sure this leaves enough
                                    room for the slider as well!

        @see setTextBoxIsEditable, getValueFromText, getTextFromValue
    */
    void setTextBoxStyle (const TextEntryBoxPosition newPosition,
                          const bool isReadOnly,
                          const int textEntryBoxWidth,
                          const int textEntryBoxHeight);

    /** Returns the status of the text-box.
        @see setTextBoxStyle
    */
    const TextEntryBoxPosition getTextBoxPosition() const throw()           { return textBoxPos; }

    /** Returns the width used for the text-box.
        @see setTextBoxStyle
    */
    int getTextBoxWidth() const throw()                                     { return textBoxWidth; }

    /** Returns the height used for the text-box.
        @see setTextBoxStyle
    */
    int getTextBoxHeight() const throw()                                    { return textBoxHeight; }

    /** Makes the text-box editable.

        By default this is true, and the user can enter values into the textbox,
        but it can be turned off if that's not suitable.

        @see setTextBoxStyle, getValueFromText, getTextFromValue
    */
    void setTextBoxIsEditable (const bool shouldBeEditable) throw();

    /** Returns true if the text-box is read-only.
        @see setTextBoxStyle
    */
    bool isTextBoxEditable() const throw()                                  { return editableText; }

    /** If the text-box is editable, this will give it the focus so that the user can
        type directly into it.

        This is basically the effect as the user clicking on it.
    */
    void showTextBox();

    /** If the text-box currently has focus and is being edited, this resets it and takes keyboard
        focus away from it.

        @param discardCurrentEditorContents     if true, the slider's value will be left
                                                unchanged; if false, the current contents of the
                                                text editor will be used to set the slider position
                                                before it is hidden.
    */
    void hideTextBox (const bool discardCurrentEditorContents);

    /** Changes the slider's current value.

        This will trigger a callback to SliderListener::sliderValueChanged() for any listeners
        that are registered, and will synchronously call the valueChanged() method in case subclasses
        want to handle it.

        @param newValue                 the new value to set - this will be restricted by the
                                        minimum and maximum range, and will be snapped to the
                                        nearest interval if one has been set
        @param sendUpdateMessage        if false, a change to the value will not trigger a call to
                                        any SliderListeners or the valueChanged() method
        @param sendMessageSynchronously if true, then a call to the SliderListeners will be made
                                        synchronously; if false, it will be asynchronous
    */
    void setValue (double newValue,
                   const bool sendUpdateMessage = true,
                   const bool sendMessageSynchronously = false);

    /** Returns the slider's current value. */
    double getValue() const throw();

    /** Sets the limits that the slider's value can take.

        @param newMinimum   the lowest value allowed
        @param newMaximum   the highest value allowed
        @param newInterval  the steps in which the value is allowed to increase - if this
                            is not zero, the value will always be (newMinimum + (newInterval * an integer)).
    */
    void setRange (const double newMinimum,
                   const double newMaximum,
                   const double newInterval = 0);

    /** Returns the current maximum value.
        @see setRange
    */
    double getMaximum() const throw()                                       { return maximum; }

    /** Returns the current minimum value.
        @see setRange
    */
    double getMinimum() const throw()                                       { return minimum; }

    /** Returns the current step-size for values.
        @see setRange
    */
    double getInterval() const throw()                                      { return interval; }

    /** For a slider with two or three thumbs, this returns the lower of its values.

        For a two-value slider, the values are controlled with getMinValue() and getMaxValue().
        A slider with three values also uses the normal getValue() and setValue() methods to
        control the middle value.

        @see setMinValue, getMaxValue, TwoValueHorizontal, TwoValueVertical, ThreeValueHorizontal, ThreeValueVertical
    */
    double getMinValue() const throw();

    /** For a slider with two or three thumbs, this sets the lower of its values.

        This will trigger a callback to SliderListener::sliderValueChanged() for any listeners
        that are registered, and will synchronously call the valueChanged() method in case subclasses
        want to handle it.

        @param newValue                 the new value to set - this will be restricted by the
                                        minimum and maximum range, and will be snapped to the nearest
                                        interval if one has been set.
        @param sendUpdateMessage        if false, a change to the value will not trigger a call to
                                        any SliderListeners or the valueChanged() method
        @param sendMessageSynchronously if true, then a call to the SliderListeners will be made
                                        synchronously; if false, it will be asynchronous
        @param allowNudgingOfOtherValues  if false, this value will be restricted to being below the
                                        max value (in a two-value slider) or the mid value (in a three-value
                                        slider). If false, then if this value goes beyond those values,
                                        it will push them along with it.
        @see getMinValue, setMaxValue, setValue
    */
    void setMinValue (double newValue,
                      const bool sendUpdateMessage = true,
                      const bool sendMessageSynchronously = false,
                      const bool allowNudgingOfOtherValues = false);

    /** For a slider with two or three thumbs, this returns the higher of its values.

        For a two-value slider, the values are controlled with getMinValue() and getMaxValue().
        A slider with three values also uses the normal getValue() and setValue() methods to
        control the middle value.

        @see getMinValue, TwoValueHorizontal, TwoValueVertical, ThreeValueHorizontal, ThreeValueVertical
    */
    double getMaxValue() const throw();

    /** For a slider with two or three thumbs, this sets the lower of its values.

        This will trigger a callback to SliderListener::sliderValueChanged() for any listeners
        that are registered, and will synchronously call the valueChanged() method in case subclasses
        want to handle it.

        @param newValue                 the new value to set - this will be restricted by the
                                        minimum and maximum range, and will be snapped to the nearest
                                        interval if one has been set.
        @param sendUpdateMessage        if false, a change to the value will not trigger a call to
                                        any SliderListeners or the valueChanged() method
        @param sendMessageSynchronously if true, then a call to the SliderListeners will be made
                                        synchronously; if false, it will be asynchronous
        @param allowNudgingOfOtherValues  if false, this value will be restricted to being above the
                                        min value (in a two-value slider) or the mid value (in a three-value
                                        slider). If false, then if this value goes beyond those values,
                                        it will push them along with it.
        @see getMaxValue, setMinValue, setValue
    */
    void setMaxValue (double newValue,
                      const bool sendUpdateMessage = true,
                      const bool sendMessageSynchronously = false,
                      const bool allowNudgingOfOtherValues = false);

    /** Adds a listener to be called when this slider's value changes. */
    void addListener (SliderListener* const listener) throw();

    /** Removes a previously-registered listener. */
    void removeListener (SliderListener* const listener) throw();

    /** This lets you choose whether double-clicking moves the slider to a given position.

        By default this is turned off, but it's handy if you want a double-click to act
        as a quick way of resetting a slider. Just pass in the value you want it to
        go to when double-clicked.

        @see getDoubleClickReturnValue
    */
    void setDoubleClickReturnValue (const bool isDoubleClickEnabled,
                                    const double valueToSetOnDoubleClick) throw();

    /** Returns the values last set by setDoubleClickReturnValue() method.

        Sets isEnabled to true if double-click is enabled, and returns the value
        that was set.

        @see setDoubleClickReturnValue
    */
    double getDoubleClickReturnValue (bool& isEnabled) const throw();

    /** Tells the slider whether to keep sending change messages while the user
        is dragging the slider.

        If set to true, a change message will only be sent when the user has
        dragged the slider and let go. If set to false (the default), then messages
        will be continuously sent as they drag it while the mouse button is still
        held down.
    */
    void setChangeNotificationOnlyOnRelease (const bool onlyNotifyOnRelease) throw();

    /** This lets you change whether the slider thumb jumps to the mouse position
        when you click.

        By default, this is true. If it's false, then the slider moves with relative
        motion when you drag it.

        This only applies to linear bars, and won't affect two- or three- value
        sliders.
    */
    void setSliderSnapsToMousePosition (const bool shouldSnapToMouse) throw();

    /** If enabled, this gives the slider a pop-up bubble which appears while the
        slider is being dragged.

        This can be handy if your slider doesn't have a text-box, so that users can
        see the value just when they're changing it.

        If you pass a component as the parentComponentToUse parameter, the pop-up
        bubble will be added as a child of that component when it's needed. If you
        pass 0, the pop-up will be placed on the desktop instead (note that it's a
        transparent window, so if you're using an OS that can't do transparent windows
        you'll have to add it to a parent component instead).
    */
    void setPopupDisplayEnabled (const bool isEnabled,
                                 Component* const parentComponentToUse) throw();

    /** If this is set to true, then right-clicking on the slider will pop-up
        a menu to let the user change the way it works.

        By default this is turned off, but when turned on, the menu will include
        things like velocity sensitivity, and for rotary sliders, whether they
        use a linear or rotary mouse-drag to move them.
    */
    void setPopupMenuEnabled (const bool menuEnabled) throw();

    /** This can be used to stop the mouse scroll-wheel from moving the slider.

        By default it's enabled.
    */
    void setScrollWheelEnabled (const bool enabled) throw();

    /** Returns a number to indicate which thumb is currently being dragged by the
        mouse.

        This will return 0 for the main thumb, 1 for the minimum-value thumb, 2 for
        the maximum-value thumb, or -1 if none is currently down.
    */
    int getThumbBeingDragged() const throw()        { return sliderBeingDragged; }

    /** Callback to indicate that the user is about to start dragging the slider.

        @see SliderListener::sliderDragStarted
    */
    virtual void startedDragging();

    /** Callback to indicate that the user has just stopped dragging the slider.

        @see SliderListener::sliderDragEnded
    */
    virtual void stoppedDragging();

    /** Callback to indicate that the user has just moved the slider.

        @see SliderListener::sliderValueChanged
    */
    virtual void valueChanged();

    /** Callback to indicate that the user has just moved the slider.
        Note - the valueChanged() method has changed its format and now no longer has
        any parameters. Update your code to use the new version.
        This version has been left here with an int as its return value to cause
        a syntax error if you've got existing code that uses the old version.
    */
    virtual int valueChanged (double) { jassertfalse; return 0; }

    /** Subclasses can override this to convert a text string to a value.

        When the user enters something into the text-entry box, this method is
        called to convert it to a value.

        The default routine just tries to convert it to a double.

        @see getTextFromValue
    */
    virtual double getValueFromText (const String& text);

    /** Turns the slider's current value into a text string.

        Subclasses can override this to customise the formatting of the text-entry box.

        The default implementation just turns the value into a string, using
        a number of decimal places based on the range interval. If a suffix string
        has been set using setTextValueSuffix(), this will be appended to the text.

        @see getValueFromText
    */
    virtual const String getTextFromValue (double value);

    /** Sets a suffix to append to the end of the numeric value when it's displayed as
        a string.

        This is used by the default implementation of getTextFromValue(), and is just
        appended to the numeric value. For more advanced formatting, you can override
        getTextFromValue() and do something else.
    */
    void setTextValueSuffix (const String& suffix);

    /** Allows a user-defined mapping of distance along the slider to its value.

        The default implementation for this performs the skewing operation that
        can be set up in the setSkewFactor() method. Override it if you need
        some kind of custom mapping instead, but make sure you also implement the
        inverse function in valueToProportionOfLength().

        @param proportion       a value 0 to 1.0, indicating a distance along the slider
        @returns                the slider value that is represented by this position
        @see valueToProportionOfLength
    */
    virtual double proportionOfLengthToValue (double proportion);

    /** Allows a user-defined mapping of value to the position of the slider along its length.

        The default implementation for this performs the skewing operation that
        can be set up in the setSkewFactor() method. Override it if you need
        some kind of custom mapping instead, but make sure you also implement the
        inverse function in proportionOfLengthToValue().

        @param value            a valid slider value, between the range of values specified in
                                setRange()
        @returns                a value 0 to 1.0 indicating the distance along the slider that
                                represents this value
        @see proportionOfLengthToValue
    */
    virtual double valueToProportionOfLength (double value);

    /** Returns the X or Y coordinate of a value along the slider's length.

        If the slider is horizontal, this will be the X coordinate of the given
        value, relative to the left of the slider. If it's vertical, then this will
        be the Y coordinate, relative to the top of the slider.

        If the slider is rotary, this will throw an assertion and return 0. If the
        value is out-of-range, it will be constrained to the length of the slider.
    */
    float getPositionOfValue (const double value);

    /** This can be overridden to allow the slider to snap to user-definable values.

        If overridden, it will be called when the user tries to move the slider to
        a given position, and allows a subclass to sanity-check this value, possibly
        returning a different value to use instead.

        @param attemptedValue       the value the user is trying to enter
        @param userIsDragging       true if the user is dragging with the mouse; false if
                                    they are entering the value using the text box
        @returns                    the value to use instead
    */
    virtual double snapValue (double attemptedValue, const bool userIsDragging);

    /** This can be called to force the text box to update its contents.

        (Not normally needed, as this is done automatically).
    */
    void updateText();

    /** True if the slider moves horizontally. */
    bool isHorizontal() const throw();
    /** True if the slider moves vertically. */
    bool isVertical() const throw();

    /** A set of colour IDs to use to change the colour of various aspects of the slider.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId          = 0x1001200,  /**< A colour to use to fill the slider's background. */
        thumbColourId               = 0x1001300,  /**< The colour to draw the thumb with. It's up to the look
                                                       and feel class how this is used. */
        trackColourId               = 0x1001310,  /**< The colour to draw the groove that the thumb moves along. */
        rotarySliderFillColourId    = 0x1001311,  /**< For rotary sliders, this colour fills the outer curve. */
        rotarySliderOutlineColourId = 0x1001312,  /**< For rotary sliders, this colour is used to draw the outer curve's outline. */

        textBoxTextColourId         = 0x1001400,  /**< The colour for the text in the text-editor box used for editing the value. */
        textBoxBackgroundColourId   = 0x1001500,  /**< The background colour for the text-editor box. */
        textBoxHighlightColourId    = 0x1001600,  /**< The text highlight colour for the text-editor box. */
        textBoxOutlineColourId      = 0x1001700   /**< The colour to use for a border around the text-editor box. */
    };

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void labelTextChanged (Label*);
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseUp (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    void mouseDoubleClick (const MouseEvent& e);
    /** @internal */
    void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
    /** @internal */
    void modifierKeysChanged (const ModifierKeys& modifiers);
    /** @internal */
    void buttonClicked (Button* button);
    /** @internal */
    void lookAndFeelChanged();
    /** @internal */
    void enablementChanged();
    /** @internal */
    void focusOfChildComponentChanged (FocusChangeType cause);
    /** @internal */
    void handleAsyncUpdate();
    /** @internal */
    void colourChanged();

private:
    SortedSet <void*> listeners;
    double currentValue, valueMin, valueMax;
    double minimum, maximum, interval, doubleClickReturnValue;
    double valueWhenLastDragged, valueOnMouseDown, skewFactor, lastAngle;
    double velocityModeSensitivity, velocityModeOffset, minMaxDiff;
    int velocityModeThreshold;
    float rotaryStart, rotaryEnd;
    int numDecimalPlaces, mouseXWhenLastDragged, mouseYWhenLastDragged;
    int mouseDragStartX, mouseDragStartY;
    int sliderRegionStart, sliderRegionSize;
    int sliderBeingDragged;
    int pixelsForFullDragExtent;
    Rectangle sliderRect;
    String textSuffix;

    SliderStyle style;
    TextEntryBoxPosition textBoxPos;
    int textBoxWidth, textBoxHeight;
    IncDecButtonMode incDecButtonMode;

    bool editableText : 1, doubleClickToValue : 1;
    bool isVelocityBased : 1, userKeyOverridesVelocity : 1, rotaryStop : 1;
    bool incDecButtonsSideBySide : 1, sendChangeOnlyOnRelease : 1, popupDisplayEnabled : 1;
    bool menuEnabled : 1, menuShown : 1, mouseWasHidden : 1, incDecDragged : 1;
    bool scrollWheelEnabled : 1, snapsToMousePos : 1;
    Font font;
    Label* valueBox;
    Button* incButton;
    Button* decButton;
    Component* popupDisplay;
    Component* parentForPopupDisplay;

    float getLinearSliderPos (const double value);
    void restoreMouseIfHidden();
    void sendDragStart();
    void sendDragEnd();
    double constrainedValue (double value) const throw();
    void triggerChangeMessage (const bool synchronous);
    bool incDecDragDirectionIsHorizontal() const throw();

    Slider (const Slider&);
    const Slider& operator= (const Slider&);
};

#endif   // __JUCE_SLIDER_JUCEHEADER__
/********* End of inlined file: juce_Slider.h *********/

#endif
#ifndef __JUCE_SLIDERLISTENER_JUCEHEADER__

#endif
#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_TableHeaderComponent.h *********/
#ifndef __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__
#define __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__

class TableHeaderComponent;

/**
    Receives events from a TableHeaderComponent when columns are resized, moved, etc.

    You can register one of these objects for table events using TableHeaderComponent::addListener()
    and TableHeaderComponent::removeListener().

    @see TableHeaderComponent
*/
class JUCE_API  TableHeaderListener
{
public:

    TableHeaderListener() {}

    /** Destructor. */
    virtual ~TableHeaderListener() {}

    /** This is called when some of the table's columns are added, removed, hidden,
        or rearranged.
    */
    virtual void tableColumnsChanged (TableHeaderComponent* tableHeader) = 0;

    /** This is called when one or more of the table's columns are resized.
    */
    virtual void tableColumnsResized (TableHeaderComponent* tableHeader) = 0;

    /** This is called when the column by which the table should be sorted is changed.
    */
    virtual void tableSortOrderChanged (TableHeaderComponent* tableHeader) = 0;

    /** This is called when the user begins or ends dragging one of the columns around.

        When the user starts dragging a column, this is called with the ID of that
        column. When they finish dragging, it is called again with 0 as the ID.
    */
    virtual void tableColumnDraggingChanged (TableHeaderComponent* tableHeader,
                                             int columnIdNowBeingDragged);
};

/**
    A component that displays a strip of column headings for a table, and allows these
    to be resized, dragged around, etc.

    This is just the component that goes at the top of a table. You can use it
    directly for custom components, or to create a simple table, use the
    TableListBox class.

    To use one of these, create it and use addColumn() to add all the columns that you need.
    Each column must be given a unique ID number that's used to refer to it.

    @see TableListBox, TableHeaderListener
*/
class JUCE_API  TableHeaderComponent   : public Component,
                                         private AsyncUpdater
{
public:

    /** Creates an empty table header.
    */
    TableHeaderComponent();

    /** Destructor. */
    ~TableHeaderComponent();

    /** A combination of these flags are passed into the addColumn() method to specify
        the properties of a column.
    */
    enum ColumnPropertyFlags
    {
        visible                     = 1,    /**< If this is set, the column will be shown; if not, it will be hidden until the user enables it with the pop-up menu. */
        resizable                   = 2,    /**< If this is set, the column can be resized by dragging it. */
        draggable                   = 4,    /**< If this is set, the column can be dragged around to change its order in the table. */
        appearsOnColumnMenu         = 8,    /**< If this is set, the column will be shown on the pop-up menu allowing it to be hidden/shown. */
        sortable                    = 16,   /**< If this is set, then clicking on the column header will set it to be the sort column, and clicking again will reverse the order. */
        sortedForwards              = 32,   /**< If this is set, the column is currently the one by which the table is sorted (forwards). */
        sortedBackwards             = 64,   /**< If this is set, the column is currently the one by which the table is sorted (backwards). */

        /** This set of default flags is used as the default parameter value in addColumn(). */
        defaultFlags                = (visible | resizable | draggable | appearsOnColumnMenu | sortable),

        /** A quick way of combining flags for a column that's not resizable. */
        notResizable                = (visible | draggable | appearsOnColumnMenu | sortable),

        /** A quick way of combining flags for a column that's not resizable or sortable. */
        notResizableOrSortable      = (visible | draggable | appearsOnColumnMenu),

        /** A quick way of combining flags for a column that's not sortable. */
        notSortable                 = (visible | resizable | draggable | appearsOnColumnMenu)
    };

    /** Adds a column to the table.

        This will add a column, and asynchronously call the tableColumnsChanged() method of any
        registered listeners.

        @param columnName       the name of the new column. It's ok to have two or more columns with the same name
        @param columnId         an ID for this column. The ID can be any number apart from 0, but every column must have
                                a unique ID. This is used to identify the column later on, after the user may have
                                changed the order that they appear in
        @param width            the initial width of the column, in pixels
        @param maximumWidth     a maximum width that the column can take when the user is resizing it. This only applies
                                if the 'resizable' flag is specified for this column
        @param minimumWidth     a minimum width that the column can take when the user is resizing it. This only applies
                                if the 'resizable' flag is specified for this column
        @param propertyFlags    a combination of some of the values from the ColumnPropertyFlags enum, to define the
                                properties of this column
        @param insertIndex      the index at which the column should be added. A value of 0 puts it at the start (left-hand side)
                                and -1 puts it at the end (right-hand size) of the table. Note that the index the index within
                                all columns, not just the index amongst those that are currently visible
    */
    void addColumn (const String& columnName,
                    const int columnId,
                    const int width,
                    const int minimumWidth = 30,
                    const int maximumWidth = -1,
                    const int propertyFlags = defaultFlags,
                    const int insertIndex = -1);

    /** Removes a column with the given ID.

        If there is such a column, this will asynchronously call the tableColumnsChanged() method of any
        registered listeners.
    */
    void removeColumn (const int columnIdToRemove);

    /** Deletes all columns from the table.

        If there are any columns to remove, this will asynchronously call the tableColumnsChanged() method of any
        registered listeners.
    */
    void removeAllColumns();

    /** Returns the number of columns in the table.

        If onlyCountVisibleColumns is true, this will return the number of visible columns; otherwise it'll
        return the total number of columns, including hidden ones.

        @see isColumnVisible
    */
    int getNumColumns (const bool onlyCountVisibleColumns) const throw();

    /** Returns the name for a column.
        @see setColumnName
    */
    const String getColumnName (const int columnId) const throw();

    /** Changes the name of a column. */
    void setColumnName (const int columnId, const String& newName);

    /** Moves a column to a different index in the table.

        @param columnId             the column to move
        @param newVisibleIndex      the target index for it, from 0 to the number of columns currently visible.
    */
    void moveColumn (const int columnId, int newVisibleIndex);

    /** Changes the width of a column.

        This will cause an asynchronous callback to the tableColumnsResized() method of any registered listeners.
    */
    void setColumnWidth (const int columnId, const int newWidth);

    /** Shows or hides a column.

        This can cause an asynchronous callback to the tableColumnsChanged() method of any registered listeners.
        @see isColumnVisible
    */
    void setColumnVisible (const int columnId, const bool shouldBeVisible);

    /** Returns true if this column is currently visible.
        @see setColumnVisible
    */
    bool isColumnVisible (const int columnId) const;

    /** Changes the column which is the sort column.

        This can cause an asynchronous callback to the tableSortOrderChanged() method of any registered listeners.

        If this method doesn't actually change the column ID, then no re-sort will take place (you can
        call reSortTable() to force a re-sort to happen if you've modified the table's contents).

        @see getSortColumnId, isSortedForwards, reSortTable
    */
    void setSortColumnId (const int columnId, const bool sortForwards);

    /** Returns the column ID by which the table is currently sorted, or 0 if it is unsorted.

        @see setSortColumnId, isSortedForwards
    */
    int getSortColumnId() const throw();

    /** Returns true if the table is currently sorted forwards, or false if it's backwards.
        @see setSortColumnId
    */
    bool isSortedForwards() const throw();

    /** Triggers a re-sort of the table according to the current sort-column.

        If you modifiy the table's contents, you can call this to signal that the table needs
        to be re-sorted.

        (This doesn't do any sorting synchronously - it just asynchronously sends a call to the
        tableSortOrderChanged() method of any listeners).
    */
    void reSortTable();

    /** Returns the total width of all the visible columns in the table.
    */
    int getTotalWidth() const throw();

    /** Returns the index of a given column.

        If there's no such column ID, this will return -1.

        If onlyCountVisibleColumns is true, this will return the index amoungst the visible columns;
        otherwise it'll return the index amongst all the columns, including any hidden ones.
    */
    int getIndexOfColumnId (const int columnId, const bool onlyCountVisibleColumns) const throw();

    /** Returns the ID of the column at a given index.

        If onlyCountVisibleColumns is true, this will count the index amoungst the visible columns;
        otherwise it'll count it amongst all the columns, including any hidden ones.

        If the index is out-of-range, it'll return 0.
    */
    int getColumnIdOfIndex (int index, const bool onlyCountVisibleColumns) const throw();

    /** Returns the rectangle containing of one of the columns.

        The index is an index from 0 to the number of columns that are currently visible (hidden
        ones are not counted). It returns a rectangle showing the position of the column relative
        to this component's top-left. If the index is out-of-range, an empty rectangle is retrurned.
    */
    const Rectangle getColumnPosition (const int index) const throw();

    /** Finds the column ID at a given x-position in the component.

        If there is a column at this point this returns its ID, or if not, it will return 0.
    */
    int getColumnIdAtX (const int xToFind) const throw();

    /** If set to true, this indicates that the columns should be expanded or shrunk to fill the
        entire width of the component.

        By default this is disabled. Turning it on also means that when resizing a column, those
        on the right will be squashed to fit.
    */
    void setStretchToFitActive (const bool shouldStretchToFit);

    /** Returns true if stretch-to-fit has been enabled.
        @see setStretchToFitActive
    */
    bool isStretchToFitActive() const throw();

    /** If stretch-to-fit is enabled, this will resize all the columns to make them fit into the
        specified width, keeping their relative proportions the same.

        If the minimum widths of the columns are too wide to fit into this space, it may
        actually end up wider.
    */
    void resizeAllColumnsToFit (int targetTotalWidth);

    /** Enables or disables the pop-up menu.

        The default menu allows the user to show or hide columns. You can add custom
        items to this menu by overloading the addMenuItems() and reactToMenuItem() methods.

        By default the menu is enabled.

        @see isPopupMenuActive, addMenuItems, reactToMenuItem
    */
    void setPopupMenuActive (const bool hasMenu);

    /** Returns true if the pop-up menu is enabled.
        @see setPopupMenuActive
    */
    bool isPopupMenuActive() const throw();

    /** Returns a string that encapsulates the table's current layout.

        This can be restored later using restoreFromString(). It saves the order of
        the columns, the currently-sorted column, and the widths.

        @see restoreFromString
    */
    const String toString() const;

    /** Restores the state of the table, based on a string previously created with
        toString().

        @see toString
    */
    void restoreFromString (const String& storedVersion);

    /** Adds a listener to be informed about things that happen to the header. */
    void addListener (TableHeaderListener* const newListener) throw();

    /** Removes a previously-registered listener. */
    void removeListener (TableHeaderListener* const listenerToRemove) throw();

    /** This can be overridden to handle a mouse-click on one of the column headers.

        The default implementation will use this click to call getSortColumnId() and
        change the sort order.
    */
    virtual void columnClicked (int columnId, const ModifierKeys& mods);

    /** This can be overridden to add custom items to the pop-up menu.

        If you override this, you should call the superclass's method to add its
        column show/hide items, if you want them on the menu as well.

        Then to handle the result, override reactToMenuItem().

        @see reactToMenuItem
    */
    virtual void addMenuItems (PopupMenu& menu, const int columnIdClicked);

    /** Override this to handle any custom items that you have added to the
        pop-up menu with an addMenuItems() override.

        If the menuReturnId isn't one of your own custom menu items, you'll need to
        call TableHeaderComponent::reactToMenuItem() to allow the base class to
        handle the items that it had added.

        @see addMenuItems
    */
    virtual void reactToMenuItem (const int menuReturnId, const int columnIdClicked);

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void mouseMove (const MouseEvent&);
    /** @internal */
    void mouseEnter (const MouseEvent&);
    /** @internal */
    void mouseExit (const MouseEvent&);
    /** @internal */
    void mouseDown (const MouseEvent&);
    /** @internal */
    void mouseDrag (const MouseEvent&);
    /** @internal */
    void mouseUp (const MouseEvent&);
    /** @internal */
    const MouseCursor getMouseCursor();

    /** Can be overridden for more control over the pop-up menu behaviour. */
    virtual void showColumnChooserMenu (const int columnIdClicked);

    juce_UseDebuggingNewOperator

private:
    struct ColumnInfo
    {
        String name;
        int id, propertyFlags, width, minimumWidth, maximumWidth;
        double lastDeliberateWidth;

        bool isVisible() const throw();
    };

    OwnedArray <ColumnInfo> columns;
    Array <TableHeaderListener*> listeners;
    Component* dragOverlayComp;

    bool columnsChanged, columnsResized, sortChanged, menuActive, stretchToFit;
    int columnIdBeingResized, columnIdBeingDragged, initialColumnWidth;
    int columnIdUnderMouse, draggingColumnOffset, draggingColumnOriginalIndex, lastDeliberateWidth;

    ColumnInfo* getInfoForId (const int columnId) const throw();
    int visibleIndexToTotalIndex (const int visibleIndex) const throw();
    void sendColumnsChanged();
    void handleAsyncUpdate();
    void beginDrag (const MouseEvent&);
    void endDrag (const int finalIndex);
    int getResizeDraggerAt (const int mouseX) const throw();
    void updateColumnUnderMouse (int x, int y);
    void resizeColumnsToFit (int firstColumnIndex, int targetTotalWidth);

    TableHeaderComponent (const TableHeaderComponent&);
    const TableHeaderComponent operator= (const TableHeaderComponent&);
};

#endif   // __JUCE_TABLEHEADERCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_TableHeaderComponent.h *********/

#endif
#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__

/********* Start of inlined file: juce_TableListBox.h *********/
#ifndef __JUCE_TABLELISTBOX_JUCEHEADER__
#define __JUCE_TABLELISTBOX_JUCEHEADER__

/**
    One of these is used by a TableListBox as the data model for the table's contents.

    The virtual methods that you override in this class take care of drawing the
    table cells, and reacting to events.

    @see TableListBox
*/
class JUCE_API  TableListBoxModel
{
public:

    TableListBoxModel()  {}

    /** Destructor. */
    virtual ~TableListBoxModel()  {}

    /** This must return the number of rows currently in the table.

        If the number of rows changes, you must call TableListBox::updateContent() to
        cause it to refresh the list.
    */
    virtual int getNumRows() = 0;

    /** This must draw the background behind one of the rows in the table.

        The graphics context has its origin at the row's top-left, and your method
        should fill the area specified by the width and height parameters.
    */
    virtual void paintRowBackground (Graphics& g,
                                     int rowNumber,
                                     int width, int height,
                                     bool rowIsSelected) = 0;

    /** This must draw one of the cells.

        The graphics context's origin will already be set to the top-left of the cell,
        whose size is specified by (width, height).
    */
    virtual void paintCell (Graphics& g,
                            int rowNumber,
                            int columnId,
                            int width, int height,
                            bool rowIsSelected) = 0;

    /** This is used to create or update a custom component to go in a cell.

        Any cell may contain a custom component, or can just be drawn with the paintCell() method
        and handle mouse clicks with cellClicked().

        This method will be called whenever a custom component might need to be updated - e.g.
        when the table is changed, or TableListBox::updateContent() is called.

        If you don't need a custom component for the specified cell, then return 0.

        If you do want a custom component, and the existingComponentToUpdate is null, then
        this method must create a new component suitable for the cell, and return it.

        If the existingComponentToUpdate is non-null, it will be a pointer to a component previously created
        by this method. In this case, the method must either update it to make sure it's correctly representing
        the given cell (which may be different from the one that the component was created for), or it can
        delete this component and return a new one.
    */
    virtual Component* refreshComponentForCell (int rowNumber, int columnId, bool isRowSelected,
                                                Component* existingComponentToUpdate);

    /** This callback is made when the user clicks on one of the cells in the table.

        The mouse event's coordinates will be relative to the entire table row.
        @see cellDoubleClicked, backgroundClicked
    */
    virtual void cellClicked (int rowNumber, int columnId, const MouseEvent& e);

    /** This callback is made when the user clicks on one of the cells in the table.

        The mouse event's coordinates will be relative to the entire table row.
        @see cellClicked, backgroundClicked
    */
    virtual void cellDoubleClicked (int rowNumber, int columnId, const MouseEvent& e);

    /** This can be overridden to react to the user double-clicking on a part of the list where
        there are no rows.

        @see cellClicked
    */
    virtual void backgroundClicked();

    /** This callback is made when the table's sort order is changed.

        This could be because the user has clicked a column header, or because the
        TableHeaderComponent::setSortColumnId() method was called.

        If you implement this, your method should re-sort the table using the given
        column as the key.
    */
    virtual void sortOrderChanged (int newSortColumnId, const bool isForwards);

    /** Returns the best width for one of the columns.

        If you implement this method, you should measure the width of all the items
        in this column, and return the best size.

        Returning 0 means that the column shouldn't be changed.

        This is used by TableListBox::autoSizeColumn() and TableListBox::autoSizeAllColumns().
    */
    virtual int getColumnAutoSizeWidth (int columnId);

    /** Override this to be informed when rows are selected or deselected.

        @see ListBox::selectedRowsChanged()
    */
    virtual void selectedRowsChanged (int lastRowSelected);

    /** Override this to be informed when the delete key is pressed.

        @see ListBox::deleteKeyPressed()
    */
    virtual void deleteKeyPressed (int lastRowSelected);

    /** Override this to be informed when the return key is pressed.

        @see ListBox::returnKeyPressed()
    */
    virtual void returnKeyPressed (int lastRowSelected);

    /** Override this to be informed when the list is scrolled.

        This might be caused by the user moving the scrollbar, or by programmatic changes
        to the list position.
    */
    virtual void listWasScrolled();

    /** To allow rows from your table to be dragged-and-dropped, implement this method.

        If this returns a non-empty name then when the user drags a row, the table will try to
        find a DragAndDropContainer in its parent hierarchy, and will use it to trigger a
        drag-and-drop operation, using this string as the source description, and the listbox
        itself as the source component.

        @see DragAndDropContainer::startDragging
    */
    virtual const String getDragSourceDescription (const SparseSet<int>& currentlySelectedRows);
};

/**
    A table of cells, using a TableHeaderComponent as its header.

    This component makes it easy to create a table by providing a TableListBoxModel as
    the data source.

    @see TableListBoxModel, TableHeaderComponent
*/
class JUCE_API  TableListBox   : public ListBox,
                                 private ListBoxModel,
                                 private TableHeaderListener
{
public:

    /** Creates a TableListBox.

        The model pointer passed-in can be null, in which case you can set it later
        with setModel().
    */
    TableListBox (const String& componentName,
                  TableListBoxModel* const model);

    /** Destructor. */
    ~TableListBox();

    /** Changes the TableListBoxModel that is being used for this table.
    */
    void setModel (TableListBoxModel* const newModel);

    /** Returns the model currently in use. */
    TableListBoxModel* getModel() const throw()                     { return model; }

    /** Returns the header component being used in this table. */
    TableHeaderComponent* getHeader() const throw()                 { return header; }

    /** Changes the height of the table header component.
        @see getHeaderHeight
    */
    void setHeaderHeight (const int newHeight);

    /** Returns the height of the table header.
        @see setHeaderHeight
    */
    int getHeaderHeight() const throw();

    /** Resizes a column to fit its contents.

        This uses TableListBoxModel::getColumnAutoSizeWidth() to find the best width,
        and applies that to the column.

        @see autoSizeAllColumns, TableHeaderComponent::setColumnWidth
    */
    void autoSizeColumn (const int columnId);

    /** Calls autoSizeColumn() for all columns in the table. */
    void autoSizeAllColumns();

    /** Enables or disables the auto size options on the popup menu.

        By default, these are enabled.
    */
    void setAutoSizeMenuOptionShown (const bool shouldBeShown);

    /** True if the auto-size options should be shown on the menu.
        @see setAutoSizeMenuOptionsShown
    */
    bool isAutoSizeMenuOptionShown() const throw();

    /** Returns the position of one of the cells in the table.

        If relativeToComponentTopLeft is true, the co-ordinates are relative to
        the table component's top-left. The row number isn't checked to see if it's
        in-range, but the column ID must exist or this will return an empty rectangle.

        If relativeToComponentTopLeft is false, the co-ords are relative to the
        top-left of the table's top-left cell.
    */
    const Rectangle getCellPosition (const int columnId,
                                     const int rowNumber,
                                     const bool relativeToComponentTopLeft) const;

    /** Scrolls horizontally if necessary to make sure that a particular column is visible.

        @see ListBox::scrollToEnsureRowIsOnscreen
    */
    void scrollToEnsureColumnIsOnscreen (const int columnId);

    /** @internal */
    int getNumRows();
    /** @internal */
    void paintListBoxItem (int, Graphics&, int, int, bool);
    /** @internal */
    Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate);
    /** @internal */
    void selectedRowsChanged (int lastRowSelected);
    /** @internal */
    void deleteKeyPressed (int currentSelectedRow);
    /** @internal */
    void returnKeyPressed (int currentSelectedRow);
    /** @internal */
    void backgroundClicked();
    /** @internal */
    void listWasScrolled();
    /** @internal */
    void tableColumnsChanged (TableHeaderComponent*);
    /** @internal */
    void tableColumnsResized (TableHeaderComponent*);
    /** @internal */
    void tableSortOrderChanged (TableHeaderComponent*);
    /** @internal */
    void tableColumnDraggingChanged (TableHeaderComponent*, int);
    /** @internal */
    void resized();

    juce_UseDebuggingNewOperator

private:
    TableHeaderComponent* header;
    TableListBoxModel* model;
    int columnIdNowBeingDragged;
    bool autoSizeOptionsShown;

    void updateColumnComponents() const;

    TableListBox (const TableListBox&);
    const TableListBox& operator= (const TableListBox&);
};

#endif   // __JUCE_TABLELISTBOX_JUCEHEADER__
/********* End of inlined file: juce_TableListBox.h *********/

#endif
#ifndef __JUCE_TOOLBAR_JUCEHEADER__

#endif
#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__

/********* Start of inlined file: juce_ToolbarItemFactory.h *********/
#ifndef __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__
#define __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__

/**
    A factory object which can create ToolbarItemComponent objects.

    A subclass of ToolbarItemFactory publishes a set of types of toolbar item
    that it can create.

    Each type of item is identified by a unique ID, and multiple instances of an
    item type can exist at once (even on the same toolbar, e.g. spacers or separator
    bars).

    @see Toolbar, ToolbarItemComponent, ToolbarButton
*/
class JUCE_API  ToolbarItemFactory
{
public:

    ToolbarItemFactory();

    /** Destructor. */
    virtual ~ToolbarItemFactory();

    /** A set of reserved item ID values, used for the built-in item types.
    */
    enum SpecialItemIds
    {
        separatorBarId      = -1,   /**< The item ID for a vertical (or horizontal) separator bar that
                                         can be placed between sets of items to break them into groups. */
        spacerId            = -2,   /**< The item ID for a fixed-width space that can be placed between
                                         items.*/
        flexibleSpacerId    = -3    /**< The item ID for a gap that pushes outwards against the things on
                                         either side of it, filling any available space. */
    };

    /** Must return a list of the IDs for all the item types that this factory can create.

        The ids should be added to the array that is passed-in.

        An item ID can be any integer you choose, except for 0, which is considered a null ID,
        and the predefined IDs in the SpecialItemIds enum.

        You should also add the built-in types (separatorBarId, spacerId and flexibleSpacerId)
        to this list if you want your toolbar to be able to contain those items.

        The list returned here is used by the ToolbarItemPalette class to obtain its list
        of available items, and their order on the palette will reflect the order in which
        they appear on this list.

        @see ToolbarItemPalette
    */
    virtual void getAllToolbarItemIds (Array <int>& ids) = 0;

    /** Must return the set of items that should be added to a toolbar as its default set.

        This method is used by Toolbar::addDefaultItems() to determine which items to
        create.

        The items that your method adds to the array that is passed-in will be added to the
        toolbar in the same order. Items can appear in the list more than once.
    */
    virtual void getDefaultItemSet (Array <int>& ids) = 0;

    /** Must create an instance of one of the items that the factory lists in its
        getAllToolbarItemIds() method.

        The itemId parameter can be any of the values listed by your getAllToolbarItemIds()
        method, except for the built-in item types from the SpecialItemIds enum, which
        are created internally by the toolbar code.

        Try not to keep a pointer to the object that is returned, as it will be deleted
        automatically by the toolbar, and remember that multiple instances of the same
        item type are likely to exist at the same time.
    */
    virtual ToolbarItemComponent* createItem (const int itemId) = 0;
};

#endif   // __JUCE_TOOLBARITEMFACTORY_JUCEHEADER__
/********* End of inlined file: juce_ToolbarItemFactory.h *********/

#endif
#ifndef __JUCE_TOOLBARITEMCOMPONENT_JUCEHEADER__

#endif
#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__

/********* Start of inlined file: juce_ToolbarItemPalette.h *********/
#ifndef __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__
#define __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__

/**
    A component containing a list of toolbar items, which the user can drag onto
    a toolbar to add them.

    You can use this class directly, but it's a lot easier to call Toolbar::showCustomisationDialog(),
    which automatically shows one of these in a dialog box with lots of extra controls.

    @see Toolbar
*/
class JUCE_API  ToolbarItemPalette    : public Component,
                                        public DragAndDropContainer
{
public:

    /** Creates a palette of items for a given factory, with the aim of adding them
        to the specified toolbar.

        The ToolbarItemFactory::getAllToolbarItemIds() method is used to create the
        set of items that are shown in this palette.

        The toolbar and factory must not be deleted while this object exists.
    */
    ToolbarItemPalette (ToolbarItemFactory& factory,
                        Toolbar* const toolbar);

    /** Destructor. */
    ~ToolbarItemPalette();

    /** @internal */
    void resized();

    juce_UseDebuggingNewOperator

private:
    ToolbarItemFactory& factory;
    Toolbar* toolbar;
    Viewport* viewport;

    friend class Toolbar;
    void replaceComponent (ToolbarItemComponent* const comp);

    ToolbarItemPalette (const ToolbarItemPalette&);
    const ToolbarItemPalette& operator= (const ToolbarItemPalette&);
};

#endif   // __JUCE_TOOLBARITEMPALETTE_JUCEHEADER__
/********* End of inlined file: juce_ToolbarItemPalette.h *********/

#endif
#ifndef __JUCE_TREEVIEW_JUCEHEADER__

#endif
#ifndef __JUCE_TEXTEDITOR_JUCEHEADER__

#endif
#ifndef __JUCE_LISTBOX_JUCEHEADER__

#endif
#ifndef __JUCE_COMBOBOX_JUCEHEADER__

#endif
#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_BooleanPropertyComponent.h *********/
#ifndef __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__
#define __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__

/**
    A PropertyComponent that contains an on/off toggle button.

    This type of property component can be used if you have a boolean value to
    toggle on/off.

    @see PropertyComponent
*/
class JUCE_API  BooleanPropertyComponent  : public PropertyComponent,
                                            private ButtonListener
{
public:

    /** Creates a button component.

        @param propertyName         the property name to be passed to the PropertyComponent
        @param buttonTextWhenTrue   the text shown in the button when the value is true
        @param buttonTextWhenFalse  the text shown in the button when the value is false
    */
    BooleanPropertyComponent (const String& propertyName,
                              const String& buttonTextWhenTrue,
                              const String& buttonTextWhenFalse);

    /** Destructor. */
    ~BooleanPropertyComponent();

    /** Called to change the state of the boolean value. */
    virtual void setState (const bool newState) = 0;

    /** Must return the current value of the property. */
    virtual bool getState() const = 0;

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void refresh();
    /** @internal */
    void buttonClicked (Button*);

    juce_UseDebuggingNewOperator

private:
    ToggleButton* button;
    String onText, offText;
};

#endif   // __JUCE_BOOLEANPROPERTYCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_BooleanPropertyComponent.h *********/

#endif
#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_ButtonPropertyComponent.h *********/
#ifndef __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__
#define __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__

/**
    A PropertyComponent that contains a button.

    This type of property component can be used if you need a button to trigger some
    kind of action.

    @see PropertyComponent
*/
class JUCE_API  ButtonPropertyComponent  : public PropertyComponent,
                                           private ButtonListener
{
public:

    /** Creates a button component.

        @param propertyName         the property name to be passed to the PropertyComponent
        @param triggerOnMouseDown   this is passed to the Button::setTriggeredOnMouseDown() method
    */
    ButtonPropertyComponent (const String& propertyName,
                             const bool triggerOnMouseDown);

    /** Destructor. */
    ~ButtonPropertyComponent();

    /** Called when the user clicks the button.
    */
    virtual void buttonClicked() = 0;

    /** Returns the string that should be displayed in the button.

        If you need to change this string, call refresh() to update the component.
    */
    virtual const String getButtonText() const = 0;

    /** @internal */
    void refresh();
    /** @internal */
    void buttonClicked (Button*);

    juce_UseDebuggingNewOperator

private:
    TextButton* button;
};

#endif   // __JUCE_BUTTONPROPERTYCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_ButtonPropertyComponent.h *********/

#endif
#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_ChoicePropertyComponent.h *********/
#ifndef __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__
#define __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__

/**
    A PropertyComponent that shows its value as a combo box.

    This type of property component contains a list of options and has a
    combo box to choose one.

    Your subclass's constructor must add some strings to the choices StringArray
    and these are shown in the list.

    The getIndex() method will be called to find out which option is the currently
    selected one. If you call refresh() it will call getIndex() to check whether
    the value has changed, and will update the combo box if needed.

    If the user selects a different item from the list, setIndex() will be
    called to let your class process this.

    @see PropertyComponent, PropertyPanel
*/
class JUCE_API  ChoicePropertyComponent    : public PropertyComponent,
                                             private ComboBoxListener
{
public:
    /** Creates the component.

        Your subclass's constructor must add a list of options to the choices
        member variable.
    */
    ChoicePropertyComponent (const String& propertyName);

    /** Destructor. */
    ~ChoicePropertyComponent();

    /** Called when the user selects an item from the combo box.

        Your subclass must use this callback to update the value that this component
        represents. The index is the index of the chosen item in the choices
        StringArray.
    */
    virtual void setIndex (const int newIndex) = 0;

    /** Returns the index of the item that should currently be shown.

        This is the index of the item in the choices StringArray that will be
        shown.
    */
    virtual int getIndex() const = 0;

    /** Returns the list of options. */
    const StringArray& getChoices() const throw();

    /** @internal */
    void refresh();
    /** @internal */
    void comboBoxChanged (ComboBox*);

    juce_UseDebuggingNewOperator

protected:
    /** The list of options that will be shown in the combo box.

        Your subclass must populate this array in its constructor. If any empty
        strings are added, these will be replaced with horizontal separators (see
        ComboBox::addSeparator() for more info).
    */
    StringArray choices;

private:
    ComboBox* comboBox;
};

#endif   // __JUCE_CHOICEPROPERTYCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_ChoicePropertyComponent.h *********/

#endif
#ifndef __JUCE_PROPERTYCOMPONENT_JUCEHEADER__

#endif
#ifndef __JUCE_PROPERTYPANEL_JUCEHEADER__

#endif
#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_SliderPropertyComponent.h *********/
#ifndef __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__
#define __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__

/**
    A PropertyComponent that shows its value as a slider.

    @see PropertyComponent, Slider
*/
class JUCE_API  SliderPropertyComponent   : public PropertyComponent,
                                            private SliderListener
{
public:

    /** Creates the property component.

        The ranges, interval and skew factor are passed to the Slider component.

        If you need to customise the slider in other ways, your constructor can
        access the slider member variable and change it directly.
    */
    SliderPropertyComponent (const String& propertyName,
                             const double rangeMin,
                             const double rangeMax,
                             const double interval,
                             const double skewFactor = 1.0);

    /** Destructor. */
    ~SliderPropertyComponent();

    /** Called when the user moves the slider to change its value.

        Your subclass must use this method to update whatever item this property
        represents.
    */
    virtual void setValue (const double newValue) = 0;

    /** Returns the value that the slider should show. */
    virtual const double getValue() const = 0;

    /** @internal */
    void refresh();
    /** @internal */
    void changeListenerCallback (void*);
    /** @internal */
    void sliderValueChanged (Slider*);

    juce_UseDebuggingNewOperator

protected:

    /** The slider component being used in this component.

        Your subclass has access to this in case it needs to customise it in some way.
    */
    Slider* slider;
};

#endif   // __JUCE_SLIDERPROPERTYCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_SliderPropertyComponent.h *********/

#endif
#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_TextPropertyComponent.h *********/
#ifndef __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__
#define __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__

/**
    A PropertyComponent that shows its value as editable text.

    @see PropertyComponent
*/
class JUCE_API  TextPropertyComponent  : public PropertyComponent
{
public:

    /** Creates a text property component.

        The maxNumChars is used to set the length of string allowable, and isMultiLine
        sets whether the text editor allows carriage returns.

        @see TextEditor
    */
    TextPropertyComponent (const String& propertyName,
                           const int maxNumChars,
                           const bool isMultiLine);

    /** Destructor. */
    ~TextPropertyComponent();

    /** Called when the user edits the text.

        Your subclass must use this callback to change the value of whatever item
        this property component represents.
    */
    virtual void setText (const String& newText) = 0;

    /** Returns the text that should be shown in the text editor.
    */
    virtual const String getText() const = 0;

    /** @internal */
    void refresh();
    /** @internal */
    void textWasEdited();

    juce_UseDebuggingNewOperator

private:
    Label* textEditor;
};

#endif   // __JUCE_TEXTPROPERTYCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_TextPropertyComponent.h *********/

#endif
#ifndef __JUCE_COMPONENTANIMATOR_JUCEHEADER__

#endif
#ifndef __JUCE_COMPONENTBOUNDSCONSTRAINER_JUCEHEADER__

#endif
#ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__

/********* Start of inlined file: juce_ComponentMovementWatcher.h *********/
#ifndef __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__
#define __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__

/** An object that watches for any movement of a component or any of its parent components.

    This makes it easy to check when a component is moved relative to its top-level
    peer window. The normal Component::moved() method is only called when a component
    moves relative to its immediate parent, and sometimes you want to know if any of
    components higher up the tree have moved (which of course will affect the overall
    position of all their sub-components).

    It also includes a callback that lets you know when the top-level peer is changed.

    This class is used by specialised components like OpenGLComponent or QuickTimeComponent
    because they need to keep their custom windows in the right place and respond to
    changes in the peer.
*/
class JUCE_API  ComponentMovementWatcher    : public ComponentListener
{
public:

    /** Creates a ComponentMovementWatcher to watch a given target component. */
    ComponentMovementWatcher (Component* const component);

    /** Destructor. */
    ~ComponentMovementWatcher();

    /** This callback happens when the component that is being watched is moved
        relative to its top-level peer window, or when it is resized.
    */
    virtual void componentMovedOrResized (bool wasMoved, bool wasResized) = 0;

    /** This callback happens when the component's top-level peer is changed.
    */
    virtual void componentPeerChanged() = 0;

    juce_UseDebuggingNewOperator

    /** @internal */
    void componentParentHierarchyChanged (Component& component);
    /** @internal */
    void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized);

private:

    Component* const component;
    ComponentPeer* lastPeer;
    VoidArray registeredParentComps;
    bool reentrant;
    int lastX, lastY, lastWidth, lastHeight;
#ifdef JUCE_DEBUG
    ComponentDeletionWatcher* deletionWatcher;
#endif

    void unregister() throw();
    void registerWithParentComps() throw();

    ComponentMovementWatcher (const ComponentMovementWatcher&);
    const ComponentMovementWatcher& operator= (const ComponentMovementWatcher&);
};

#endif   // __JUCE_COMPONENTMOVEMENTWATCHER_JUCEHEADER__
/********* End of inlined file: juce_ComponentMovementWatcher.h *********/

#endif
#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_GroupComponent.h *********/
#ifndef __JUCE_GROUPCOMPONENT_JUCEHEADER__
#define __JUCE_GROUPCOMPONENT_JUCEHEADER__

/**
    A component that draws an outline around itself and has an optional title at
    the top, for drawing an outline around a group of controls.

*/
class JUCE_API  GroupComponent    : public Component
{
public:

    /** Creates a GroupComponent.

        @param componentName    the name to give the component
        @param labelText        the text to show at the top of the outline
    */
    GroupComponent (const String& componentName,
                    const String& labelText);

    /** Destructor. */
    ~GroupComponent();

    /** Changes the text that's shown at the top of the component. */
    void setText (const String& newText) throw();

    /** Returns the currently displayed text label. */
    const String getText() const throw();

    /** Sets the positioning of the text label.

        (The default is Justification::left)

        @see getTextLabelPosition
    */
    void setTextLabelPosition (const Justification& justification);

    /** Returns the current text label position.

        @see setTextLabelPosition
    */
    const Justification getTextLabelPosition() const throw()            { return justification; }

    /** A set of colour IDs to use to change the colour of various aspects of the component.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        outlineColourId     = 0x1005400,    /**< The colour to use for drawing the line around the edge. */
        textColourId        = 0x1005410     /**< The colour to use to draw the text label. */
    };

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void enablementChanged();
    /** @internal */
    void colourChanged();

private:
    String text;
    Justification justification;

    GroupComponent (const GroupComponent&);
    const GroupComponent& operator= (const GroupComponent&);
};

#endif   // __JUCE_GROUPCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_GroupComponent.h *********/

#endif
#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__

/********* Start of inlined file: juce_MultiDocumentPanel.h *********/
#ifndef __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__
#define __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__

/********* Start of inlined file: juce_TabbedComponent.h *********/
#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__
#define __JUCE_TABBEDCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_TabbedButtonBar.h *********/
#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__
#define __JUCE_TABBEDBUTTONBAR_JUCEHEADER__

class TabbedButtonBar;

/** In a TabbedButtonBar, this component is used for each of the buttons.

    If you want to create a TabbedButtonBar with custom tab components, derive
    your component from this class, and override the TabbedButtonBar::createTabButton()
    method to create it instead of the default one.

    @see TabbedButtonBar
*/
class JUCE_API  TabBarButton  : public Button
{
public:

    /** Creates the tab button. */
    TabBarButton (const String& name,
                  TabbedButtonBar* const ownerBar,
                  const int tabIndex);

    /** Destructor. */
    ~TabBarButton();

    /** Chooses the best length for the tab, given the specified depth.

        If the tab is horizontal, this should return its width, and the depth
        specifies its height. If it's vertical, it should return the height, and
        the depth is actually its width.
    */
    virtual int getBestTabLength (const int depth);

    void paintButton (Graphics& g, bool isMouseOverButton, bool isButtonDown);
    void clicked (const ModifierKeys& mods);
    bool hitTest (int x, int y);

    juce_UseDebuggingNewOperator

protected:
    friend class TabbedButtonBar;
    TabbedButtonBar* const owner;
    int tabIndex, overlapPixels;
    DropShadowEffect shadow;

    /** Returns an area of the component that's safe to draw in.

        This deals with the orientation of the tabs, which affects which side is
        touching the tabbed box's content component.
    */
    void getActiveArea (int& x, int& y, int& w, int& h);

private:
    TabBarButton (const TabBarButton&);
    const TabBarButton& operator= (const TabBarButton&);
};

/**
    A vertical or horizontal bar containing tabs that you can select.

    You can use one of these to generate things like a dialog box that has
    tabbed pages you can flip between. Attach a ChangeListener to the
    button bar to be told when the user changes the page.

    An easier method than doing this is to use a TabbedComponent, which
    contains its own TabbedButtonBar and which takes care of the layout
    and other housekeeping.

    @see TabbedComponent
*/
class JUCE_API  TabbedButtonBar  : public Component,
                                   public ChangeBroadcaster,
                                   public ButtonListener
{
public:

    /** The placement of the tab-bar

        @see setOrientation, getOrientation
    */
    enum Orientation
    {
        TabsAtTop,
        TabsAtBottom,
        TabsAtLeft,
        TabsAtRight
    };

    /** Creates a TabbedButtonBar with a given placement.

        You can change the orientation later if you need to.
    */
    TabbedButtonBar (const Orientation orientation);

    /** Destructor. */
    ~TabbedButtonBar();

    /** Changes the bar's orientation.

        This won't change the bar's actual size - you'll need to do that yourself,
        but this determines which direction the tabs go in, and which side they're
        stuck to.
    */
    void setOrientation (const Orientation orientation);

    /** Returns the current orientation.

        @see setOrientation
    */
    Orientation getOrientation() const throw()                      { return orientation; }

    /** Deletes all the tabs from the bar.

        @see addTab
    */
    void clearTabs();

    /** Adds a tab to the bar.

        Tabs are added in left-to-right reading order.

        If this is the first tab added, it'll also be automatically selected.
    */
    void addTab (const String& tabName,
                 const Colour& tabBackgroundColour,
                 int insertIndex = -1);

    /** Changes the name of one of the tabs. */
    void setTabName (const int tabIndex,
                     const String& newName);

    /** Gets rid of one of the tabs. */
    void removeTab (const int tabIndex);

    /** Moves a tab to a new index in the list.

        Pass -1 as the index to move it to the end of the list.
    */
    void moveTab (const int currentIndex,
                  const int newIndex);

    /** Returns the number of tabs in the bar. */
    int getNumTabs() const;

    /** Returns a list of all the tab names in the bar. */
    const StringArray getTabNames() const;

    /** Changes the currently selected tab.

        This will send a change message and cause a synchronous callback to
        the currentTabChanged() method. (But if the given tab is already selected,
        nothing will be done).

        To deselect all the tabs, use an index of -1.
    */
    void setCurrentTabIndex (int newTabIndex, const bool sendChangeMessage = true);

    /** Returns the name of the currently selected tab.

        This could be an empty string if none are selected.
    */
    const String& getCurrentTabName() const throw()                     { return tabs [currentTabIndex]; }

    /** Returns the index of the currently selected tab.

        This could return -1 if none are selected.
    */
    int getCurrentTabIndex() const throw()                              { return currentTabIndex; }

    /** Returns the button for a specific tab.

        The button that is returned may be deleted later by this component, so don't hang
        on to the pointer that is returned. A null pointer may be returned if the index is
        out of range.
    */
    TabBarButton* getTabButton (const int index) const;

    /** Callback method to indicate the selected tab has been changed.

        @see setCurrentTabIndex
    */
    virtual void currentTabChanged (const int newCurrentTabIndex,
                                    const String& newCurrentTabName);

    /** Callback method to indicate that the user has right-clicked on a tab.

        (Or ctrl-clicked on the Mac)
    */
    virtual void popupMenuClickOnTab (const int tabIndex,
                                      const String& tabName);

    /** Returns the colour of a tab.

        This is the colour that was specified in addTab().
    */
    const Colour getTabBackgroundColour (const int tabIndex);

    /** Changes the background colour of a tab.

        @see addTab, getTabBackgroundColour
    */
    void setTabBackgroundColour (const int tabIndex, const Colour& newColour);

    /** A set of colour IDs to use to change the colour of various aspects of the component.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        tabOutlineColourId              = 0x1005812,    /**< The colour to use to draw an outline around the tabs.  */
        tabTextColourId                 = 0x1005813,    /**< The colour to use to draw the tab names. If this isn't specified,
                                                             the look and feel will choose an appropriate colour. */
        frontOutlineColourId            = 0x1005814,    /**< The colour to use to draw an outline around the currently-selected tab.  */
        frontTextColourId               = 0x1005815,    /**< The colour to use to draw the currently-selected tab name. If
                                                             this isn't specified, the look and feel will choose an appropriate
                                                             colour. */
    };

    /** @internal */
    void resized();
    /** @internal */
    void buttonClicked (Button* button);
    /** @internal */
    void lookAndFeelChanged();

    juce_UseDebuggingNewOperator

protected:

    /** This creates one of the tabs.

        If you need to use custom tab components, you can override this method and
        return your own class instead of the default.
    */
    virtual TabBarButton* createTabButton (const String& tabName,
                                           const int tabIndex);

private:
    Orientation orientation;

    StringArray tabs;
    Array <Colour> tabColours;
    int currentTabIndex;
    Component* behindFrontTab;
    Button* extraTabsButton;

    TabbedButtonBar (const TabbedButtonBar&);
    const TabbedButtonBar& operator= (const TabbedButtonBar&);
};

#endif   // __JUCE_TABBEDBUTTONBAR_JUCEHEADER__
/********* End of inlined file: juce_TabbedButtonBar.h *********/

/**
    A component with a TabbedButtonBar along one of its sides.

    This makes it easy to create a set of tabbed pages, just add a bunch of tabs
    with addTab(), and this will take care of showing the pages for you when the
    user clicks on a different tab.

    @see TabbedButtonBar
*/
class JUCE_API  TabbedComponent  : public Component
{
public:

    /** Creates a TabbedComponent, specifying where the tabs should be placed.

        Once created, add some tabs with the addTab() method.
    */
    TabbedComponent (const TabbedButtonBar::Orientation orientation);

    /** Destructor. */
    ~TabbedComponent();

    /** Changes the placement of the tabs.

        This will rearrange the layout to place the tabs along the appropriate
        side of this component, and will shift the content component accordingly.

        @see TabbedButtonBar::setOrientation
    */
    void setOrientation (const TabbedButtonBar::Orientation orientation);

    /** Returns the current tab placement.

        @see setOrientation, TabbedButtonBar::getOrientation
    */
    TabbedButtonBar::Orientation getOrientation() const throw();

    /** Specifies how many pixels wide or high the tab-bar should be.

        If the tabs are placed along the top or bottom, this specified the height
        of the bar; if they're along the left or right edges, it'll be the width
        of the bar.
    */
    void setTabBarDepth (const int newDepth);

    /** Returns the current thickness of the tab bar.

        @see setTabBarDepth
    */
    int getTabBarDepth() const throw()                          { return tabDepth; }

    /** Specifies the thickness of an outline that should be drawn around the content component.

        If this thickness is > 0, a line will be drawn around the three sides of the content
        component which don't touch the tab-bar, and the content component will be inset by this amount.

        To set the colour of the line, use setColour (outlineColourId, ...).
    */
    void setOutline (const int newThickness);

    /** Specifies a gap to leave around the edge of the content component.

        Each edge of the content component will be indented by the given number of pixels.
    */
    void setIndent (const int indentThickness);

    /** Removes all the tabs from the bar.

        @see TabbedButtonBar::clearTabs
    */
    void clearTabs();

    /** Adds a tab to the tab-bar.

        The component passed in will be shown for the tab, and if deleteComponentWhenNotNeeded
        is true, it will be deleted when the tab is removed or when this object is
        deleted.

        @see TabbedButtonBar::addTab
    */
    void addTab (const String& tabName,
                 const Colour& tabBackgroundColour,
                 Component* const contentComponent,
                 const bool deleteComponentWhenNotNeeded,
                 const int insertIndex = -1);

    /** Changes the name of one of the tabs. */
    void setTabName (const int tabIndex,
                     const String& newName);

    /** Gets rid of one of the tabs. */
    void removeTab (const int tabIndex);

    /** Returns the number of tabs in the bar. */
    int getNumTabs() const;

    /** Returns a list of all the tab names in the bar. */
    const StringArray getTabNames() const;

    /** Returns the content component that was added for the given index.

        Be sure not to use or delete the components that are returned, as this may interfere
        with the TabbedComponent's use of them.
    */
    Component* getTabContentComponent (const int tabIndex) const throw();

    /** Returns the colour of one of the tabs. */
    const Colour getTabBackgroundColour (const int tabIndex) const throw();

    /** Changes the background colour of one of the tabs. */
    void setTabBackgroundColour (const int tabIndex, const Colour& newColour);

    /** Changes the currently-selected tab.

        To deselect all the tabs, pass -1 as the index.

        @see TabbedButtonBar::setCurrentTabIndex
    */
    void setCurrentTabIndex (const int newTabIndex, const bool sendChangeMessage = true);

    /** Returns the index of the currently selected tab.

        @see addTab, TabbedButtonBar::getCurrentTabIndex()
    */
    int getCurrentTabIndex() const;

    /** Returns the name of the currently selected tab.

        @see addTab, TabbedButtonBar::getCurrentTabName()
    */
    const String& getCurrentTabName() const;

    /** Returns the current component that's filling the panel.

        This will return 0 if there isn't one.
    */
    Component* getCurrentContentComponent() const throw()           { return panelComponent; }

    /** Callback method to indicate the selected tab has been changed.

        @see setCurrentTabIndex
    */
    virtual void currentTabChanged (const int newCurrentTabIndex,
                                    const String& newCurrentTabName);

    /** Callback method to indicate that the user has right-clicked on a tab.

        (Or ctrl-clicked on the Mac)
    */
    virtual void popupMenuClickOnTab (const int tabIndex,
                                      const String& tabName);

    /** Returns the tab button bar component that is being used.
    */
    TabbedButtonBar& getTabbedButtonBar() const throw()             { return *tabs; }

    /** A set of colour IDs to use to change the colour of various aspects of the component.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId          = 0x1005800,    /**< The colour to fill the background behind the tabs. */
        outlineColourId             = 0x1005801,    /**< The colour to use to draw an outline around the content.
                                                         (See setOutline)  */
    };

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void lookAndFeelChanged();

    juce_UseDebuggingNewOperator

protected:

    TabbedButtonBar* tabs;

    /** This creates one of the tab buttons.

        If you need to use custom tab components, you can override this method and
        return your own class instead of the default.
    */
    virtual TabBarButton* createTabButton (const String& tabName,
                                           const int tabIndex);

private:

    Array <Component*> contentComponents;
    Component* panelComponent;
    int tabDepth;
    int outlineThickness, edgeIndent;

    friend class TabCompButtonBar;
    void changeCallback (const int newCurrentTabIndex, const String& newTabName);

    TabbedComponent (const TabbedComponent&);
    const TabbedComponent& operator= (const TabbedComponent&);
};

#endif   // __JUCE_TABBEDCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_TabbedComponent.h *********/

/********* Start of inlined file: juce_DocumentWindow.h *********/
#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__
#define __JUCE_DOCUMENTWINDOW_JUCEHEADER__

/********* Start of inlined file: juce_ResizableWindow.h *********/
#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__
#define __JUCE_RESIZABLEWINDOW_JUCEHEADER__

/********* Start of inlined file: juce_TopLevelWindow.h *********/
#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__
#define __JUCE_TOPLEVELWINDOW_JUCEHEADER__

/********* Start of inlined file: juce_DropShadower.h *********/
#ifndef __JUCE_DROPSHADOWER_JUCEHEADER__
#define __JUCE_DROPSHADOWER_JUCEHEADER__

/**
    Adds a drop-shadow to a component.

    This object creates and manages a set of components which sit around a
    component, creating a gaussian shadow around it. The components will track
    the position of the component and if it's brought to the front they'll also
    follow this.

    For desktop windows you don't need to use this class directly - just
    set the Component::windowHasDropShadow flag when calling
    Component::addToDesktop(), and the system will create one of these if it's
    needed (which it obviously isn't on the Mac, for example).
*/
class JUCE_API  DropShadower  : public ComponentListener
{
public:

    /** Creates a DropShadower.

        @param alpha        the opacity of the shadows, from 0 to 1.0
        @param xOffset      the horizontal displacement of the shadow, in pixels
        @param yOffset      the vertical displacement of the shadow, in pixels
        @param blurRadius   the radius of the blur to use for creating the shadow
    */
    DropShadower (const float alpha = 0.5f,
                  const int xOffset = 1,
                  const int yOffset = 5,
                  const float blurRadius = 10.0f);

    /** Destructor. */
    virtual ~DropShadower();

    /** Attaches the DropShadower to the component you want to shadow. */
    void setOwner (Component* componentToFollow);

    /** @internal */
    void componentMovedOrResized (Component& component, bool wasMoved, bool wasResized);
    /** @internal */
    void componentBroughtToFront (Component& component);
    /** @internal */
    void componentChildrenChanged (Component& component);
    /** @internal */
    void componentParentHierarchyChanged (Component& component);
    /** @internal */
    void componentVisibilityChanged (Component& component);

    juce_UseDebuggingNewOperator

private:

    Component* owner;
    int numShadows;
    Component* shadowWindows[4];
    Image* shadowImageSections[12];
    const int shadowEdge, xOffset, yOffset;
    const float alpha, blurRadius;
    bool inDestructor, reentrant;

    void updateShadows();
    void setShadowImage (Image* const src,
                         const int num,
                         const int w, const int h,
                         const int sx, const int sy) throw();

    void bringShadowWindowsToFront();
    void deleteShadowWindows();

    DropShadower (const DropShadower&);
    const DropShadower& operator= (const DropShadower&);
};

#endif   // __JUCE_DROPSHADOWER_JUCEHEADER__
/********* End of inlined file: juce_DropShadower.h *********/

/**
    A base class for top-level windows.

    This class is used for components that are considered a major part of your
    application - e.g. ResizableWindow, DocumentWindow, DialogWindow, AlertWindow,
    etc. Things like menus that pop up briefly aren't derived from it.

    A TopLevelWindow is probably on the desktop, but this isn't mandatory - it
    could itself be the child of another component.

    The class manages a list of all instances of top-level windows that are in use,
    and each one is also given the concept of being "active". The active window is
    one that is actively being used by the user. This isn't quite the same as the
    component with the keyboard focus, because there may be a popup menu or other
    temporary window which gets keyboard focus while the active top level window is
    unchanged.

    A top-level window also has an optional drop-shadow.

    @see ResizableWindow, DocumentWindow, DialogWindow
*/
class JUCE_API  TopLevelWindow  : public Component
{
public:

    /** Creates a TopLevelWindow.

        @param name                 the name to give the component
        @param addToDesktop         if true, the window will be automatically added to the
                                    desktop; if false, you can use it as a child component
    */
    TopLevelWindow (const String& name,
                    const bool addToDesktop);

    /** Destructor. */
    ~TopLevelWindow();

    /** True if this is currently the TopLevelWindow that is actively being used.

        This isn't quite the same as having keyboard focus, because the focus may be
        on a child component or a temporary pop-up menu, etc, while this window is
        still considered to be active.

        @see activeWindowStatusChanged
    */
    bool isActiveWindow() const throw()                     { return windowIsActive_; }

    /** This will set the bounds of the window so that it's centred in front of another
        window.

        If your app has a few windows open and want to pop up a dialog box for one of
        them, you can use this to show it in front of the relevent parent window, which
        is a bit neater than just having it appear in the middle of the screen.

        If componentToCentreAround is 0, then the currently active TopLevelWindow will
        be used instead. If no window is focused, it'll just default to the middle of the
        screen.
    */
    void centreAroundComponent (Component* componentToCentreAround,
                                const int width, const int height);

    /** Turns the drop-shadow on and off. */
    void setDropShadowEnabled (const bool useShadow);

    /** Sets whether an OS-native title bar will be used, or a Juce one.

        @see isUsingNativeTitleBar
    */
    void setUsingNativeTitleBar (const bool useNativeTitleBar);

    /** Returns true if the window is currently using an OS-native title bar.

        @see setUsingNativeTitleBar
    */
    bool isUsingNativeTitleBar() const throw()              { return useNativeTitleBar && isOnDesktop(); }

    /** Returns the number of TopLevelWindow objects currently in use.

        @see getTopLevelWindow
    */
    static int getNumTopLevelWindows() throw();

    /** Returns one of the TopLevelWindow objects currently in use.

        The index is 0 to (getNumTopLevelWindows() - 1).
    */
    static TopLevelWindow* getTopLevelWindow (const int index) throw();

    /** Returns the currently-active top level window.

        There might not be one, of course, so this can return 0.
    */
    static TopLevelWindow* getActiveTopLevelWindow() throw();

    juce_UseDebuggingNewOperator

    /** @internal */
    virtual void addToDesktop (int windowStyleFlags, void* nativeWindowToAttachTo = 0);

protected:

    /** This callback happens when this window becomes active or inactive.

        @see isActiveWindow
    */
    virtual void activeWindowStatusChanged();

    /** @internal */
    void focusOfChildComponentChanged (FocusChangeType cause);
    /** @internal */
    void parentHierarchyChanged();
    /** @internal */
    void visibilityChanged();
    /** @internal */
    virtual int getDesktopWindowStyleFlags() const;
    /** @internal */
    void recreateDesktopWindow();

private:
    friend class TopLevelWindowManager;
    bool useDropShadow, useNativeTitleBar, windowIsActive_;
    DropShadower* shadower;

    void setWindowActive (const bool isNowActive) throw();

    TopLevelWindow (const TopLevelWindow&);
    const TopLevelWindow& operator= (const TopLevelWindow&);
};

#endif   // __JUCE_TOPLEVELWINDOW_JUCEHEADER__
/********* End of inlined file: juce_TopLevelWindow.h *********/

/********* Start of inlined file: juce_ResizableBorderComponent.h *********/
#ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__
#define __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__

/**
    A component that resizes its parent window when dragged.

    This component forms a frame around the edge of a component, allowing it to
    be dragged by the edges or corners to resize it - like the way windows are
    resized in MSWindows or Linux.

    To use it, just add it to your component, making it fill the entire parent component
    (there's a mouse hit-test that only traps mouse-events which land around the
    edge of the component, so it's even ok to put it on top of any other components
    you're using). Make sure you rescale the resizer component to fill the parent
    each time the parent's size changes.

    @see ResizableCornerComponent
*/
class JUCE_API  ResizableBorderComponent  : public Component
{
public:

    /** Creates a resizer.

        Pass in the target component which you want to be resized when this one is
        dragged.

        The target component will usually be a parent of the resizer component, but this
        isn't mandatory.

        Remember that when the target component is resized, it'll need to move and
        resize this component to keep it in place, as this won't happen automatically.

        If the constrainer parameter is non-zero, then this object will be used to enforce
        limits on the size and position that the component can be stretched to. Make sure
        that the constrainer isn't deleted while still in use by this object.

        @see ComponentBoundsConstrainer
    */
    ResizableBorderComponent (Component* const componentToResize,
                              ComponentBoundsConstrainer* const constrainer);

    /** Destructor. */
    ~ResizableBorderComponent();

    /** Specifies how many pixels wide the draggable edges of this component are.

        @see getBorderThickness
    */
    void setBorderThickness (const BorderSize& newBorderSize) throw();

    /** Returns the number of pixels wide that the draggable edges of this component are.

        @see setBorderThickness
    */
    const BorderSize getBorderThickness() const throw();

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void mouseEnter (const MouseEvent& e);
    /** @internal */
    void mouseMove (const MouseEvent& e);
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    void mouseUp (const MouseEvent& e);
    /** @internal */
    bool hitTest (int x, int y);

private:
    Component* const component;
    ComponentBoundsConstrainer* constrainer;
    BorderSize borderSize;
    int originalX, originalY, originalW, originalH;
    int mouseZone;

    void updateMouseZone (const MouseEvent& e) throw();

    ResizableBorderComponent (const ResizableBorderComponent&);
    const ResizableBorderComponent& operator= (const ResizableBorderComponent&);
};

#endif   // __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_ResizableBorderComponent.h *********/

/********* Start of inlined file: juce_ResizableCornerComponent.h *********/
#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__
#define __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__

/** A component that resizes a parent window when dragged.

    This is the small triangular stripey resizer component you get in the bottom-right
    of windows (more commonly on the Mac than Windows). Put one in the corner of
    a larger component and it will automatically resize its parent when it gets dragged
    around.

    @see ResizableFrameComponent
*/
class JUCE_API  ResizableCornerComponent  : public Component
{
public:

    /** Creates a resizer.

        Pass in the target component which you want to be resized when this one is
        dragged.

        The target component will usually be a parent of the resizer component, but this
        isn't mandatory.

        Remember that when the target component is resized, it'll need to move and
        resize this component to keep it in place, as this won't happen automatically.

        If the constrainer parameter is non-zero, then this object will be used to enforce
        limits on the size and position that the component can be stretched to. Make sure
        that the constrainer isn't deleted while still in use by this object. If you
        pass a zero in here, no limits will be put on the sizes it can be stretched to.

        @see ComponentBoundsConstrainer
    */
    ResizableCornerComponent (Component* const componentToResize,
                              ComponentBoundsConstrainer* const constrainer);

    /** Destructor. */
    ~ResizableCornerComponent();

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    void mouseUp (const MouseEvent& e);
    /** @internal */
    bool hitTest (int x, int y);

private:

    Component* const component;
    ComponentBoundsConstrainer* constrainer;
    int originalX, originalY, originalW, originalH;

    ResizableCornerComponent (const ResizableCornerComponent&);
    const ResizableCornerComponent& operator= (const ResizableCornerComponent&);
};

#endif   // __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_ResizableCornerComponent.h *********/

/**
    A base class for top-level windows that can be dragged around and resized.

    To add content to the window, use its setContentComponent() method to
    give it a component that will remain positioned inside it (leaving a gap around
    the edges for a border).

    It's not advisable to add child components directly to a ResizableWindow: put them
    inside your content component instead. And overriding methods like resized(), moved(), etc
    is also not recommended - instead override these methods for your content component.
    (If for some obscure reason you do need to override these methods, always remember to
    call the super-class's resized() method too, otherwise it'll fail to lay out the window
    decorations correctly).

    By default resizing isn't enabled - use the setResizable() method to enable it and
    to choose the style of resizing to use.

    @see TopLevelWindow
*/
class JUCE_API  ResizableWindow  : public TopLevelWindow
{
public:

    /** Creates a ResizableWindow.

        This constructor doesn't specify a background colour, so the LookAndFeel's default
        background colour will be used.

        @param name                 the name to give the component
        @param addToDesktop         if true, the window will be automatically added to the
                                    desktop; if false, you can use it as a child component
    */
    ResizableWindow (const String& name,
                     const bool addToDesktop);

    /** Creates a ResizableWindow.

        @param name                 the name to give the component
        @param backgroundColour     the colour to use for filling the window's background.
        @param addToDesktop         if true, the window will be automatically added to the
                                    desktop; if false, you can use it as a child component
    */
    ResizableWindow (const String& name,
                     const Colour& backgroundColour,
                     const bool addToDesktop);

    /** Destructor.

        If a content component has been set with setContentComponent(), it
        will be deleted.
    */
    ~ResizableWindow();

    /** Returns the colour currently being used for the window's background.

        As a convenience the window will fill itself with this colour, but you
        can override the paint() method if you need more customised behaviour.

        This method is the same as retrieving the colour for ResizableWindow::backgroundColourId.

        @see setBackgroundColour
    */
    const Colour getBackgroundColour() const throw();

    /** Changes the colour currently being used for the window's background.

        As a convenience the window will fill itself with this colour, but you
        can override the paint() method if you need more customised behaviour.

        Note that the opaque state of this window is altered by this call to reflect
        the opacity of the colour passed-in. On window systems which can't support
        semi-transparent windows this might cause problems, (though it's unlikely you'll
        be using this class as a base for a semi-transparent component anyway).

        You can also use the ResizableWindow::backgroundColourId colour id to set
        this colour.

        @see getBackgroundColour
    */
    void setBackgroundColour (const Colour& newColour);

    /** Make the window resizable or fixed.

        @param shouldBeResizable            whether it's resizable at all
        @param useBottomRightCornerResizer  if true, it'll add a ResizableCornerComponent at the
                                            bottom-right; if false, it'll use a ResizableBorderComponent
                                            around the edge
        @see setResizeLimits, isResizable
    */
    void setResizable (const bool shouldBeResizable,
                       const bool useBottomRightCornerResizer);

    /** True if resizing is enabled.

        @see setResizable
    */
    bool isResizable() const throw();

    /** This sets the maximum and minimum sizes for the window.

        If the window's current size is outside these limits, it will be resized to
        make sure it's within them.

        Calling setBounds() on the component will bypass any size checking - it's only when
        the window is being resized by the user that these values are enforced.

        @see setResizable, setFixedAspectRatio
    */
    void setResizeLimits (const int newMinimumWidth,
                          const int newMinimumHeight,
                          const int newMaximumWidth,
                          const int newMaximumHeight) throw();

    /** Returns the bounds constrainer object that this window is using.

        You can access this to change its properties.
    */
    ComponentBoundsConstrainer* getConstrainer() throw()            { return constrainer; }

    /** Sets the bounds-constrainer object to use for resizing and dragging this window.

        A pointer to the object you pass in will be kept, but it won't be deleted
        by this object, so it's the caller's responsiblity to manage it.

        If you pass 0, then no contraints will be placed on the positioning of the window.
    */
    void setConstrainer (ComponentBoundsConstrainer* newConstrainer);

    /** Calls the window's setBounds method, after first checking these bounds
        with the current constrainer.

        @see setConstrainer
    */
    void setBoundsConstrained (int x, int y, int width, int height);

    /** Returns true if the window is currently in full-screen mode.

        @see setFullScreen
    */
    bool isFullScreen() const;

    /** Puts the window into full-screen mode, or restores it to its normal size.

        If true, the window will become full-screen; if false, it will return to the
        last size it was before being made full-screen.

        @see isFullScreen
    */
    void setFullScreen (const bool shouldBeFullScreen);

    /** Returns true if the window is currently minimised.

        @see setMinimised
    */
    bool isMinimised() const;

    /** Minimises the window, or restores it to its previous position and size.

        When being un-minimised, it'll return to the last position and size it
        was in before being minimised.

        @see isMinimised
    */
    void setMinimised (const bool shouldMinimise);

    /** Returns a string which encodes the window's current size and position.

        This string will encapsulate the window's size, position, and whether it's
        in full-screen mode. It's intended for letting your application save and
        restore a window's position.

        Use the restoreWindowStateFromString() to restore from a saved state.

        @see restoreWindowStateFromString
    */
    const String getWindowStateAsString();

    /** Restores the window to a previously-saved size and position.

        This restores the window's size, positon and full-screen status from an
        string that was previously created with the getWindowStateAsString()
        method.

        @returns false if the string wasn't a valid window state
        @see getWindowStateAsString
    */
    bool restoreWindowStateFromString (const String& previousState);

    /** Returns the current content component.

        This will be the component set by setContentComponent(), or 0 if none
        has yet been specified.

        @see setContentComponent
    */
    Component* getContentComponent() const throw()                  { return contentComponent; }

    /** Changes the current content component.

        This sets a component that will be placed in the centre of the ResizableWindow,
        (leaving a space around the edge for the border).

        You should never add components directly to a ResizableWindow (or any of its subclasses)
        with addChildComponent(). Instead, add them to the content component.

        @param newContentComponent  the new component to use (or null to not use one) - this
                                    component will be deleted either when replaced by another call
                                    to this method, or when the ResizableWindow is deleted.
                                    To remove a content component without deleting it, use
                                    setContentComponent (0, false).
        @param deleteOldOne         if true, the previous content component will be deleted; if
                                    false, the previous component will just be removed without
                                    deleting it.
        @param resizeToFit          if true, the ResizableWindow will maintain its size such that
                                    it always fits around the size of the content component. If false, the
                                    new content will be resized to fit the current space available.
    */
    void setContentComponent (Component* const newContentComponent,
                              const bool deleteOldOne = true,
                              const bool resizeToFit = false);

    /** Changes the window so that the content component ends up with the specified size.

        This is basically a setSize call on the window, but which adds on the borders,
        so you can specify the content component's target size.
    */
    void setContentComponentSize (int width, int height);

    /** A set of colour IDs to use to change the colour of various aspects of the window.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId          = 0x1005700,  /**< A colour to use to fill the window's background. */
    };

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paint (Graphics& g);
    /** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */
    void moved();
    /** (if overriding this, make sure you call ResizableWindow::resized() in your subclass) */
    void resized();
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    void lookAndFeelChanged();
    /** @internal */
    void childBoundsChanged (Component* child);
    /** @internal */
    void parentSizeChanged();
    /** @internal */
    void visibilityChanged();
    /** @internal */
    void activeWindowStatusChanged();
    /** @internal */
    int getDesktopWindowStyleFlags() const;

    /** Returns the width of the border to use around the window.

        @see getContentComponentBorder
    */
    virtual const BorderSize getBorderThickness();

    /** Returns the insets to use when positioning the content component.

        @see getBorderThickness
    */
    virtual const BorderSize getContentComponentBorder();

#ifdef JUCE_DEBUG
    /** Overridden to warn people about adding components directly to this component
        instead of using setContentComponent().

        If you know what you're doing and are sure you really want to add a component, specify
        a base-class method call to Component::addAndMakeVisible(), to side-step this warning.
    */
    void addChildComponent (Component* const child, int zOrder = -1);
    /** Overridden to warn people about adding components directly to this component
        instead of using setContentComponent().

        If you know what you're doing and are sure you really want to add a component, specify
        a base-class method call to Component::addAndMakeVisible(), to side-step this warning.
    */
    void addAndMakeVisible (Component* const child, int zOrder = -1);

#endif

    ResizableCornerComponent* resizableCorner;
    ResizableBorderComponent* resizableBorder;

private:
    Component* contentComponent;
    bool resizeToFitContent, fullscreen;
    ComponentDragger dragger;
    Rectangle lastNonFullScreenPos;
    ComponentBoundsConstrainer defaultConstrainer;
    ComponentBoundsConstrainer* constrainer;
    #ifdef JUCE_DEBUG
    bool hasBeenResized;
    #endif

    void updateLastPos();

    ResizableWindow (const ResizableWindow&);
    const ResizableWindow& operator= (const ResizableWindow&);

    // (xxx remove these eventually)
    // temporarily here to stop old code compiling, as the parameters for these methods have changed..
    void getBorderThickness (int& left, int& top, int& right, int& bottom);
    // temporarily here to stop old code compiling, as the parameters for these methods have changed..
    void getContentComponentBorder (int& left, int& top, int& right, int& bottom);
};

#endif   // __JUCE_RESIZABLEWINDOW_JUCEHEADER__
/********* End of inlined file: juce_ResizableWindow.h *********/

/**
    A resizable window with a title bar and maximise, minimise and close buttons.

    This subclass of ResizableWindow creates a fairly standard type of window with
    a title bar and various buttons. The name of the component is shown in the
    title bar, and an icon can optionally be specified with setIcon().

    All the methods available to a ResizableWindow are also available to this,
    so it can easily be made resizable, minimised, maximised, etc.

    It's not advisable to add child components directly to a DocumentWindow: put them
    inside your content component instead. And overriding methods like resized(), moved(), etc
    is also not recommended - instead override these methods for your content component.
    (If for some obscure reason you do need to override these methods, always remember to
    call the super-class's resized() method too, otherwise it'll fail to lay out the window
    decorations correctly).

    You can also automatically add a menu bar to the window, using the setMenuBar()
    method.

    @see ResizableWindow, DialogWindow
*/
class JUCE_API  DocumentWindow   : public ResizableWindow
{
public:

    /** The set of available button-types that can be put on the title bar.

        @see setTitleBarButtonsRequired
    */
    enum TitleBarButtons
    {
        minimiseButton = 1,
        maximiseButton = 2,
        closeButton = 4,

        /** A combination of all the buttons above. */
        allButtons = 7
    };

    /** Creates a DocumentWindow.

        @param name             the name to give the component - this is also
                                the title shown at the top of the window. To change
                                this later, use setName()
        @param backgroundColour the colour to use for filling the window's background.
        @param requiredButtons  specifies which of the buttons (close, minimise, maximise)
                                should be shown on the title bar. This value is a bitwise
                                combination of values from the TitleBarButtons enum. Note
                                that it can be "allButtons" to get them all. You
                                can change this later with the setTitleBarButtonsRequired()
                                method, which can also specify where they are positioned.
        @param addToDesktop     if true, the window will be automatically added to the
                                desktop; if false, you can use it as a child component
        @see TitleBarButtons
    */
    DocumentWindow (const String& name,
                    const Colour& backgroundColour,
                    const int requiredButtons,
                    const bool addToDesktop = true);

    /** Destructor.

        If a content component has been set with setContentComponent(), it
        will be deleted.
    */
    ~DocumentWindow();

    /** Changes the component's name.

        (This is overridden from Component::setName() to cause a repaint, as
        the name is what gets drawn across the window's title bar).
    */
    void setName (const String& newName);

    /** Sets an icon to show in the title bar, next to the title.

        A copy is made internally of the image, so the caller can delete the
        image after calling this. If 0 is passed-in, any existing icon will be
        removed.
    */
    void setIcon (const Image* imageToUse);

    /** Changes the height of the title-bar. */
    void setTitleBarHeight (const int newHeight);

    /** Returns the current title bar height. */
    int getTitleBarHeight() const;

    /** Changes the set of title-bar buttons being shown.

        @param requiredButtons  specifies which of the buttons (close, minimise, maximise)
                                should be shown on the title bar. This value is a bitwise
                                combination of values from the TitleBarButtons enum. Note
                                that it can be "allButtons" to get them all.
        @param positionTitleBarButtonsOnLeft    if true, the buttons should go at the
                                left side of the bar; if false, they'll be placed at the right
    */
    void setTitleBarButtonsRequired (const int requiredButtons,
                                     const bool positionTitleBarButtonsOnLeft);

    /** Sets whether the title should be centred within the window.

        If true, the title text is shown in the middle of the title-bar; if false,
        it'll be shown at the left of the bar.
    */
    void setTitleBarTextCentred (const bool textShouldBeCentred);

    /** Creates a menu inside this window.

        @param menuBarModel     this specifies a MenuBarModel that should be used to
                                generate the contents of a menu bar that will be placed
                                just below the title bar, and just above any content
                                component. If this value is zero, any existing menu bar
                                will be removed from the component; if non-zero, one will
                                be added if it's required.
        @param menuBarHeight    the height of the menu bar component, if one is needed. Pass a value of zero
                                or less to use the look-and-feel's default size.
    */
    void setMenuBar (MenuBarModel* menuBarModel,
                     const int menuBarHeight = 0);

    /** This method is called when the user tries to close the window.

        This is triggered by the user clicking the close button, or using some other
        OS-specific key shortcut or OS menu for getting rid of a window.

        If the window is just a pop-up, you should override this closeButtonPressed()
        method and make it delete the window in whatever way is appropriate for your
        app. E.g. you might just want to call "delete this".

        If your app is centred around this window such that the whole app should quit when
        the window is closed, then you will probably want to use this method as an opportunity
        to call JUCEApplication::quit(), and leave the window to be deleted later by your
        JUCEApplication::shutdown() method. (Doing it this way means that your window will
        still get cleaned-up if the app is quit by some other means (e.g. a cmd-Q on the mac
        or closing it via the taskbar icon on Windows).

        (Note that the DocumentWindow class overrides Component::userTriedToCloseWindow() and
        redirects it to call this method, so any methods of closing the window that are
        caught by userTriedToCloseWindow() will also end up here).
    */
    virtual void closeButtonPressed();

    /** Callback that is triggered when the minimise button is pressed.

        The default implementation of this calls ResizableWindow::setMinimised(), but
        you can override it to do more customised behaviour.
    */
    virtual void minimiseButtonPressed();

    /** Callback that is triggered when the maximise button is pressed, or when the
        title-bar is double-clicked.

        The default implementation of this calls ResizableWindow::setFullScreen(), but
        you can override it to do more customised behaviour.
    */
    virtual void maximiseButtonPressed();

    /** Returns the close button, (or 0 if there isn't one). */
    Button* getCloseButton() const throw();

    /** Returns the minimise button, (or 0 if there isn't one). */
    Button* getMinimiseButton() const throw();

    /** Returns the maximise button, (or 0 if there isn't one). */
    Button* getMaximiseButton() const throw();

    /** A set of colour IDs to use to change the colour of various aspects of the window.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        textColourId                = 0x1005701,  /**< The colour to draw any text with. It's up to the look
                                                       and feel class how this is used. */
    };

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void lookAndFeelChanged();
    /** @internal */
    const BorderSize getBorderThickness();
    /** @internal */
    const BorderSize getContentComponentBorder();
    /** @internal */
    void mouseDoubleClick (const MouseEvent& e);
    /** @internal */
    void userTriedToCloseWindow();
    /** @internal */
    void activeWindowStatusChanged();
    /** @internal */
    int getDesktopWindowStyleFlags() const;
    /** @internal */
    void parentHierarchyChanged();

    juce_UseDebuggingNewOperator

private:
    int titleBarHeight, menuBarHeight, requiredButtons;
    bool positionTitleBarButtonsOnLeft, drawTitleTextCentred;
    Button* titleBarButtons [3];
    Image* titleBarIcon;
    MenuBarComponent* menuBar;
    MenuBarModel* menuBarModel;

    class ButtonListenerProxy   : public ButtonListener
    {
    public:
        ButtonListenerProxy();
        void buttonClicked (Button* button);

        DocumentWindow* owner;

    } buttonListener;

    int getBorderSize() const;
    void repaintTitleBar();

    DocumentWindow (const DocumentWindow&);
    const DocumentWindow& operator= (const DocumentWindow&);
};

#endif   // __JUCE_DOCUMENTWINDOW_JUCEHEADER__
/********* End of inlined file: juce_DocumentWindow.h *********/

class MultiDocumentPanel;
class MDITabbedComponentInternal;

/**
    This is a derivative of DocumentWindow that is used inside a MultiDocumentPanel
    component.

    It's like a normal DocumentWindow but has some extra functionality to make sure
    everything works nicely inside a MultiDocumentPanel.

    @see MultiDocumentPanel
*/
class JUCE_API  MultiDocumentPanelWindow  : public DocumentWindow
{
public:

    /**
    */
    MultiDocumentPanelWindow (const Colour& backgroundColour);

    /** Destructor. */
    ~MultiDocumentPanelWindow();

    /** @internal */
    void maximiseButtonPressed();
    /** @internal */
    void closeButtonPressed();
    /** @internal */
    void activeWindowStatusChanged();
    /** @internal */
    void broughtToFront();

    juce_UseDebuggingNewOperator

private:
    void updateOrder();
    MultiDocumentPanel* getOwner() const throw();
};

/**
    A component that contains a set of other components either in floating windows
    or tabs.

    This acts as a panel that can be used to hold a set of open document windows, with
    different layout modes.

    Use addDocument() and closeDocument() to add or remove components from the
    panel - never use any of the Component methods to access the panel's child
    components directly, as these are managed internally.
*/
class JUCE_API  MultiDocumentPanel  : public Component,
                                      private ComponentListener
{
public:

    /** Creates an empty panel.

        Use addDocument() and closeDocument() to add or remove components from the
        panel - never use any of the Component methods to access the panel's child
        components directly, as these are managed internally.
    */
    MultiDocumentPanel();

    /** Destructor.

        When deleted, this will call closeAllDocuments (false) to make sure all its
        components are deleted. If you need to make sure all documents are saved
        before closing, then you should call closeAllDocuments (true) and check that
        it returns true before deleting the panel.
    */
    ~MultiDocumentPanel();

    /** Tries to close all the documents.

        If checkItsOkToCloseFirst is true, then the tryToCloseDocument() method will
        be called for each open document, and any of these calls fails, this method
        will stop and return false, leaving some documents still open.

        If checkItsOkToCloseFirst is false, then all documents will be closed
        unconditionally.

        @see closeDocument
    */
    bool closeAllDocuments (const bool checkItsOkToCloseFirst);

    /** Adds a document component to the panel.

        If the number of documents would exceed the limit set by setMaximumNumDocuments() then
        this will fail and return false. (If it does fail, the component passed-in will not be
        deleted, even if deleteWhenRemoved was set to true).

        The MultiDocumentPanel will deal with creating a window border to go around your component,
        so just pass in the bare content component here, no need to give it a ResizableWindow
        or DocumentWindow.

        @param component            the component to add
        @param backgroundColour     the background colour to use to fill the component's
                                    window or tab
        @param deleteWhenRemoved    if true, then when the component is removed by closeDocument()
                                    or closeAllDocuments(), then it will be deleted. If false, then
                                    the caller must handle the component's deletion
    */
    bool addDocument (Component* const component,
                      const Colour& backgroundColour,
                      const bool deleteWhenRemoved);

    /** Closes one of the documents.

        If checkItsOkToCloseFirst is true, then the tryToCloseDocument() method will
        be called, and if it fails, this method will return false without closing the
        document.

        If checkItsOkToCloseFirst is false, then the documents will be closed
        unconditionally.

        The component will be deleted if the deleteWhenRemoved parameter was set to
        true when it was added with addDocument.

        @see addDocument, closeAllDocuments
    */
    bool closeDocument (Component* component,
                        const bool checkItsOkToCloseFirst);

    /** Returns the number of open document windows.

        @see getDocument
    */
    int getNumDocuments() const throw();

    /** Returns one of the open documents.

        The order of the documents in this array may change when they are added, removed
        or moved around.

        @see getNumDocuments
    */
    Component* getDocument (const int index) const throw();

    /** Returns the document component that is currently focused or on top.

        If currently using floating windows, then this will be the component in the currently
        active window, or the top component if none are active.

        If it's currently in tabbed mode, then it'll return the component in the active tab.

        @see setActiveDocument
    */
    Component* getActiveDocument() const throw();

    /** Makes one of the components active and brings it to the top.

        @see getActiveDocument
    */
    void setActiveDocument (Component* component);

    /** Callback which gets invoked when the currently-active document changes. */
    virtual void activeDocumentChanged();

    /** Sets a limit on how many windows can be open at once.

        If this is zero or less there's no limit (the default). addDocument() will fail
        if this number is exceeded.
    */
    void setMaximumNumDocuments (const int maximumNumDocuments);

    /** Sets an option to make the document fullscreen if there's only one document open.

        If set to true, then if there's only one document, it'll fill the whole of this
        component without tabs or a window border. If false, then tabs or a window
        will always be shown, even if there's only one document. If there's more than
        one document open, then this option makes no difference.
    */
    void useFullscreenWhenOneDocument (const bool shouldUseTabs);

    /** Returns the result of the last time useFullscreenWhenOneDocument() was called.
    */
    bool isFullscreenWhenOneDocument() const throw();

    /** The different layout modes available. */
    enum LayoutMode
    {
        FloatingWindows,            /**< In this mode, there are overlapping DocumentWindow components for each document. */
        MaximisedWindowsWithTabs    /**< In this mode, a TabbedComponent is used to show one document at a time. */
    };

    /** Changes the panel's mode.

        @see LayoutMode, getLayoutMode
    */
    void setLayoutMode (const LayoutMode newLayoutMode);

    /** Returns the current layout mode. */
    LayoutMode getLayoutMode() const throw()                            { return mode; }

    /** Sets the background colour for the whole panel.

        Each document has its own background colour, but this is the one used to fill the areas
        behind them.
    */
    void setBackgroundColour (const Colour& newBackgroundColour);

    /** Returns the current background colour.

        @see setBackgroundColour
    */
    const Colour& getBackgroundColour() const throw()                   { return backgroundColour; }

    /** A subclass must override this to say whether its currently ok for a document
        to be closed.

        This method is called by closeDocument() and closeAllDocuments() to indicate that
        a document should be saved if possible, ready for it to be closed.

        If this method returns true, then it means the document is ok and can be closed.

        If it returns false, then it means that the closeDocument() method should stop
        and not close.

        Normally, you'd use this method to ask the user if they want to save any changes,
        then return true if the save operation went ok. If the user cancelled the save
        operation you could return false here to abort the close operation.

        If your component is based on the FileBasedDocument class, then you'd probably want
        to call FileBasedDocument::saveIfNeededAndUserAgrees() and return true if this returned
        FileBasedDocument::savedOk

        @see closeDocument, FileBasedDocument::saveIfNeededAndUserAgrees()
    */
    virtual bool tryToCloseDocument (Component* component) = 0;

    /** Creates a new window to be used for a document.

        The default implementation of this just returns a basic MultiDocumentPanelWindow object,
        but you might want to override it to return a custom component.
    */
    virtual MultiDocumentPanelWindow* createNewDocumentWindow();

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void componentNameChanged (Component&);

    juce_UseDebuggingNewOperator

private:
    LayoutMode mode;
    Array <Component*> components;
    TabbedComponent* tabComponent;
    Colour backgroundColour;
    int maximumNumDocuments, numDocsBeforeTabsUsed;

    friend class MultiDocumentPanelWindow;
    friend class MDITabbedComponentInternal;

    Component* getContainerComp (Component* c) const;
    void updateOrder();

    void addWindow (Component* component);
};

#endif   // __JUCE_MULTIDOCUMENTPANEL_JUCEHEADER__
/********* End of inlined file: juce_MultiDocumentPanel.h *********/

#endif
#ifndef __JUCE_RESIZABLEBORDERCOMPONENT_JUCEHEADER__

#endif
#ifndef __JUCE_RESIZABLECORNERCOMPONENT_JUCEHEADER__

#endif
#ifndef __JUCE_SCROLLBAR_JUCEHEADER__

#endif
#ifndef __JUCE_TABBEDBUTTONBAR_JUCEHEADER__

#endif
#ifndef __JUCE_TABBEDCOMPONENT_JUCEHEADER__

#endif
#ifndef __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__

/********* Start of inlined file: juce_StretchableLayoutManager.h *********/
#ifndef __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__
#define __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__

/**
    For laying out a set of components, where the components have preferred sizes
    and size limits, but where they are allowed to stretch to fill the available
    space.

    For example, if you have a component containing several other components, and
    each one should be given a share of the total size, you could use one of these
    to resize the child components when the parent component is resized. Then
    you could add a StretchableLayoutResizerBar to easily let the user rescale them.

    A StretchableLayoutManager operates only in one dimension, so if you have a set
    of components stacked vertically on top of each other, you'd use one to manage their
    heights. To build up complex arrangements of components, e.g. for applications
    with multiple nested panels, you would use more than one StretchableLayoutManager.
    E.g. by using two (one vertical, one horizontal), you could create a resizable
    spreadsheet-style table.

    E.g.
    @code
    class MyComp  : public Component
    {
        StretchableLayoutManager myLayout;

        MyComp()
        {
            myLayout.setItemLayout (0,          // for item 0
                                    50, 100,    // must be between 50 and 100 pixels in size
                                    -0.6);      // and its preferred size is 60% of the total available space

            myLayout.setItemLayout (1,          // for item 1
                                    -0.2, -0.6, // size must be between 20% and 60% of the available space
                                    50);        // and its preferred size is 50 pixels
        }

        void resized()
        {
            // make a list of two of our child components that we want to reposition
            Component* comps[] = { myComp1, myComp2 };

            // this will position the 2 components, one above the other, to fit
            // vertically into the rectangle provided.
            myLayout.layOutComponents (comps, 2,
                                       0, 0, getWidth(), getHeight(),
                                       true);
        }
    };
    @endcode

    @see StretchableLayoutResizerBar
*/
class JUCE_API  StretchableLayoutManager
{
public:

    /** Creates an empty layout.

        You'll need to add some item properties to the layout before it can be used
        to resize things - see setItemLayout().
    */
    StretchableLayoutManager();

    /** Destructor. */
    ~StretchableLayoutManager();

    /** For a numbered item, this sets its size limits and preferred size.

        @param itemIndex        the index of the item to change.
        @param minimumSize      the minimum size that this item is allowed to be - a positive number
                                indicates an absolute size in pixels. A negative number indicates a
                                proportion of the available space (e.g -0.5 is 50%)
        @param maximumSize      the maximum size that this item is allowed to be - a positive number
                                indicates an absolute size in pixels. A negative number indicates a
                                proportion of the available space
        @param preferredSize    the size that this item would like to be, if there's enough room. A
                                positive number indicates an absolute size in pixels. A negative number
                                indicates a proportion of the available space
        @see getItemLayout
    */
    void setItemLayout (const int itemIndex,
                        const double minimumSize,
                        const double maximumSize,
                        const double preferredSize);

    /** For a numbered item, this returns its size limits and preferred size.

        @param itemIndex        the index of the item.
        @param minimumSize      the minimum size that this item is allowed to be - a positive number
                                indicates an absolute size in pixels. A negative number indicates a
                                proportion of the available space (e.g -0.5 is 50%)
        @param maximumSize      the maximum size that this item is allowed to be - a positive number
                                indicates an absolute size in pixels. A negative number indicates a
                                proportion of the available space
        @param preferredSize    the size that this item would like to be, if there's enough room. A
                                positive number indicates an absolute size in pixels. A negative number
                                indicates a proportion of the available space
        @returns false if the item's properties hadn't been set
        @see setItemLayout
    */
    bool getItemLayout (const int itemIndex,
                        double& minimumSize,
                        double& maximumSize,
                        double& preferredSize) const;

    /** Clears all the properties that have been set with setItemLayout() and resets
        this object to its initial state.
    */
    void clearAllItems();

    /** Takes a set of components that correspond to the layout's items, and positions
        them to fill a space.

        This will try to give each item its preferred size, whether that's a relative size
        or an absolute one.

        @param components       an array of components that correspond to each of the
                                numbered items that the StretchableLayoutManager object
                                has been told about with setItemLayout()
        @param numComponents    the number of components in the array that is passed-in. This
                                should be the same as the number of items this object has been
                                told about.
        @param x                the left of the rectangle in which the components should
                                be laid out
        @param y                the top of the rectangle in which the components should
                                be laid out
        @param width            the width of the rectangle in which the components should
                                be laid out
        @param height           the height of the rectangle in which the components should
                                be laid out
        @param vertically       if true, the components will be positioned in a vertical stack,
                                so that they fill the height of the rectangle. If false, they
                                will be placed side-by-side in a horizontal line, filling the
                                available width
        @param resizeOtherDimension     if true, this means that the components will have their
                                other dimension resized to fit the space - i.e. if the 'vertically'
                                parameter is true, their x-positions and widths are adjusted to fit
                                the x and width parameters; if 'vertically' is false, their y-positions
                                and heights are adjusted to fit the y and height parameters.
    */
    void layOutComponents (Component** const components,
                           int numComponents,
                           int x, int y, int width, int height,
                           const bool vertically,
                           const bool resizeOtherDimension);

    /** Returns the current position of one of the items.

        This is only a valid call after layOutComponents() has been called, as it
        returns the last position that this item was placed at. If the layout was
        vertical, the value returned will be the y position of the top of the item,
        relative to the top of the rectangle in which the items were placed (so for
        example, item 0 will always have position of 0, even in the rectangle passed
        in to layOutComponents() wasn't at y = 0). If the layout was done horizontally,
        the position returned is the item's left-hand position, again relative to the
        x position of the rectangle used.

        @see getItemCurrentSize, setItemPosition
    */
    int getItemCurrentPosition (const int itemIndex) const;

    /** Returns the current size of one of the items.

        This is only meaningful after layOutComponents() has been called, as it
        returns the last size that this item was given. If the layout was done
        vertically, it'll return the item's height in pixels; if it was horizontal,
        it'll return its width.

        @see getItemCurrentRelativeSize
    */
    int getItemCurrentAbsoluteSize (const int itemIndex) const;

    /** Returns the current size of one of the items.

        This is only meaningful after layOutComponents() has been called, as it
        returns the last size that this item was given. If the layout was done
        vertically, it'll return a negative value representing the item's height relative
        to the last size used for laying the components out; if the layout was done
        horizontally it'll be the proportion of its width.

        @see getItemCurrentAbsoluteSize
    */
    double getItemCurrentRelativeSize (const int itemIndex) const;

    /** Moves one of the items, shifting along any other items as necessary in
        order to get it to the desired position.

        Calling this method will also update the preferred sizes of the items it
        shuffles along, so that they reflect their new positions.

        (This is the method that a StretchableLayoutResizerBar uses to shift the items
        about when it's dragged).

        @param itemIndex        the item to move
        @param newPosition      the absolute position that you'd like this item to move
                                to. The item might not be able to always reach exactly this position,
                                because other items may have minimum sizes that constrain how
                                far it can go
    */
    void setItemPosition (const int itemIndex,
                          int newPosition);

    juce_UseDebuggingNewOperator

private:
    struct ItemLayoutProperties
    {
        int itemIndex;
        int currentSize;
        double minSize, maxSize, preferredSize;
    };

    OwnedArray <ItemLayoutProperties> items;
    int totalSize;

    static int sizeToRealSize (double size, int totalSpace);

    ItemLayoutProperties* getInfoFor (const int itemIndex) const;

    void setTotalSize (const int newTotalSize);

    int fitComponentsIntoSpace (const int startIndex,
                                const int endIndex,
                                const int availableSpace,
                                int startPos);

    int getMinimumSizeOfItems (const int startIndex, const int endIndex) const;
    int getMaximumSizeOfItems (const int startIndex, const int endIndex) const;

    void updatePrefSizesToMatchCurrentPositions();

    StretchableLayoutManager (const StretchableLayoutManager&);
    const StretchableLayoutManager& operator= (const StretchableLayoutManager&);
};

#endif   // __JUCE_STRETCHABLELAYOUTMANAGER_JUCEHEADER__
/********* End of inlined file: juce_StretchableLayoutManager.h *********/

#endif
#ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__

/********* Start of inlined file: juce_StretchableLayoutResizerBar.h *********/
#ifndef __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__
#define __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__

/**
    A component that acts as one of the vertical or horizontal bars you see being
    used to resize panels in a window.

    One of these acts with a StretchableLayoutManager to resize the other components.

    @see StretchableLayoutManager
*/
class JUCE_API  StretchableLayoutResizerBar  : public Component
{
public:

    /** Creates a resizer bar for use on a specified layout.

        @param layoutToUse          the layout that will be affected when this bar
                                    is dragged
        @param itemIndexInLayout    the item index in the layout that corresponds to
                                    this bar component. You'll need to set up the item
                                    properties in a suitable way for a divider bar, e.g.
                                    for an 8-pixel wide bar which, you could call
                                    myLayout->setItemLayout (barIndex, 8, 8, 8)
        @param isBarVertical        true if it's an upright bar that you drag left and
                                    right; false for a horizontal one that you drag up and
                                    down
    */
    StretchableLayoutResizerBar (StretchableLayoutManager* const layoutToUse,
                                 const int itemIndexInLayout,
                                 const bool isBarVertical);

    /** Destructor. */
    ~StretchableLayoutResizerBar();

    /** This is called when the bar is dragged.

        This method must update the positions of any components whose position is
        determined by the StretchableLayoutManager, because they might have just
        moved.

        The default implementation calls the resized() method of this component's
        parent component, because that's often where you're likely to apply the
        layout, but it can be overridden for more specific needs.
    */
    virtual void hasBeenMoved();

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);

    juce_UseDebuggingNewOperator

private:
    StretchableLayoutManager* layout;
    int itemIndex, mouseDownPos;
    bool isVertical;

    StretchableLayoutResizerBar (const StretchableLayoutResizerBar&);
    const StretchableLayoutResizerBar& operator= (const StretchableLayoutResizerBar&);
};

#endif   // __JUCE_STRETCHABLELAYOUTRESIZERBAR_JUCEHEADER__
/********* End of inlined file: juce_StretchableLayoutResizerBar.h *********/

#endif
#ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__

/********* Start of inlined file: juce_StretchableObjectResizer.h *********/
#ifndef __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__
#define __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__

/**
    A utility class for fitting a set of objects whose sizes can vary between
    a minimum and maximum size, into a space.

    This is a trickier algorithm than it would first seem, so I've put it in this
    class to allow it to be shared by various bits of code.

    To use it, create one of these objects, call addItem() to add the list of items
    you need, then call resizeToFit(), which will change all their sizes. You can
    then retrieve the new sizes with getItemSize() and getNumItems().

    It's currently used by the TableHeaderComponent for stretching out the table
    headings to fill the table's width.
*/
class StretchableObjectResizer
{
public:

    /** Creates an empty object resizer. */
    StretchableObjectResizer();

    /** Destructor. */
    ~StretchableObjectResizer();

    /** Adds an item to the list.

        The order parameter lets you specify groups of items that are resized first when some
        space needs to be found. Those items with an order of 0 will be the first ones to be
        resized, and if that doesn't provide enough space to meet the requirements, the algorithm
        will then try resizing the items with an order of 1, then 2, and so on.
    */
    void addItem (const double currentSize,
                  const double minSize,
                  const double maxSize,
                  const int order = 0);

    /** Resizes all the items to fit this amount of space.

        This will attempt to fit them in without exceeding each item's miniumum and
        maximum sizes. In cases where none of the items can be expanded or enlarged any
        further, the final size may be greater or less than the size passed in.

        After calling this method, you can retrieve the new sizes with the getItemSize()
        method.
    */
    void resizeToFit (const double targetSize);

    /** Returns the number of items that have been added. */
    int getNumItems() const throw()                         { return items.size(); }

    /** Returns the size of one of the items. */
    double getItemSize (const int index) const throw();

    juce_UseDebuggingNewOperator

private:
    struct Item
    {
        double size;
        double minSize;
        double maxSize;
        int order;
    };

    OwnedArray <Item> items;

    StretchableObjectResizer (const StretchableObjectResizer&);
    const StretchableObjectResizer& operator= (const StretchableObjectResizer&);
};

#endif   // __JUCE_STRETCHABLEOBJECTRESIZER_JUCEHEADER__
/********* End of inlined file: juce_StretchableObjectResizer.h *********/

#endif
#ifndef __JUCE_VIEWPORT_JUCEHEADER__

#endif
#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_DirectoryContentsDisplayComponent.h *********/
#ifndef __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__
#define __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_DirectoryContentsList.h *********/
#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__
#define __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__

/********* Start of inlined file: juce_FileFilter.h *********/
#ifndef __JUCE_FILEFILTER_JUCEHEADER__
#define __JUCE_FILEFILTER_JUCEHEADER__

/**
    Interface for deciding which files are suitable for something.

    For example, this is used by DirectoryContentsList to select which files
    go into the list.

    @see WildcardFileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
*/
class JUCE_API  FileFilter
{
public:

    /** Creates a filter with the given description.

        The description can be returned later with the getDescription() method.
    */
    FileFilter (const String& filterDescription);

    /** Destructor. */
    virtual ~FileFilter();

    /** Returns the description that the filter was created with. */
    const String& getDescription() const throw();

    /** Should return true if this file is suitable for inclusion in whatever context
        the object is being used.
    */
    virtual bool isFileSuitable (const File& file) const = 0;

    /** Should return true if this directory is suitable for inclusion in whatever context
        the object is being used.
    */
    virtual bool isDirectorySuitable (const File& file) const = 0;

protected:

    String description;
};

#endif   // __JUCE_FILEFILTER_JUCEHEADER__
/********* End of inlined file: juce_FileFilter.h *********/

/**
    A class to asynchronously scan for details about the files in a directory.

    This keeps a list of files and some information about them, using a background
    thread to scan for more files. As files are found, it broadcasts change messages
    to tell any listeners.

    @see FileListComponent, FileBrowserComponent
*/
class JUCE_API  DirectoryContentsList   : public ChangeBroadcaster,
                                          public TimeSliceClient
{
public:

    /** Creates a directory list.

        To set the directory it should point to, use setDirectory(), which will
        also start it scanning for files on the background thread.

        When the background thread finds and adds new files to this list, the
        ChangeBroadcaster class will send a change message, so you can register
        listeners and update them when the list changes.

        @param fileFilter       an optional filter to select which files are
                                included in the list. If this is 0, then all files
                                and directories are included. Make sure that the
                                filter doesn't get deleted during the lifetime of this
                                object
        @param threadToUse      a thread object that this list can use
                                to scan for files as a background task. Make sure
                                that the thread you give it has been started, or you
                                won't get any files!
    */
    DirectoryContentsList (const FileFilter* const fileFilter,
                           TimeSliceThread& threadToUse);

    /** Destructor. */
    ~DirectoryContentsList();

    /** Sets the directory to look in for files.

        If the directory that's passed in is different to the current one, this will
        also start the background thread scanning it for files.
    */
    void setDirectory (const File& directory,
                       const bool includeDirectories,
                       const bool includeFiles);

    /** Returns the directory that's currently being used. */
    const File& getDirectory() const throw();

    /** Clears the list, and stops the thread scanning for files. */
    void clear();

    /** Clears the list and restarts scanning the directory for files. */
    void refresh();

    /** True if the background thread hasn't yet finished scanning for files. */
    bool isStillLoading() const;

    /** Tells the list whether or not to ignore hidden files.

        By default these are ignored.
    */
    void setIgnoresHiddenFiles (const bool shouldIgnoreHiddenFiles);

    /** Returns true if hidden files are ignored.
        @see setIgnoresHiddenFiles
    */
    bool ignoresHiddenFiles() const throw()          { return ignoreHiddenFiles; }

    /** Contains cached information about one of the files in a DirectoryContentsList.
    */
    struct FileInfo
    {

        /** The filename.

            This isn't a full pathname, it's just the last part of the path, same as you'd
            get from File::getFileName().

            To get the full pathname, use DirectoryContentsList::getDirectory().getChildFile (filename).
        */
        String filename;

        /** File size in bytes. */
        int64 fileSize;

        /** File modification time.

            As supplied by File::getLastModificationTime().
        */
        Time modificationTime;

        /** File creation time.

            As supplied by File::getCreationTime().
        */
        Time creationTime;

        /** True if the file is a directory. */
        bool isDirectory;

        /** True if the file is read-only. */
        bool isReadOnly;
    };

    /** Returns the number of files currently available in the list.

        The info about one of these files can be retrieved with getFileInfo() or
        getFile().

        Obviously as the background thread runs and scans the directory for files, this
        number will change.

        @see getFileInfo, getFile
    */
    int getNumFiles() const;

    /** Returns the cached information about one of the files in the list.

        If the index is in-range, this will return true and will copy the file's details
        to the structure that is passed-in.

        If it returns false, then the index wasn't in range, and the structure won't
        be affected.

        @see getNumFiles, getFile
    */
    bool getFileInfo (const int index,
                      FileInfo& resultInfo) const;

    /** Returns one of the files in the list.

        @param index    should be less than getNumFiles(). If this is out-of-range, the
                        return value will be File::nonexistent
        @see getNumFiles, getFileInfo
    */
    const File getFile (const int index) const;

    /** Returns the file filter being used.

        The filter is specified in the constructor.
    */
    const FileFilter* getFilter() const throw()             { return fileFilter; }

    /** @internal */
    bool useTimeSlice();
    /** @internal */
    TimeSliceThread& getTimeSliceThread() throw()           { return thread; }
    /** @internal */
    static int compareElements (const DirectoryContentsList::FileInfo* const first,
                                const DirectoryContentsList::FileInfo* const second) throw();

    juce_UseDebuggingNewOperator

private:
    File root;
    const FileFilter* fileFilter;
    TimeSliceThread& thread;
    bool includeDirectories, includeFiles, ignoreHiddenFiles;

    CriticalSection fileListLock;
    OwnedArray <FileInfo> files;

    void* volatile fileFindHandle;
    bool volatile shouldStop;

    void changed();
    bool checkNextFile (bool& hasChanged);
    bool addFile (const String& filename, const bool isDir, const bool isHidden,
                  const int64 fileSize, const Time& modTime,
                  const Time& creationTime, const bool isReadOnly);

    DirectoryContentsList (const DirectoryContentsList&);
    const DirectoryContentsList& operator= (const DirectoryContentsList&);
};

#endif   // __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__
/********* End of inlined file: juce_DirectoryContentsList.h *********/

/********* Start of inlined file: juce_FileBrowserListener.h *********/
#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__
#define __JUCE_FILEBROWSERLISTENER_JUCEHEADER__

/**
    A listener for user selection events in a file browser.

    This is used by a FileBrowserComponent or FileListComponent.
*/
class JUCE_API  FileBrowserListener
{
public:

    /** Destructor. */
    virtual ~FileBrowserListener();

    /** Callback when the user selects a different file in the browser. */
    virtual void selectionChanged() = 0;

    /** Callback when the user clicks on a file in the browser. */
    virtual void fileClicked (const File& file, const MouseEvent& e) = 0;

    /** Callback when the user double-clicks on a file in the browser. */
    virtual void fileDoubleClicked (const File& file) = 0;
};

#endif   // __JUCE_FILEBROWSERLISTENER_JUCEHEADER__
/********* End of inlined file: juce_FileBrowserListener.h *********/

/**
    A base class for components that display a list of the files in a directory.

    @see DirectoryContentsList
*/
class JUCE_API  DirectoryContentsDisplayComponent
{
public:

    /**
    */
    DirectoryContentsDisplayComponent (DirectoryContentsList& listToShow);

    /** Destructor. */
    virtual ~DirectoryContentsDisplayComponent();

    /** Returns the file that the user has currently selected.

        Returns File::nonexistent if none is selected.
    */
    virtual const File getSelectedFile() const = 0;

    /** Scrolls this view to the top. */
    virtual void scrollToTop() = 0;

    /** Adds a listener to be told when files are selected or clicked.

        @see removeListener
    */
    void addListener (FileBrowserListener* const listener) throw();

    /** Removes a listener.

        @see addListener
    */
    void removeListener (FileBrowserListener* const listener) throw();

    /** A set of colour IDs to use to change the colour of various aspects of the label.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        Note that you can also use the constants from TextEditor::ColourIds to change the
        colour of the text editor that is opened when a label is editable.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        highlightColourId      = 0x1000540, /**< The colour to use to fill a highlighted row of the list. */
        textColourId           = 0x1000541, /**< The colour for the text. */
    };

    /** @internal */
    void sendSelectionChangeMessage();
    /** @internal */
    void sendDoubleClickMessage (const File& file);
    /** @internal */
    void sendMouseClickMessage (const File& file, const MouseEvent& e);

    juce_UseDebuggingNewOperator

protected:
    DirectoryContentsList& fileList;
    SortedSet <void*> listeners;

    DirectoryContentsDisplayComponent (const DirectoryContentsDisplayComponent&);
    const DirectoryContentsDisplayComponent& operator= (const DirectoryContentsDisplayComponent&);
};

#endif   // __JUCE_DIRECTORYCONTENTSDISPLAYCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_DirectoryContentsDisplayComponent.h *********/

#endif
#ifndef __JUCE_DIRECTORYCONTENTSLIST_JUCEHEADER__

#endif
#ifndef __JUCE_FILEBROWSERLISTENER_JUCEHEADER__

#endif
#ifndef __JUCE_FILECHOOSER_JUCEHEADER__

/********* Start of inlined file: juce_FileChooser.h *********/
#ifndef __JUCE_FILECHOOSER_JUCEHEADER__
#define __JUCE_FILECHOOSER_JUCEHEADER__

/********* Start of inlined file: juce_FilePreviewComponent.h *********/
#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__
#define __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__

/**
    Base class for components that live inside a file chooser dialog box and
    show previews of the files that get selected.

    One of these allows special extra information to be displayed for files
    in a dialog box as the user selects them. Each time the current file or
    directory is changed, the selectedFileChanged() method will be called
    to allow it to update itself appropriately.

    @see FileChooser, ImagePreviewComponent
*/
class JUCE_API  FilePreviewComponent  : public Component
{
public:

    /** Creates a FilePreviewComponent. */
    FilePreviewComponent();

    /** Destructor. */
    ~FilePreviewComponent();

    /** Called to indicate that the user's currently selected file has changed.

        @param newSelectedFile  the newly selected file or directory, which may be
                                File::nonexistent if none is selected.
    */
    virtual void selectedFileChanged (const File& newSelectedFile) = 0;

    juce_UseDebuggingNewOperator

private:
    FilePreviewComponent (const FilePreviewComponent&);
    const FilePreviewComponent& operator= (const FilePreviewComponent&);
};

#endif   // __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_FilePreviewComponent.h *********/

/**
    Creates a dialog box to choose a file or directory to load or save.

    To use a FileChooser:
    - create one (as a local stack variable is the neatest way)
    - call one of its browseFor.. methods
    - if this returns true, the user has selected a file, so you can retrieve it
      with the getResult() method.

    e.g. @code
    void loadMooseFile()
    {
        FileChooser myChooser ("Please select the moose you want to load...",
                               File::getSpecialLocation (File::userHomeDirectory),
                               "*.moose");

        if (myChooser.browseForFileToOpen())
        {
            File mooseFile (myChooser.getResult());

            loadMoose (mooseFile);
        }
    }
    @endcode
*/
class JUCE_API  FileChooser
{
public:

    /** Creates a FileChooser.

        After creating one of these, use one of the browseFor... methods to display it.

        @param dialogBoxTitle           a text string to display in the dialog box to
                                        tell the user what's going on
        @param initialFileOrDirectory   the file or directory that should be selected when
                                        the dialog box opens. If this parameter is set to
                                        File::nonexistent, a sensible default directory
                                        will be used instead.
        @param filePatternsAllowed      a set of file patterns to specify which files can be
                                        selected - each pattern should be separated by a
                                        comma or semi-colon, e.g. "*" or "*.jpg;*.gif". An
                                        empty string means that all files are allowed
        @param useOSNativeDialogBox     if true, then a native dialog box will be used if
                                        possible; if false, then a Juce-based browser dialog
                                        box will always be used
        @see browseForFileToOpen, browseForFileToSave, browseForDirectory
    */
    FileChooser (const String& dialogBoxTitle,
                 const File& initialFileOrDirectory = File::nonexistent,
                 const String& filePatternsAllowed = String::empty,
                 const bool useOSNativeDialogBox = true);

    /** Destructor. */
    ~FileChooser();

    /** Shows a dialog box to choose a file to open.

        This will display the dialog box modally, using an "open file" mode, so that
        it won't allow non-existent files or directories to be chosen.

        @param previewComponent   an optional component to display inside the dialog
                                  box to show special info about the files that the user
                                  is browsing. The component will not be deleted by this
                                  object, so the caller must take care of it.
        @returns    true if the user selected a file, in which case, use the getResult()
                    method to find out what it was. Returns false if they cancelled instead.
        @see browseForFileToSave, browseForDirectory
    */
    bool browseForFileToOpen (FilePreviewComponent* previewComponent = 0);

    /** Same as browseForFileToOpen, but allows the user to select multiple files.

        The files that are returned can be obtained by calling getResults(). See
        browseForFileToOpen() for more info about the behaviour of this method.
    */
    bool browseForMultipleFilesToOpen (FilePreviewComponent* previewComponent = 0);

    /** Shows a dialog box to choose a file to save.

        This will display the dialog box modally, using an "save file" mode, so it
        will allow non-existent files to be chosen, but not directories.

        @param warnAboutOverwritingExistingFiles     if true, the dialog box will ask
                    the user if they're sure they want to overwrite a file that already
                    exists
        @returns    true if the user chose a file and pressed 'ok', in which case, use
                    the getResult() method to find out what the file was. Returns false
                    if they cancelled instead.
        @see browseForFileToOpen, browseForDirectory
    */
    bool browseForFileToSave (const bool warnAboutOverwritingExistingFiles);

    /** Shows a dialog box to choose a directory.

        This will display the dialog box modally, using an "open directory" mode, so it
        will only allow directories to be returned, not files.

        @returns    true if the user chose a directory and pressed 'ok', in which case, use
                    the getResult() method to find out what they chose. Returns false
                    if they cancelled instead.
        @see browseForFileToOpen, browseForFileToSave
    */
    bool browseForDirectory();

    /** Returns the last file that was chosen by one of the browseFor methods.

        After calling the appropriate browseFor... method, this method lets you
        find out what file or directory they chose.

        Note that the file returned is only valid if the browse method returned true (i.e.
        if the user pressed 'ok' rather than cancelling).

        If you're using a multiple-file select, then use the getResults() method instead,
        to obtain the list of all files chosen.

        @see getResults
    */
    const File getResult() const;

    /** Returns a list of all the files that were chosen during the last call to a
        browse method.

        This array may be empty if no files were chosen, or can contain multiple entries
        if multiple files were chosen.

        @see getResult
    */
    const OwnedArray <File>& getResults() const;

    juce_UseDebuggingNewOperator

private:
    String title, filters;
    File startingFile;
    OwnedArray <File> results;
    bool useNativeDialogBox;

    bool showDialog (const bool isDirectory,
                     const bool isSave,
                     const bool warnAboutOverwritingExistingFiles,
                     const bool selectMultipleFiles,
                     FilePreviewComponent* const previewComponent);

    static void showPlatformDialog (OwnedArray<File>& results,
                                    const String& title,
                                    const File& file,
                                    const String& filters,
                                    bool isDirectory,
                                    bool isSave,
                                    bool warnAboutOverwritingExistingFiles,
                                    bool selectMultipleFiles,
                                    FilePreviewComponent* previewComponent);
};

#endif   // __JUCE_FILECHOOSER_JUCEHEADER__
/********* End of inlined file: juce_FileChooser.h *********/

#endif
#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__

/********* Start of inlined file: juce_FileChooserDialogBox.h *********/
#ifndef __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__
#define __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__

/********* Start of inlined file: juce_FileBrowserComponent.h *********/
#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__
#define __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__

/**
    A component for browsing and selecting a file or directory to open or save.

    This contains a FileListComponent and adds various boxes and controls for
    navigating and selecting a file. It can work in different modes so that it can
    be used for loading or saving a file, or for choosing a directory.

    @see FileChooserDialogBox, FileChooser, FileListComponent
*/
class JUCE_API  FileBrowserComponent  : public Component,
                                        public ChangeBroadcaster,
                                        private FileBrowserListener,
                                        private TextEditorListener,
                                        private ButtonListener,
                                        private ComboBoxListener
{
public:

    /** Various modes that the browser can be used in.

        One of these is passed into the constructor.
    */
    enum FileChooserMode
    {
        loadFileMode,           /**< the component should allow the user to choose an existing
                                     file with the intention of opening it. */
        saveFileMode,           /**< the component should allow the user to specify the name of
                                     a file that will be used to save something. */
        chooseDirectoryMode     /**< the component should allow the user to select an existing
                                     directory. */
    };

    /** Creates a FileBrowserComponent.

        @param browserMode              The intended purpose for the browser - see the
                                        FileChooserMode enum for the various options
        @param initialFileOrDirectory   The file or directory that should be selected when
                                        the component begins. If this is File::nonexistent,
                                        a default directory will be chosen.
        @param fileFilter               an optional filter to use to determine which files
                                        are shown. If this is 0 then all files are displayed. Note
                                        that a pointer is kept internally to this object, so
                                        make sure that it is not deleted before the browser object
                                        is deleted.
        @param previewComp              an optional preview component that will be used to
                                        show previews of files that the user selects
        @param useTreeView              if this is false, the files are shown in a list; if true,
                                        they are shown in a treeview
        @param filenameTextBoxIsReadOnly    if true, the user won't be allowed to type their own
                                        text into the filename box.
    */
    FileBrowserComponent (FileChooserMode browserMode,
                          const File& initialFileOrDirectory,
                          const FileFilter* fileFilter,
                          FilePreviewComponent* previewComp,
                          const bool useTreeView = false,
                          const bool filenameTextBoxIsReadOnly = false);

    /** Destructor. */
    ~FileBrowserComponent();

    /**
    */
    const File getCurrentFile() const throw();

    /** Returns true if the current file is usable.

        This can be used to decide whether the user can press "ok" for the
        current file. What it does depends on the mode, so for example in an "open"
        mode, the current file is only valid if one has been selected and if the file
        exists. In a "save" mode, a non-existent file would also be valid.
    */
    bool currentFileIsValid() const;

    /** Returns the directory whose contents are currently being shown in the listbox. */
    const File getRoot() const;

    /** Changes the directory that's being shown in the listbox. */
    void setRoot (const File& newRootDirectory);

    /** Equivalent to pressing the "up" button to browse the parent directory. */
    void goUp();

    /** Refreshes the directory that's currently being listed. */
    void refresh();

    /** Returns the browser's current mode. */
    FileChooserMode getMode() const throw()                     { return mode; }

    /** Returns a verb to describe what should happen when the file is accepted.

        E.g. if browsing in "load file" mode, this will be "Open", if in "save file"
        mode, it'll be "Save", etc.
    */
    virtual const String getActionVerb() const;

    /** Adds a listener to be told when the user selects and clicks on files.

        @see removeListener
    */
    void addListener (FileBrowserListener* const listener) throw();

    /** Removes a listener.

        @see addListener
    */
    void removeListener (FileBrowserListener* const listener) throw();

    /** @internal */
    void resized();
    /** @internal */
    void buttonClicked (Button* b);
    /** @internal */
    void comboBoxChanged (ComboBox*);
    /** @internal */
    void textEditorTextChanged (TextEditor& editor);
    /** @internal */
    void textEditorReturnKeyPressed (TextEditor& editor);
    /** @internal */
    void textEditorEscapeKeyPressed (TextEditor& editor);
    /** @internal */
    void textEditorFocusLost (TextEditor& editor);
    /** @internal */
    bool keyPressed (const KeyPress& key);
    /** @internal */
    void selectionChanged();
    /** @internal */
    void fileClicked (const File& f, const MouseEvent& e);
    /** @internal */
    void fileDoubleClicked (const File& f);

    /** @internal */
    FilePreviewComponent* getPreviewComponent() const throw();

    juce_UseDebuggingNewOperator

protected:
    virtual const BitArray getRoots (StringArray& rootNames, StringArray& rootPaths);

private:

    DirectoryContentsList* fileList;
    FileFilter* directoriesOnlyFilter;

    FileChooserMode mode;
    File currentRoot;
    SortedSet <void*> listeners;

    DirectoryContentsDisplayComponent* fileListComponent;
    FilePreviewComponent* previewComp;
    ComboBox* currentPathBox;
    TextEditor* filenameBox;
    Button* goUpButton;

    TimeSliceThread thread;

    void sendListenerChangeMessage();

    FileBrowserComponent (const FileBrowserComponent&);
    const FileBrowserComponent& operator= (const FileBrowserComponent&);
};

#endif   // __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_FileBrowserComponent.h *********/

/**
    A file open/save dialog box.

    This is a Juce-based file dialog box; to use a native file chooser, see the
    FileChooser class.

    To use one of these, create it and call its show() method. e.g.

    @code
    {
        WildcardFileFilter wildcardFilter (T("*.foo"), T("Foo files"));

        FileBrowserComponent browser (FileBrowserComponent::loadFileMode,
                                      File::nonexistent,
                                      &wildcardFilter,
                                      0);

        FileChooserDialogBox dialogBox (T("Open some kind of file"),
                                        T("Please choose some kind of file that you want to open..."),
                                        browser,
                                        getLookAndFeel().alertWindowBackground);

        if (dialogBox.show())
        {
            File selectedFile = browser.getCurrentFile();
            ...
        }
    }
    @endcode

    @see FileChooser
*/
class JUCE_API  FileChooserDialogBox : public ResizableWindow,
                                       public ButtonListener,
                                       public FileBrowserListener
{
public:

    /** Creates a file chooser box.

        @param title            the main title to show at the top of the box
        @param instructions     an optional longer piece of text to show below the title in
                                a smaller font, describing in more detail what's required.
        @param browserComponent a FileBrowserComponent that will be shown inside this dialog
                                box. Make sure you delete this after (but not before!) the
                                dialog box has been deleted.
        @param warnAboutOverwritingExistingFiles     if true, then the user will be asked to confirm
                                if they try to select a file that already exists. (This
                                flag is only used when saving files)
        @param backgroundColour the background colour for the top level window

        @see FileBrowserComponent, FilePreviewComponent
    */
    FileChooserDialogBox (const String& title,
                          const String& instructions,
                          FileBrowserComponent& browserComponent,
                          const bool warnAboutOverwritingExistingFiles,
                          const Colour& backgroundColour);

    /** Destructor. */
    ~FileChooserDialogBox();

    /** Displays and runs the dialog box modally.

        This will show the box with the specified size, returning true if the user
        pressed 'ok', or false if they cancelled.

        Leave the width or height as 0 to use the default size
    */
    bool show (int width = 0,int height = 0);

    /** @internal */
    void buttonClicked (Button* button);
    /** @internal */
    void closeButtonPressed();
    /** @internal */
    void selectionChanged();
    /** @internal */
    void fileClicked (const File& file, const MouseEvent& e);
    /** @internal */
    void fileDoubleClicked (const File& file);

    juce_UseDebuggingNewOperator

private:
    class ContentComponent  : public Component
    {
    public:
        ContentComponent();
        ~ContentComponent();

        void paint (Graphics& g);
        void resized();

        String instructions;
        GlyphArrangement text;

        FileBrowserComponent* chooserComponent;
        FilePreviewComponent* previewComponent;
        TextButton* okButton;
        TextButton* cancelButton;
    };

    ContentComponent* content;
    const bool warnAboutOverwritingExistingFiles;

    FileChooserDialogBox (const FileChooserDialogBox&);
    const FileChooserDialogBox& operator= (const FileChooserDialogBox&);
};

#endif   // __JUCE_FILECHOOSERDIALOGBOX_JUCEHEADER__
/********* End of inlined file: juce_FileChooserDialogBox.h *********/

#endif
#ifndef __JUCE_FILEFILTER_JUCEHEADER__

#endif
#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_FileListComponent.h *********/
#ifndef __JUCE_FILELISTCOMPONENT_JUCEHEADER__
#define __JUCE_FILELISTCOMPONENT_JUCEHEADER__

/**
    A component that displays the files in a directory as a listbox.

    This implements the DirectoryContentsDisplayComponent base class so that
    it can be used in a FileBrowserComponent.

    To attach a listener to it, use its DirectoryContentsDisplayComponent base
    class and the FileBrowserListener class.

    @see DirectoryContentsList, FileTreeComponent
*/
class JUCE_API  FileListComponent  : public ListBox,
                                     public DirectoryContentsDisplayComponent,
                                     private ListBoxModel,
                                     private ChangeListener
{
public:

    /** Creates a listbox to show the contents of a specified directory.
    */
    FileListComponent (DirectoryContentsList& listToShow);

    /** Destructor. */
    ~FileListComponent();

    /** Returns the file that the user has currently selected.

        Returns File::nonexistent if none is selected.
    */
    const File getSelectedFile() const;

    /** Scrolls to the top of the list. */
    void scrollToTop();

    /** @internal */
    void changeListenerCallback (void*);
    /** @internal */
    int getNumRows();
    /** @internal */
    void paintListBoxItem (int, Graphics&, int, int, bool);
    /** @internal */
    Component* refreshComponentForRow (int rowNumber, bool isRowSelected, Component* existingComponentToUpdate);
    /** @internal */
    void selectedRowsChanged (int lastRowSelected);
    /** @internal */
    void deleteKeyPressed (int currentSelectedRow);
    /** @internal */
    void returnKeyPressed (int currentSelectedRow);

    juce_UseDebuggingNewOperator

private:
    FileListComponent (const FileListComponent&);
    const FileListComponent& operator= (const FileListComponent&);

    File lastDirectory;
};

#endif   // __JUCE_FILELISTCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_FileListComponent.h *********/

#endif
#ifndef __JUCE_FILEPREVIEWCOMPONENT_JUCEHEADER__

#endif
#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_FileTreeComponent.h *********/
#ifndef __JUCE_FILETREECOMPONENT_JUCEHEADER__
#define __JUCE_FILETREECOMPONENT_JUCEHEADER__

/**
    A component that displays the files in a directory as a treeview.

    This implements the DirectoryContentsDisplayComponent base class so that
    it can be used in a FileBrowserComponent.

    To attach a listener to it, use its DirectoryContentsDisplayComponent base
    class and the FileBrowserListener class.

    @see DirectoryContentsList, FileListComponent
*/
class JUCE_API  FileTreeComponent  : public TreeView,
                                     public DirectoryContentsDisplayComponent
{
public:

    /** Creates a listbox to show the contents of a specified directory.
    */
    FileTreeComponent (DirectoryContentsList& listToShow);

    /** Destructor. */
    ~FileTreeComponent();

    /** Returns the number of selected files in the tree.
    */
    int getNumSelectedFiles() const throw()         { return TreeView::getNumSelectedItems(); }

    /** Returns one of the files that the user has currently selected.

        Returns File::nonexistent if none is selected.
    */
    const File getSelectedFile (int index) const throw();

    /** Returns the first of the files that the user has currently selected.

        Returns File::nonexistent if none is selected.
    */
    const File getSelectedFile() const;

    /** Scrolls the list to the top. */
    void scrollToTop();

    /** Setting a name for this allows tree items to be dragged.

        The string that you pass in here will be returned by the getDragSourceDescription()
        of the items in the tree. For more info, see TreeViewItem::getDragSourceDescription().
    */
    void setDragAndDropDescription (const String& description) throw();

    /** Returns the last value that was set by setDragAndDropDescription().
    */
    const String& getDragAndDropDescription() const throw()      { return dragAndDropDescription; }

    juce_UseDebuggingNewOperator

private:
    String dragAndDropDescription;

    FileTreeComponent (const FileTreeComponent&);
    const FileTreeComponent& operator= (const FileTreeComponent&);
};

#endif   // __JUCE_FILETREECOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_FileTreeComponent.h *********/

#endif
#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_FileSearchPathListComponent.h *********/
#ifndef __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__
#define __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__

/**
    Shows a set of file paths in a list, allowing them to be added, removed or
    re-ordered.

    @see FileSearchPath
*/
class JUCE_API  FileSearchPathListComponent  : public Component,
                                               public SettableTooltipClient,
                                               public FileDragAndDropTarget,
                                               private ButtonListener,
                                               private ListBoxModel
{
public:

    /** Creates an empty FileSearchPathListComponent.

    */
    FileSearchPathListComponent();

    /** Destructor. */
    ~FileSearchPathListComponent();

    /** Returns the path as it is currently shown. */
    const FileSearchPath& getPath() const throw()                   { return path; }

    /** Changes the current path. */
    void setPath (const FileSearchPath& newPath);

    /** Sets a file or directory to be the default starting point for the browser to show.

        This is only used if the current file hasn't been set.
    */
    void setDefaultBrowseTarget (const File& newDefaultDirectory) throw();

    /** A set of colour IDs to use to change the colour of various aspects of the label.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId      = 0x1004100, /**< The background colour to fill the component with.
                                                  Make this transparent if you don't want the background to be filled. */
    };

    /** @internal */
    int getNumRows();
    /** @internal */
    void paintListBoxItem (int rowNumber, Graphics& g, int width, int height, bool rowIsSelected);
    /** @internal */
    void deleteKeyPressed (int lastRowSelected);
    /** @internal */
    void returnKeyPressed (int lastRowSelected);
    /** @internal */
    void listBoxItemDoubleClicked (int row, const MouseEvent&);
    /** @internal */
    void selectedRowsChanged (int lastRowSelected);
    /** @internal */
    void resized();
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    bool isInterestedInFileDrag (const StringArray& files);
    /** @internal */
    void filesDropped (const StringArray& files, int, int);
    /** @internal */
    void buttonClicked (Button* button);

    juce_UseDebuggingNewOperator

private:

    FileSearchPath path;
    File defaultBrowseTarget;

    ListBox* listBox;
    Button* addButton;
    Button* removeButton;
    Button* changeButton;
    Button* upButton;
    Button* downButton;

    void changed() throw();
    void updateButtons() throw();

    FileSearchPathListComponent (const FileSearchPathListComponent&);
    const FileSearchPathListComponent& operator= (const FileSearchPathListComponent&);
};

#endif   // __JUCE_FILESEARCHPATHLISTCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_FileSearchPathListComponent.h *********/

#endif
#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__

/********* Start of inlined file: juce_WildcardFileFilter.h *********/
#ifndef __JUCE_WILDCARDFILEFILTER_JUCEHEADER__
#define __JUCE_WILDCARDFILEFILTER_JUCEHEADER__

/**
    A type of FileFilter that works by wildcard pattern matching.

    This filter only allows files that match one of the specified patterns, but
    allows all directories through.

    @see FileFilter, DirectoryContentsList, FileListComponent, FileBrowserComponent
*/
class JUCE_API  WildcardFileFilter  : public FileFilter
{
public:

    /**
        Creates a wildcard filter for one or more patterns.

        The wildcardPatterns parameter is a comma or semicolon-delimited set of
        patterns, e.g. "*.wav;*.aiff" would look for files ending in either .wav
        or .aiff.

        The description is a name to show the user in a list of possible patterns, so
        for the wav/aiff example, your description might be "audio files".
    */
    WildcardFileFilter (const String& wildcardPatterns,
                        const String& description);

    /** Destructor. */
    ~WildcardFileFilter();

    /** Returns true if the filename matches one of the patterns specified. */
    bool isFileSuitable (const File& file) const;

    /** This always returns true. */
    bool isDirectorySuitable (const File& file) const;

    juce_UseDebuggingNewOperator

private:
    StringArray wildcards;
};

#endif   // __JUCE_WILDCARDFILEFILTER_JUCEHEADER__
/********* End of inlined file: juce_WildcardFileFilter.h *********/

#endif
#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_ImagePreviewComponent.h *********/
#ifndef __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__
#define __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__

/**
    A simple preview component that shows thumbnails of image files.

    @see FileChooserDialogBox, FilePreviewComponent
*/
class JUCE_API  ImagePreviewComponent  : public FilePreviewComponent,
                                         private Timer
{
public:

    /** Creates an ImagePreviewComponent. */
    ImagePreviewComponent();

    /** Destructor. */
    ~ImagePreviewComponent();

    /** @internal */
    void selectedFileChanged (const File& newSelectedFile);
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void timerCallback();

    juce_UseDebuggingNewOperator

private:
    File fileToLoad;
    Image* currentThumbnail;
    String currentDetails;

    void getThumbSize (int& w, int& h) const;

    ImagePreviewComponent (const ImagePreviewComponent&);
    const ImagePreviewComponent& operator= (const ImagePreviewComponent&);
};

#endif   // __JUCE_IMAGEPREVIEWCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_ImagePreviewComponent.h *********/

#endif
#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_FilenameComponent.h *********/
#ifndef __JUCE_FILENAMECOMPONENT_JUCEHEADER__
#define __JUCE_FILENAMECOMPONENT_JUCEHEADER__

class FilenameComponent;

/**
    Listens for events happening to a FilenameComponent.

    Use FilenameComponent::addListener() and FilenameComponent::removeListener() to
    register one of these objects for event callbacks when the filename is changed.

    @see FilenameComponent
*/
class JUCE_API  FilenameComponentListener
{
public:
    /** Destructor. */
    virtual ~FilenameComponentListener() {}

    /** This method is called after the FilenameComponent's file has been changed. */
    virtual void filenameComponentChanged (FilenameComponent* fileComponentThatHasChanged) = 0;
};

/**
    Shows a filename as an editable text box, with a 'browse' button and a
    drop-down list for recently selected files.

    A handy component for dialogue boxes where you want the user to be able to
    select a file or directory.

    Attach an FilenameComponentListener using the addListener() method, and it will
    get called each time the user changes the filename, either by browsing for a file
    and clicking 'ok', or by typing a new filename into the box and pressing return.

    @see FileChooser, ComboBox
*/
class JUCE_API  FilenameComponent  : public Component,
                                     public SettableTooltipClient,
                                     public FileDragAndDropTarget,
                                     private AsyncUpdater,
                                     private ButtonListener,
                                     private ComboBoxListener
{
public:

    /** Creates a FilenameComponent.

        @param name             the name for this component.
        @param currentFile      the file to initially show in the box
        @param canEditFilename  if true, the user can manually edit the filename; if false,
                                they can only change it by browsing for a new file
        @param isDirectory      if true, the file will be treated as a directory, and
                                an appropriate directory browser used
        @param isForSaving      if true, the file browser will allow non-existent files to
                                be picked, as the file is assumed to be used for saving rather
                                than loading
        @param fileBrowserWildcard  a wildcard pattern to use in the file browser - e.g. "*.txt;*.foo".
                                If an empty string is passed in, then the pattern is assumed to be "*"
        @param enforcedSuffix   if this is non-empty, it is treated as a suffix that will be added
                                to any filenames that are entered or chosen
        @param textWhenNothingSelected  the message to display in the box before any filename is entered. (This
                                will only appear if the initial file isn't valid)
    */
    FilenameComponent (const String& name,
                       const File& currentFile,
                       const bool canEditFilename,
                       const bool isDirectory,
                       const bool isForSaving,
                       const String& fileBrowserWildcard,
                       const String& enforcedSuffix,
                       const String& textWhenNothingSelected);

    /** Destructor. */
    ~FilenameComponent();

    /** Returns the currently displayed filename. */
    const File getCurrentFile() const;

    /** Changes the current filename.

        If addToRecentlyUsedList is true, the filename will also be added to the
        drop-down list of recent files.

        If sendChangeNotification is false, then the listeners won't be told of the
        change.
    */
    void setCurrentFile (File newFile,
                         const bool addToRecentlyUsedList,
                         const bool sendChangeNotification = true);

    /** Changes whether the use can type into the filename box.
    */
    void setFilenameIsEditable (const bool shouldBeEditable);

    /** Sets a file or directory to be the default starting point for the browser to show.

        This is only used if the current file hasn't been set.
    */
    void setDefaultBrowseTarget (const File& newDefaultDirectory) throw();

    /** Returns all the entries on the recent files list.

        This can be used in conjunction with setRecentlyUsedFilenames() for saving the
        state of this list.

        @see setRecentlyUsedFilenames
    */
    const StringArray getRecentlyUsedFilenames() const;

    /** Sets all the entries on the recent files list.

        This can be used in conjunction with getRecentlyUsedFilenames() for saving the
        state of this list.

        @see getRecentlyUsedFilenames, addRecentlyUsedFile
    */
    void setRecentlyUsedFilenames (const StringArray& filenames);

    /** Adds an entry to the recently-used files dropdown list.

        If the file is already in the list, it will be moved to the top. A limit
        is also placed on the number of items that are kept in the list.

        @see getRecentlyUsedFilenames, setRecentlyUsedFilenames, setMaxNumberOfRecentFiles
    */
    void addRecentlyUsedFile (const File& file);

    /** Changes the limit for the number of files that will be stored in the recent-file list.
    */
    void setMaxNumberOfRecentFiles (const int newMaximum);

    /** Changes the text shown on the 'browse' button.

        By default this button just says "..." but you can change it. The button itself
        can be changed using the look-and-feel classes, so it might not actually have any
        text on it.
    */
    void setBrowseButtonText (const String& browseButtonText);

    /** Adds a listener that will be called when the selected file is changed. */
    void addListener (FilenameComponentListener* const listener) throw();

    /** Removes a previously-registered listener. */
    void removeListener (FilenameComponentListener* const listener) throw();

    /** Gives the component a tooltip. */
    void setTooltip (const String& newTooltip);

    /** @internal */
    void paintOverChildren (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void lookAndFeelChanged();
    /** @internal */
    bool isInterestedInFileDrag (const StringArray& files);
    /** @internal */
    void filesDropped (const StringArray& files, int, int);
    /** @internal */
    void fileDragEnter (const StringArray& files, int, int);
    /** @internal */
    void fileDragExit (const StringArray& files);

    juce_UseDebuggingNewOperator

private:

    ComboBox* filenameBox;
    String lastFilename;
    Button* browseButton;
    int maxRecentFiles;
    bool isDir, isSaving, isFileDragOver;
    String wildcard, enforcedSuffix, browseButtonText;
    SortedSet <void*> listeners;
    File defaultBrowseFile;

    void comboBoxChanged (ComboBox*);
    void buttonClicked (Button* button);
    void handleAsyncUpdate();

    FilenameComponent (const FilenameComponent&);
    const FilenameComponent& operator= (const FilenameComponent&);
};

#endif   // __JUCE_FILENAMECOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_FilenameComponent.h *********/

#endif
#ifndef __JUCE_FILEBROWSERCOMPONENT_JUCEHEADER__

#endif
#ifndef __JUCE_ALERTWINDOW_JUCEHEADER__

/********* Start of inlined file: juce_AlertWindow.h *********/
#ifndef __JUCE_ALERTWINDOW_JUCEHEADER__
#define __JUCE_ALERTWINDOW_JUCEHEADER__

/** A window that displays a message and has buttons for the user to react to it.

    For simple dialog boxes with just a couple of buttons on them, there are
    some static methods for running these.

    For more complex dialogs, an AlertWindow can be created, then it can have some
    buttons and components added to it, and its runModalLoop() method is then used to
    show it. The value returned by runModalLoop() shows which button the
    user pressed to dismiss the box.

    @see ThreadWithProgressWindow
*/
class JUCE_API  AlertWindow  : public TopLevelWindow,
                               private ButtonListener
{
public:

    /** The type of icon to show in the dialog box. */
    enum AlertIconType
    {
        NoIcon,         /**< No icon will be shown on the dialog box. */
        QuestionIcon,   /**< A question-mark icon, for dialog boxes that need the
                             user to answer a question. */
        WarningIcon,    /**< An exclamation mark to indicate that the dialog is a
                             warning about something and shouldn't be ignored. */
        InfoIcon        /**< An icon that indicates that the dialog box is just
                             giving the user some information, which doesn't require
                             a response from them. */
    };

    /** Creates an AlertWindow.

        @param title    the headline to show at the top of the dialog box
        @param message  a longer, more descriptive message to show underneath the
                        headline
        @param iconType the type of icon to display
        @param associatedComponent   if this is non-zero, it specifies the component that the
                        alert window should be associated with. Depending on the look
                        and feel, this might be used for positioning of the alert window.
    */
    AlertWindow (const String& title,
                 const String& message,
                 AlertIconType iconType,
                 Component* associatedComponent = 0);

    /** Destroys the AlertWindow */
    ~AlertWindow();

    /** Returns the type of alert icon that was specified when the window
        was created. */
    AlertIconType getAlertType() const throw()              { return alertIconType; }

    /** Changes the dialog box's message.

        This will also resize the window to fit the new message if required.
    */
    void setMessage (const String& message);

    /** Adds a button to the window.

        @param name         the text to show on the button
        @param returnValue  the value that should be returned from runModalLoop()
                            if this is the button that the user presses.
        @param shortcutKey1 an optional key that can be pressed to trigger this button
        @param shortcutKey2 a second optional key that can be pressed to trigger this button
    */
    void addButton (const String& name,
                    const int returnValue,
                    const KeyPress& shortcutKey1 = KeyPress(),
                    const KeyPress& shortcutKey2 = KeyPress());

    /** Returns the number of buttons that the window currently has. */
    int getNumButtons() const;

    /** Adds a textbox to the window for entering strings.

        @param name             an internal name for the text-box. This is the name to pass to
                                the getTextEditorContents() method to find out what the
                                user typed-in.
        @param initialContents  a string to show in the text box when it's first shown
        @param onScreenLabel    if this is non-empty, it will be displayed next to the
                                text-box to label it.
        @param isPasswordBox    if true, the text editor will display asterisks instead of
                                the actual text
        @see getTextEditorContents
    */
    void addTextEditor (const String& name,
                        const String& initialContents,
                        const String& onScreenLabel = String::empty,
                        const bool isPasswordBox = false);

    /** Returns the contents of a named textbox.

        After showing an AlertWindow that contains a text editor, this can be
        used to find out what the user has typed into it.

        @param nameOfTextEditor     the name of the text box that you're interested in
        @see addTextEditor
    */
    const String getTextEditorContents (const String& nameOfTextEditor) const;

    /** Adds a drop-down list of choices to the box.

        After the box has been shown, the getComboBoxComponent() method can
        be used to find out which item the user picked.

        @param name     the label to use for the drop-down list
        @param items    the list of items to show in it
        @param onScreenLabel    if this is non-empty, it will be displayed next to the
                                combo-box to label it.
        @see getComboBoxComponent
    */
    void addComboBox (const String& name,
                      const StringArray& items,
                      const String& onScreenLabel = String::empty);

    /** Returns a drop-down list that was added to the AlertWindow.

        @param nameOfList   the name that was passed into the addComboBox() method
                            when creating the drop-down
        @returns the ComboBox component, or 0 if none was found for the given name.
    */
    ComboBox* getComboBoxComponent (const String& nameOfList) const;

    /** Adds a block of text.

        This is handy for adding a multi-line note next to a textbox or combo-box,
        to provide more details about what's going on.
    */
    void addTextBlock (const String& text);

    /** Adds a progress-bar to the window.

        @param progressValue    a variable that will be repeatedly checked while the
                                dialog box is visible, to see how far the process has
                                got. The value should be in the range 0 to 1.0
    */
    void addProgressBarComponent (double& progressValue);

    /** Adds a user-defined component to the dialog box.

        @param component    the component to add - its size should be set up correctly
                            before it is passed in. The caller is responsible for deleting
                            the component later on - the AlertWindow won't delete it.
    */
    void addCustomComponent (Component* const component);

    /** Returns the number of custom components in the dialog box.

        @see getCustomComponent, addCustomComponent
    */
    int getNumCustomComponents() const;

    /** Returns one of the custom components in the dialog box.

        @param index    a value 0 to (getNumCustomComponents() - 1). Out-of-range indexes
                        will return 0
        @see getNumCustomComponents, addCustomComponent
    */
    Component* getCustomComponent (const int index) const;

    /** Removes one of the custom components in the dialog box.

        Note that this won't delete it, it just removes the component from the window

        @param index    a value 0 to (getNumCustomComponents() - 1). Out-of-range indexes
                        will return 0
        @returns        the component that was removed (or zero)
        @see getNumCustomComponents, addCustomComponent
    */
    Component* removeCustomComponent (const int index);

    /** Returns true if the window contains any components other than just buttons.*/
    bool containsAnyExtraComponents() const;

    // easy-to-use message box functions:

    /** Shows a dialog box that just has a message and a single button to get rid of it.

        The box is shown modally, and the method returns after the user
        has clicked the button (or pressed the escape or return keys).

        @param iconType     the type of icon to show
        @param title        the headline to show at the top of the box
        @param message      a longer, more descriptive message to show underneath the
                            headline
        @param buttonText   the text to show in the button - if this string is empty, the
                            default string "ok" (or a localised version) will be used.
        @param associatedComponent   if this is non-zero, it specifies the component that the
                            alert window should be associated with. Depending on the look
                            and feel, this might be used for positioning of the alert window.
    */
    static void JUCE_CALLTYPE showMessageBox (AlertIconType iconType,
                                              const String& title,
                                              const String& message,
                                              const String& buttonText = String::empty,
                                              Component* associatedComponent = 0);

    /** Shows a dialog box with two buttons.

        Ideal for ok/cancel or yes/no choices. The return key can also be used
        to trigger the first button, and the escape key for the second button.

        @param iconType     the type of icon to show
        @param title        the headline to show at the top of the box
        @param message      a longer, more descriptive message to show underneath the
                            headline
        @param button1Text  the text to show in the first button - if this string is
                            empty, the default string "ok" (or a localised version of it)
                            will be used.
        @param button2Text  the text to show in the second button - if this string is
                            empty, the default string "cancel" (or a localised version of it)
                            will be used.
     @param associatedComponent   if this is non-zero, it specifies the component that the
                             alert window should be associated with. Depending on the look
                             and feel, this might be used for positioning of the alert window.
     @returns true if button 1 was clicked, false if it was button 2
    */
    static bool JUCE_CALLTYPE showOkCancelBox (AlertIconType iconType,
                                               const String& title,
                                               const String& message,
                                               const String& button1Text = String::empty,
                                               const String& button2Text = String::empty,
                                               Component* associatedComponent = 0);

    /** Shows a dialog box with three buttons.

        Ideal for yes/no/cancel boxes.

        The escape key can be used to trigger the third button.

        @param iconType     the type of icon to show
        @param title        the headline to show at the top of the box
        @param message      a longer, more descriptive message to show underneath the
                            headline
        @param button1Text  the text to show in the first button - if an empty string, then
                            "yes" will be used (or a localised version of it)
        @param button2Text  the text to show in the first button - if an empty string, then
                            "no" will be used (or a localised version of it)
        @param button3Text  the text to show in the first button - if an empty string, then
                            "cancel" will be used (or a localised version of it)
        @param associatedComponent   if this is non-zero, it specifies the component that the
                            alert window should be associated with. Depending on the look
                            and feel, this might be used for positioning of the alert window.

        @returns one of the following values:
                 - 0 if the third button was pressed (normally used for 'cancel')
                 - 1 if the first button was pressed (normally used for 'yes')
                 - 2 if the middle button was pressed (normally used for 'no')
    */
    static int JUCE_CALLTYPE showYesNoCancelBox (AlertIconType iconType,
                                                 const String& title,
                                                 const String& message,
                                                 const String& button1Text = String::empty,
                                                 const String& button2Text = String::empty,
                                                 const String& button3Text = String::empty,
                                                 Component* associatedComponent = 0);

    /** Shows an operating-system native dialog box.

        @param title        the title to use at the top
        @param bodyText     the longer message to show
        @param isOkCancel   if true, this will show an ok/cancel box, if false,
                            it'll show a box with just an ok button
        @returns true if the ok button was pressed, false if they pressed cancel.
    */
    static bool JUCE_CALLTYPE showNativeDialogBox (const String& title,
                                                   const String& bodyText,
                                                   bool isOkCancel);

    /** A set of colour IDs to use to change the colour of various aspects of the alert box.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId          = 0x1001800,  /**< The background colour for the window. */
        textColourId                = 0x1001810,  /**< The colour for the text. */
        outlineColourId             = 0x1001820   /**< An optional colour to use to draw a border around the window. */
    };

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    bool keyPressed (const KeyPress& key);
    /** @internal */
    void buttonClicked (Button* button);
    /** @internal */
    void lookAndFeelChanged();
    /** @internal */
    void userTriedToCloseWindow();
    /** @internal */
    int getDesktopWindowStyleFlags() const;

private:
    String text;
    TextLayout textLayout;
    AlertIconType alertIconType;
    ComponentBoundsConstrainer constrainer;
    ComponentDragger dragger;
    Rectangle textArea;
    VoidArray buttons, textBoxes, comboBoxes;
    VoidArray progressBars, customComps, textBlocks, allComps;
    StringArray textboxNames, comboBoxNames;
    Font font;
    Component* associatedComponent;

    void updateLayout (const bool onlyIncreaseSize);

    // disable copy constructor
    AlertWindow (const AlertWindow&);
    const AlertWindow& operator= (const AlertWindow&);
};

#endif   // __JUCE_ALERTWINDOW_JUCEHEADER__
/********* End of inlined file: juce_AlertWindow.h *********/

#endif
#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__

/********* Start of inlined file: juce_DialogWindow.h *********/
#ifndef __JUCE_DIALOGWINDOW_JUCEHEADER__
#define __JUCE_DIALOGWINDOW_JUCEHEADER__

/**
    A dialog-box style window.

    This class is a convenient way of creating a DocumentWindow with a close button
    that can be triggered by pressing the escape key.

    Any of the methods available to a DocumentWindow or ResizableWindow are also
    available to this, so it can be made resizable, have a menu bar, etc.

    To add items to the box, see the ResizableWindow::setContentComponent() method.
    Don't add components directly to this class - always put them in a content component!

    You'll need to override the DocumentWindow::closeButtonPressed() method to handle
    the user clicking the close button - for more info, see the DocumentWindow
    help.

    @see DocumentWindow, ResizableWindow
*/
class JUCE_API  DialogWindow   : public DocumentWindow
{
public:

    /** Creates a DialogWindow.

        @param name                 the name to give the component - this is also
                                    the title shown at the top of the window. To change
                                    this later, use setName()
        @param backgroundColour     the colour to use for filling the window's background.
        @param escapeKeyTriggersCloseButton if true, then pressing the escape key will cause the
                                            close button to be triggered
        @param addToDesktop         if true, the window will be automatically added to the
                                    desktop; if false, you can use it as a child component
    */
    DialogWindow (const String& name,
                  const Colour& backgroundColour,
                  const bool escapeKeyTriggersCloseButton,
                  const bool addToDesktop = true);

    /** Destructor.

        If a content component has been set with setContentComponent(), it
        will be deleted.
    */
    ~DialogWindow();

    /** Easy way of quickly showing a dialog box containing a given component.

        This will open and display a DialogWindow containing a given component, returning
        when the user clicks its close button.

        It returns the value that was returned by the dialog box's runModalLoop() call.

        To close the dialog programatically, you should call exitModalState (returnValue) on
        the DialogWindow that is created. To find a pointer to this window from your
        contentComponent, you can do something like this:
        @code
        Dialogwindow* dw = contentComponent->findParentComponentOfClass ((DialogWindow*) 0);

        if (dw != 0)
            dw->exitModalState (1234);
        @endcode

        @param dialogTitle          the dialog box's title
        @param contentComponent     the content component for the dialog box. Make sure
                                    that this has been set to the size you want it to
                                    be before calling this method. The component won't
                                    be deleted by this call, so you can re-use it or delete
                                    it afterwards
        @param componentToCentreAround  if this is non-zero, it indicates a component that
                                    you'd like to show this dialog box in front of. See the
                                    DocumentWindow::centreAroundComponent() method for more
                                    info on this parameter
        @param backgroundColour     a colour to use for the dialog box's background colour
        @param escapeKeyTriggersCloseButton if true, then pressing the escape key will cause the
                                            close button to be triggered
        @param shouldBeResizable    if true, the dialog window has either a resizable border, or
                                    a corner resizer
        @param useBottomRightCornerResizer     if shouldBeResizable is true, this indicates whether
                                    to use a border or corner resizer component. See ResizableWindow::setResizable()
    */
    static int showModalDialog (const String& dialogTitle,
                                Component* contentComponent,
                                Component* componentToCentreAround,
                                const Colour& backgroundColour,
                                const bool escapeKeyTriggersCloseButton,
                                const bool shouldBeResizable = false,
                                const bool useBottomRightCornerResizer = false);

    juce_UseDebuggingNewOperator

protected:
    /** @internal */
    void resized();

private:
    bool escapeKeyTriggersCloseButton;

    DialogWindow (const DialogWindow&);
    const DialogWindow& operator= (const DialogWindow&);
};

#endif   // __JUCE_DIALOGWINDOW_JUCEHEADER__
/********* End of inlined file: juce_DialogWindow.h *********/

#endif
#ifndef __JUCE_DOCUMENTWINDOW_JUCEHEADER__

#endif
#ifndef __JUCE_RESIZABLEWINDOW_JUCEHEADER__

#endif
#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__

/********* Start of inlined file: juce_SplashScreen.h *********/
#ifndef __JUCE_SPLASHSCREEN_JUCEHEADER__
#define __JUCE_SPLASHSCREEN_JUCEHEADER__

/** A component for showing a splash screen while your app starts up.

    This will automatically position itself, and delete itself when the app has
    finished initialising (it uses the JUCEApplication::isInitialising() to detect
    this).

    To use it, just create one of these in your JUCEApplication::initialise() method,
    call its show() method and let the object delete itself later.

    E.g. @code

    void MyApp::initialise (const String& commandLine)
    {
        SplashScreen* splash = new SplashScreen();

        splash->show (T("welcome to my app"),
                      ImageCache::getFromFile (File ("/foobar/splash.jpg")),
                      4000, false);

        .. no need to delete the splash screen - it'll do that itself.
    }

    @endcode
*/
class JUCE_API  SplashScreen  : public Component,
                                public Timer,
                                private DeletedAtShutdown
{
public:

    /** Creates a SplashScreen object.

        After creating one of these (or your subclass of it), call one of the show()
        methods to display it.
    */
    SplashScreen();

    /** Destructor. */
    ~SplashScreen();

    /** Creates a SplashScreen object that will display an image.

        As soon as this is called, the SplashScreen will be displayed in the centre of the
        screen. This method will also dispatch any pending messages to make sure that when
        it returns, the splash screen has been completely drawn, and your initialisation
        code can carry on.

        @param title            the name to give the component
        @param backgroundImage  an image to draw on the component. The component's size
                                will be set to the size of this image, and if the image is
                                semi-transparent, the component will be made semi-transparent
                                too. This image will be deleted (or released from the ImageCache
                                if that's how it was created) by the splash screen object when
                                it is itself deleted.
        @param minimumTimeToDisplayFor    how long (in milliseconds) the splash screen
                                should stay visible for. If the initialisation takes longer than
                                this time, the splash screen will wait for it to finish before
                                disappearing, but if initialisation is very quick, this lets
                                you make sure that people get a good look at your splash.
        @param useDropShadow    if true, the window will have a drop shadow
        @param removeOnMouseClick   if true, the window will go away as soon as the user clicks
                                the mouse (anywhere)
    */
    void show (const String& title,
               Image* const backgroundImage,
               const int minimumTimeToDisplayFor,
               const bool useDropShadow,
               const bool removeOnMouseClick = true);

    /** Creates a SplashScreen object with a specified size.

        For a custom splash screen, you can use this method to display it at a certain size
        and then override the paint() method yourself to do whatever's necessary.

        As soon as this is called, the SplashScreen will be displayed in the centre of the
        screen. This method will also dispatch any pending messages to make sure that when
        it returns, the splash screen has been completely drawn, and your initialisation
        code can carry on.

        @param title            the name to give the component
        @param width            the width to use
        @param height           the height to use
        @param minimumTimeToDisplayFor    how long (in milliseconds) the splash screen
                                should stay visible for. If the initialisation takes longer than
                                this time, the splash screen will wait for it to finish before
                                disappearing, but if initialisation is very quick, this lets
                                you make sure that people get a good look at your splash.
        @param useDropShadow    if true, the window will have a drop shadow
        @param removeOnMouseClick   if true, the window will go away as soon as the user clicks
                                the mouse (anywhere)
    */
    void show (const String& title,
               const int width,
               const int height,
               const int minimumTimeToDisplayFor,
               const bool useDropShadow,
               const bool removeOnMouseClick = true);

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void timerCallback();

    juce_UseDebuggingNewOperator

private:
    Image* backgroundImage;
    Time earliestTimeToDelete;
    int originalClickCounter;
    bool isImageInCache;

    SplashScreen (const SplashScreen&);
    const SplashScreen& operator= (const SplashScreen&);
};

#endif   // __JUCE_SPLASHSCREEN_JUCEHEADER__
/********* End of inlined file: juce_SplashScreen.h *********/

#endif
#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__

/********* Start of inlined file: juce_ThreadWithProgressWindow.h *********/
#ifndef __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__
#define __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__

/**
    A thread that automatically pops up a modal dialog box with a progress bar
    and cancel button while it's busy running.

    These are handy for performing some sort of task while giving the user feedback
    about how long there is to go, etc.

    E.g. @code
    class MyTask  : public ThreadWithProgressWindow
    {
    public:
        MyTask()    : ThreadWithProgressWindow (T("busy..."), true, true)
        {
        }

        ~MyTask()
        {
        }

        void run()
        {
            for (int i = 0; i < thingsToDo; ++i)
            {
                // must check this as often as possible, because this is
                // how we know if the user's pressed 'cancel'
                if (threadShouldExit())
                    break;

                // this will update the progress bar on the dialog box
                setProgress (i / (double) thingsToDo);

                //   ... do the business here...
            }
        }
    };

    void doTheTask()
    {
        MyTask m;

        if (m.runThread())
        {
            // thread finished normally..
        }
        else
        {
            // user pressed the cancel button..
        }
    }

    @endcode

    @see Thread, AlertWindow
*/
class JUCE_API  ThreadWithProgressWindow  : public Thread,
                                            private Timer
{
public:

    /** Creates the thread.

        Initially, the dialog box won't be visible, it'll only appear when the
        runThread() method is called.

        @param windowTitle              the title to go at the top of the dialog box
        @param hasProgressBar           whether the dialog box should have a progress bar (see
                                        setProgress() )
        @param hasCancelButton          whether the dialog box should have a cancel button
        @param timeOutMsWhenCancelling  when 'cancel' is pressed, this is how long to wait for
                                        the thread to stop before killing it forcibly (see
                                        Thread::stopThread() )
        @param cancelButtonText         the text that should be shown in the cancel button
                                        (if it has one)
    */
    ThreadWithProgressWindow (const String& windowTitle,
                              const bool hasProgressBar,
                              const bool hasCancelButton,
                              const int timeOutMsWhenCancelling = 10000,
                              const String& cancelButtonText = JUCE_T("Cancel"));

    /** Destructor. */
    ~ThreadWithProgressWindow();

    /** Starts the thread and waits for it to finish.

        This will start the thread, make the dialog box appear, and wait until either
        the thread finishes normally, or until the cancel button is pressed.

        Before returning, the dialog box will be hidden.

        @param threadPriority   the priority to use when starting the thread - see
                                Thread::startThread() for values
        @returns true if the thread finished normally; false if the user pressed cancel
    */
    bool runThread (const int threadPriority = 5);

    /** The thread should call this periodically to update the position of the progress bar.

        @param newProgress  the progress, from 0.0 to 1.0
        @see setStatusMessage
    */
    void setProgress (const double newProgress);

    /** The thread can call this to change the message that's displayed in the dialog box.
    */
    void setStatusMessage (const String& newStatusMessage);

    juce_UseDebuggingNewOperator

private:
    void timerCallback();

    double progress;
    AlertWindow* alertWindow;
    String message;
    CriticalSection messageLock;
    const int timeOutMsWhenCancelling;

    ThreadWithProgressWindow (const ThreadWithProgressWindow&);
    const ThreadWithProgressWindow& operator= (const ThreadWithProgressWindow&);
};

#endif   // __JUCE_THREADWITHPROGRESSWINDOW_JUCEHEADER__
/********* End of inlined file: juce_ThreadWithProgressWindow.h *********/

#endif
#ifndef __JUCE_TOPLEVELWINDOW_JUCEHEADER__

#endif
#ifndef __JUCE_COMPONENTPEER_JUCEHEADER__

#endif
#ifndef __JUCE_TOOLTIPWINDOW_JUCEHEADER__

#endif
#ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_ActiveXControlComponent.h *********/
#ifndef __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__
#define __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__

#if JUCE_WIN32 || DOXYGEN

/**
    A Windows-specific class that can create and embed an ActiveX control inside
    itself.

    To use it, create one of these, put it in place and make sure it's visible in a
    window, then use createControl() to instantiate an ActiveX control. The control
    will then be moved and resized to follow the movements of this component.

    Of course, since the control is a heavyweight window, it'll obliterate any
    juce components that may overlap this component, but that's life.
*/
class JUCE_API  ActiveXControlComponent   : public Component
{
public:

    /** Create an initially-empty container. */
    ActiveXControlComponent();

    /** Destructor. */
    ~ActiveXControlComponent();

    /** Tries to create an ActiveX control and embed it in this peer.

        The peer controlIID is a pointer to an IID structure - it's treated
        as a void* because when including the Juce headers, you might not always
        have included windows.h first, in which case IID wouldn't be defined.

        e.g. @code
        const IID myIID = __uuidof (QTControl);
        myControlComp->createControl (&myIID);
        @endcode
    */
    bool createControl (const void* controlIID);

    /** Deletes the ActiveX control, if one has been created.
    */
    void deleteControl();

    /** Returns true if a control is currently in use. */
    bool isControlOpen() const throw()                  { return control != 0; }

    /** Does a QueryInterface call on the embedded control object.

        This allows you to cast the control to whatever type of COM object you need.

        The iid parameter is a pointer to an IID structure - it's treated
        as a void* because when including the Juce headers, you might not always
        have included windows.h first, in which case IID wouldn't be defined, but
        you should just pass a pointer to an IID.

        e.g. @code
        const IID iid = __uuidof (IOleWindow);

        IOleWindow* oleWindow = (IOleWindow*) myControlComp->queryInterface (&iid);

        if (oleWindow != 0)
        {
            HWND hwnd;
            oleWindow->GetWindow (&hwnd);

            ...

            oleWindow->Release();
        }
        @endcode
    */
    void* queryInterface (const void* iid) const;

    /** Set this to false to stop mouse events being allowed through to the control.
    */
    void setMouseEventsAllowed (const bool eventsCanReachControl);

    /** Returns true if mouse events are allowed to get through to the control.
    */
    bool areMouseEventsAllowed() const throw()                  { return mouseEventsAllowed; }

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void* originalWndProc;

    juce_UseDebuggingNewOperator

private:
    friend class ActiveXControlData;
    void* control;
    bool mouseEventsAllowed;

    ActiveXControlComponent (const ActiveXControlComponent&);
    const ActiveXControlComponent& operator= (const ActiveXControlComponent&);

    void setControlBounds (const Rectangle& bounds) const;
    void setControlVisible (const bool b) const;
};

#endif

#endif   // __JUCE_ACTIVEXCONTROLCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_ActiveXControlComponent.h *********/

#endif
#ifndef __JUCE_AUDIODEVICESELECTORCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_AudioDeviceSelectorComponent.h *********/
#ifndef __JUCE_AUDIODEVICESELECTORCOMPONENT_JUCEHEADER__
#define __JUCE_AUDIODEVICESELECTORCOMPONENT_JUCEHEADER__

class MidiInputSelectorComponentListBox;

/**
    A component containing controls to let the user change the audio settings of
    an AudioDeviceManager object.

    Very easy to use - just create one of these and show it to the user.

    @see AudioDeviceManager
*/
class JUCE_API  AudioDeviceSelectorComponent  : public Component,
                                                public ComboBoxListener,
                                                public ButtonListener,
                                                public ChangeListener
{
public:

    /** Creates the component.

        If your app needs only output channels, you might ask for a maximum of 0 input
        channels, and the component won't display any options for choosing the input
        channels. And likewise if you're doing an input-only app.

        @param deviceManager            the device manager that this component should control
        @param minAudioInputChannels    the minimum number of audio input channels that the application needs
        @param maxAudioInputChannels    the maximum number of audio input channels that the application needs
        @param minAudioOutputChannels   the minimum number of audio output channels that the application needs
        @param maxAudioOutputChannels   the maximum number of audio output channels that the application needs
        @param showMidiInputOptions     if true, the component will allow the user to select which midi inputs are enabled
        @param showMidiOutputSelector   if true, the component will let the user choose a default midi output device
        @param showChannelsAsStereoPairs    if true, channels will be treated as pairs; if false, channels will be
                                        treated as a set of separate mono channels.
        @param hideAdvancedOptionsWithButton    if true, only the minimum amount of UI components
                                        are shown, with an "advanced" button that shows the rest of them
    */
    AudioDeviceSelectorComponent (AudioDeviceManager& deviceManager,
                                  const int minAudioInputChannels,
                                  const int maxAudioInputChannels,
                                  const int minAudioOutputChannels,
                                  const int maxAudioOutputChannels,
                                  const bool showMidiInputOptions,
                                  const bool showMidiOutputSelector,
                                  const bool showChannelsAsStereoPairs,
                                  const bool hideAdvancedOptionsWithButton);

    /** Destructor */
    ~AudioDeviceSelectorComponent();

    /** @internal */
    void resized();
    /** @internal */
    void comboBoxChanged (ComboBox*);
    /** @internal */
    void buttonClicked (Button*);
    /** @internal */
    void changeListenerCallback (void*);

    juce_UseDebuggingNewOperator

private:
    AudioDeviceManager& deviceManager;
    ComboBox* deviceTypeDropDown;
    Label* deviceTypeDropDownLabel;
    Component* audioDeviceSettingsComp;
    String audioDeviceSettingsCompType;
    const int minOutputChannels, maxOutputChannels, minInputChannels, maxInputChannels;
    const bool showChannelsAsStereoPairs;
    const bool hideAdvancedOptionsWithButton;

    MidiInputSelectorComponentListBox* midiInputsList;
    Label* midiInputsLabel;
    ComboBox* midiOutputSelector;
    Label* midiOutputLabel;

    AudioDeviceSelectorComponent (const AudioDeviceSelectorComponent&);
    const AudioDeviceSelectorComponent& operator= (const AudioDeviceSelectorComponent&);
};

#endif   // __JUCE_AUDIODEVICESELECTORCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_AudioDeviceSelectorComponent.h *********/

#endif
#ifndef __JUCE_BUBBLECOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_BubbleComponent.h *********/
#ifndef __JUCE_BUBBLECOMPONENT_JUCEHEADER__
#define __JUCE_BUBBLECOMPONENT_JUCEHEADER__

/**
    A component for showing a message or other graphics inside a speech-bubble-shaped
    outline, pointing at a location on the screen.

    This is a base class that just draws and positions the bubble shape, but leaves
    the drawing of any content up to a subclass. See BubbleMessageComponent for a subclass
    that draws a text message.

    To use it, create your subclass, then either add it to a parent component or
    put it on the desktop with addToDesktop (0), use setPosition() to
    resize and position it, then make it visible.

    @see BubbleMessageComponent
*/
class JUCE_API  BubbleComponent  : public Component
{
protected:

    /** Creates a BubbleComponent.

        Your subclass will need to implement the getContentSize() and paintContent()
        methods to draw the bubble's contents.
    */
    BubbleComponent();

public:
    /** Destructor. */
    ~BubbleComponent();

    /** A list of permitted placements for the bubble, relative to the co-ordinates
        at which it should be pointing.

        @see setAllowedPlacement
    */
    enum BubblePlacement
    {
        above   = 1,
        below   = 2,
        left    = 4,
        right   = 8
    };

    /** Tells the bubble which positions it's allowed to put itself in, relative to the
        point at which it's pointing.

        By default when setPosition() is called, the bubble will place itself either
        above, below, left, or right of the target area. You can pass in a bitwise-'or' of
        the values in BubblePlacement to restrict this choice.

        E.g. if you only want your bubble to appear above or below the target area,
        use setAllowedPlacement (above | below);

        @see BubblePlacement
    */
    void setAllowedPlacement (const int newPlacement);

    /** Moves and resizes the bubble to point at a given component.

        This will resize the bubble to fit its content, then find a position for it
        so that it's next to, but doesn't overlap the given component.

        It'll put itself either above, below, or to the side of the component depending
        on where there's the most space, honouring any restrictions that were set
        with setAllowedPlacement().
    */
    void setPosition (Component* componentToPointTo);

    /** Moves and resizes the bubble to point at a given point.

        This will resize the bubble to fit its content, then position it
        so that the tip of the bubble points to the given co-ordinate. The co-ordinates
        are relative to either the bubble component's parent component if it has one, or
        they are screen co-ordinates if not.

        It'll put itself either above, below, or to the side of this point, depending
        on where there's the most space, honouring any restrictions that were set
        with setAllowedPlacement().
    */
    void setPosition (const int arrowTipX,
                      const int arrowTipY);

    /** Moves and resizes the bubble to point at a given rectangle.

        This will resize the bubble to fit its content, then find a position for it
        so that it's next to, but doesn't overlap the given rectangle. The rectangle's
        co-ordinates are relative to either the bubble component's parent component
        if it has one, or they are screen co-ordinates if not.

        It'll put itself either above, below, or to the side of the component depending
        on where there's the most space, honouring any restrictions that were set
        with setAllowedPlacement().
    */
    void setPosition (const Rectangle& rectangleToPointTo);

protected:

    /** Subclasses should override this to return the size of the content they
        want to draw inside the bubble.
    */
    virtual void getContentSize (int& width, int& height) = 0;

    /** Subclasses should override this to draw their bubble's contents.

        The graphics object's clip region and the dimensions passed in here are
        set up to paint just the rectangle inside the bubble.
    */
    virtual void paintContent (Graphics& g, int width, int height) = 0;

public:

    /** @internal */
    void paint (Graphics& g);

    juce_UseDebuggingNewOperator

private:
    Rectangle content;
    int side, allowablePlacements;
    float arrowTipX, arrowTipY;
    DropShadowEffect shadow;

    BubbleComponent (const BubbleComponent&);
    const BubbleComponent& operator= (const BubbleComponent&);
};

#endif   // __JUCE_BUBBLECOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_BubbleComponent.h *********/

#endif
#ifndef __JUCE_BUBBLEMESSAGECOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_BubbleMessageComponent.h *********/
#ifndef __JUCE_BUBBLEMESSAGECOMPONENT_JUCEHEADER__
#define __JUCE_BUBBLEMESSAGECOMPONENT_JUCEHEADER__

/**
    A speech-bubble component that displays a short message.

    This can be used to show a message with the tail of the speech bubble
    pointing to a particular component or location on the screen.

    @see BubbleComponent
*/
class JUCE_API  BubbleMessageComponent  : public BubbleComponent,
                                          private Timer
{
public:

    /** Creates a bubble component.

        After creating one a BubbleComponent, do the following:
        - add it to an appropriate parent component, or put it on the
          desktop with Component::addToDesktop (0).
        - use the showAt() method to show a message.
        - it will make itself invisible after it times-out (and can optionally
          also delete itself), or you can reuse it somewhere else by calling
          showAt() again.
    */
    BubbleMessageComponent (const int fadeOutLengthMs = 150);

    /** Destructor. */
    ~BubbleMessageComponent();

    /** Shows a message bubble at a particular position.

        This shows the bubble with its stem pointing to the given location
        (co-ordinates being relative to its parent component).

        For details about exactly how it decides where to position itself, see
        BubbleComponent::updatePosition().

        @param x                                the x co-ordinate of end of the bubble's tail
        @param y                                the y co-ordinate of end of the bubble's tail
        @param message                          the text to display
        @param numMillisecondsBeforeRemoving    how long to leave it on the screen before removing itself
                                                from its parent compnent. If this is 0 or less, it
                                                will stay there until manually removed.
        @param removeWhenMouseClicked           if this is true, the bubble will disappear as soon as a
                                                mouse button is pressed (anywhere on the screen)
        @param deleteSelfAfterUse               if true, then the component will delete itself after
                                                it becomes invisible
    */
    void showAt (int x, int y,
                 const String& message,
                 const int numMillisecondsBeforeRemoving,
                 const bool removeWhenMouseClicked = true,
                 const bool deleteSelfAfterUse = false);

    /** Shows a message bubble next to a particular component.

        This shows the bubble with its stem pointing at the given component.

        For details about exactly how it decides where to position itself, see
        BubbleComponent::updatePosition().

        @param component                        the component that you want to point at
        @param message                          the text to display
        @param numMillisecondsBeforeRemoving    how long to leave it on the screen before removing itself
                                                from its parent compnent. If this is 0 or less, it
                                                will stay there until manually removed.
        @param removeWhenMouseClicked           if this is true, the bubble will disappear as soon as a
                                                mouse button is pressed (anywhere on the screen)
        @param deleteSelfAfterUse               if true, then the component will delete itself after
                                                it becomes invisible
    */
    void showAt (Component* const component,
                 const String& message,
                 const int numMillisecondsBeforeRemoving,
                 const bool removeWhenMouseClicked = true,
                 const bool deleteSelfAfterUse = false);

    /** @internal */
    void getContentSize (int& w, int& h);
    /** @internal */
    void paintContent (Graphics& g, int w, int h);
    /** @internal */
    void timerCallback();

    juce_UseDebuggingNewOperator

private:
    int fadeOutLength, mouseClickCounter;
    TextLayout textLayout;
    int64 expiryTime;
    bool deleteAfterUse;

    void init (const int numMillisecondsBeforeRemoving,
               const bool removeWhenMouseClicked,
               const bool deleteSelfAfterUse);

    BubbleMessageComponent (const BubbleMessageComponent&);
    const BubbleMessageComponent& operator= (const BubbleMessageComponent&);
};

#endif   // __JUCE_BUBBLEMESSAGECOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_BubbleMessageComponent.h *********/

#endif
#ifndef __JUCE_COLOURSELECTOR_JUCEHEADER__

/********* Start of inlined file: juce_ColourSelector.h *********/
#ifndef __JUCE_COLOURSELECTOR_JUCEHEADER__
#define __JUCE_COLOURSELECTOR_JUCEHEADER__

/**
    A component that lets the user choose a colour.

    This shows RGB sliders and a colourspace that the user can pick colours from.

    This class is also a ChangeBroadcaster, so listeners can register to be told
    when the colour changes.
*/
class JUCE_API  ColourSelector  : public Component,
                                  public ChangeBroadcaster,
                                  protected SliderListener
{
public:

    /** Options for the type of selector to show. These are passed into the constructor. */
    enum ColourSelectorOptions
    {
        showAlphaChannel    = 1 << 0,   /**< if set, the colour's alpha channel can be changed as well as its RGB. */

        showColourAtTop     = 1 << 1,   /**< if set, a swatch of the colour is shown at the top of the component. */
        showSliders         = 1 << 2,   /**< if set, RGB sliders are shown at the bottom of the component. */
        showColourspace     = 1 << 3    /**< if set, a big HSV selector is shown. */
    };

    /** Creates a ColourSelector object.

        The flags are a combination of values from the ColourSelectorOptions enum, specifying
        which of the selector's features should be visible.

        The edgeGap value specifies the amount of space to leave around the edge.

        gapAroundColourSpaceComponent indicates how much of a gap to put around the
        colourspace and hue selector components.
    */
    ColourSelector (const int sectionsToShow = (showAlphaChannel | showColourAtTop | showSliders | showColourspace),
                    const int edgeGap = 4,
                    const int gapAroundColourSpaceComponent = 7);

    /** Destructor. */
    ~ColourSelector();

    /** Returns the colour that the user has currently selected.

        The ColourSelector class is also a ChangeBroadcaster, so listeners can
        register to be told when the colour changes.

        @see setCurrentColour
    */
    const Colour getCurrentColour() const;

    /** Changes the colour that is currently being shown.
    */
    void setCurrentColour (const Colour& newColour);

    /** Tells the selector how many preset colour swatches you want to have on the component.

        To enable swatches, you'll need to override getNumSwatches(), getSwatchColour(), and
        setSwatchColour(), to return the number of colours you want, and to set and retrieve
        their values.
    */
    virtual int getNumSwatches() const;

    /** Called by the selector to find out the colour of one of the swatches.

        Your subclass should return the colour of the swatch with the given index.

        To enable swatches, you'll need to override getNumSwatches(), getSwatchColour(), and
        setSwatchColour(), to return the number of colours you want, and to set and retrieve
        their values.
    */
    virtual const Colour getSwatchColour (const int index) const;

    /** Called by the selector when the user puts a new colour into one of the swatches.

        Your subclass should change the colour of the swatch with the given index.

        To enable swatches, you'll need to override getNumSwatches(), getSwatchColour(), and
        setSwatchColour(), to return the number of colours you want, and to set and retrieve
        their values.
    */
    virtual void setSwatchColour (const int index, const Colour& newColour) const;

    /** A set of colour IDs to use to change the colour of various aspects of the keyboard.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        backgroundColourId              = 0x1007000,    /**< the colour used to fill the component's background. */
        labelTextColourId               = 0x1007001     /**< the colour used for the labels next to the sliders. */
    };

    juce_UseDebuggingNewOperator

private:
    friend class ColourSpaceView;
    friend class HueSelectorComp;
    Colour colour;
    float h, s, v;
    Slider* sliders[4];
    Component* colourSpace;
    Component* hueSelector;
    VoidArray swatchComponents;
    const int flags;
    int topSpace, edgeGap;

    void setHue (float newH);
    void setSV (float newS, float newV);
    void updateHSV();
    void update();
    void sliderValueChanged (Slider*);
    void paint (Graphics& g);
    void resized();

    ColourSelector (const ColourSelector&);
    const ColourSelector& operator= (const ColourSelector&);

    // this constructor is here temporarily to prevent old code compiling, because the parameters
    // have changed - if you get an error here, update your code to use the new constructor instead..
    // (xxx - note to self: remember to remove this at some point in the future)
    ColourSelector (const bool);
};

#endif   // __JUCE_COLOURSELECTOR_JUCEHEADER__
/********* End of inlined file: juce_ColourSelector.h *********/

#endif
#ifndef __JUCE_DROPSHADOWER_JUCEHEADER__

#endif
#ifndef __JUCE_NSVIEWCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_NSViewComponent.h *********/
#ifndef __JUCE_NSVIEWCOMPONENT_JUCEHEADER__
#define __JUCE_NSVIEWCOMPONENT_JUCEHEADER__

#if ! DOXYGEN
 class NSViewComponentInternal;
#endif

#if JUCE_MAC || DOXYGEN

/**
    A Mac-specific class that can create and embed an NSView inside itself.

    To use it, create one of these, put it in place and make sure it's visible in a
    window, then use setView() to assign an NSView to it. The view will then be
    moved and resized to follow the movements of this component.

    Of course, since the view is a native object, it'll obliterate any
    juce components that may overlap this component, but that's life.
*/
class JUCE_API  NSViewComponent   : public Component
{
public:

    /** Create an initially-empty container. */
    NSViewComponent();

    /** Destructor. */
    ~NSViewComponent();

    /** Assigns an NSView to this peer.

        The view will be retained and released by this component for as long as
        it is needed. To remove the current view, just call setView (0).

        Note: a void* is used here to avoid including the cocoa headers as
        part of the juce.h, but the method expects an NSView*.
    */
    void setView (void* nsView);

    /** Returns the current NSView.

        Note: a void* is returned here to avoid including the cocoa headers as
        a requirement of juce.h, so you should just cast the object to an NSView*.
    */
    void* getView() const;

    /** @internal */
    void paint (Graphics& g);

    juce_UseDebuggingNewOperator

private:
    friend class NSViewComponentInternal;
    NSViewComponentInternal* info;

    NSViewComponent (const NSViewComponent&);
    const NSViewComponent& operator= (const NSViewComponent&);
};

#endif

#endif   // __JUCE_NSVIEWCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_NSViewComponent.h *********/

#endif
#ifndef __JUCE_OPENGLCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_OpenGLComponent.h *********/
#ifndef __JUCE_OPENGLCOMPONENT_JUCEHEADER__
#define __JUCE_OPENGLCOMPONENT_JUCEHEADER__

// this is used to disable OpenGL, and is defined in juce_Config.h
#if JUCE_OPENGL || DOXYGEN

class OpenGLComponentWatcher;

/**
    Represents the various properties of an OpenGL bitmap format.

    @see OpenGLComponent::setPixelFormat
*/
struct OpenGLPixelFormat
{

    /** Creates an OpenGLPixelFormat.

        The default constructor just initialises the object as a simple 8-bit
        RGBA format.
    */
    OpenGLPixelFormat (const int bitsPerRGBComponent = 8,
                       const int alphaBits = 8,
                       const int depthBufferBits = 16,
                       const int stencilBufferBits = 0) throw();

    int redBits;          /**< The number of bits per pixel to use for the red channel. */
    int greenBits;        /**< The number of bits per pixel to use for the green channel. */
    int blueBits;         /**< The number of bits per pixel to use for the blue channel. */
    int alphaBits;        /**< The number of bits per pixel to use for the alpha channel. */

    int depthBufferBits;      /**< The number of bits per pixel to use for a depth buffer. */
    int stencilBufferBits;    /**< The number of bits per pixel to use for a stencil buffer. */

    int accumulationBufferRedBits;    /**< The number of bits per pixel to use for an accumulation buffer's red channel. */
    int accumulationBufferGreenBits;  /**< The number of bits per pixel to use for an accumulation buffer's green channel. */
    int accumulationBufferBlueBits;   /**< The number of bits per pixel to use for an accumulation buffer's blue channel. */
    int accumulationBufferAlphaBits;  /**< The number of bits per pixel to use for an accumulation buffer's alpha channel. */

    uint8 fullSceneAntiAliasingNumSamples;      /**< The number of samples to use in full-scene anti-aliasing (if available). */

    /** Returns a list of all the pixel formats that can be used in this system.

        A reference component is needed in case there are multiple screens with different
        capabilities - in which case, the one that the component is on will be used.
    */
    static void getAvailablePixelFormats (Component* component,
                                          OwnedArray <OpenGLPixelFormat>& results);

    bool operator== (const OpenGLPixelFormat&) const throw();

    juce_UseDebuggingNewOperator
};

/**
    A base class for types of OpenGL context.

    An OpenGLComponent will supply its own context for drawing in its window.
*/
class OpenGLContext
{
public:

    /** Destructor. */
    virtual ~OpenGLContext();

    /** Makes this context the currently active one. */
    virtual bool makeActive() const throw() = 0;
    /** If this context is currently active, it is disactivated. */
    virtual bool makeInactive() const throw() = 0;
    /** Returns true if this context is currently active. */
    virtual bool isActive() const throw() = 0;

    /** Swaps the buffers (if the context can do this). */
    virtual void swapBuffers() = 0;

    /** Sets whether the context checks the vertical sync before swapping.

        The value is the number of frames to allow between buffer-swapping. This is
        fairly system-dependent, but 0 turns off syncing, 1 makes it swap on frame-boundaries,
        and greater numbers indicate that it should swap less often.

        Returns true if it sets the value successfully.
    */
    virtual bool setSwapInterval (const int numFramesPerSwap) = 0;

    /** Returns the current swap-sync interval.
        See setSwapInterval() for info about the value returned.
    */
    virtual int getSwapInterval() const = 0;

    /** Returns the pixel format being used by this context. */
    virtual const OpenGLPixelFormat getPixelFormat() const = 0;

    /** For windowed contexts, this moves the context within the bounds of
        its parent window.
    */
    virtual void updateWindowPosition (int x, int y, int w, int h, int outerWindowHeight) = 0;

    /** For windowed contexts, this triggers a repaint of the window.

        (Not relevent on all platforms).
    */
    virtual void repaint() = 0;

    /** Returns an OS-dependent handle to the raw GL context.

        On win32, this will be a HGLRC; on the Mac, an AGLContext; on Linux,
        a GLXContext.
    */
    virtual void* getRawContext() const throw() = 0;

    /** This tries to create a context that can be used for drawing into the
        area occupied by the specified component.

        Note that you probably shouldn't use this method directly unless you know what
        you're doing - the OpenGLComponent calls this and manages the context for you.
    */
    static OpenGLContext* createContextForWindow (Component* componentToDrawTo,
                                                  const OpenGLPixelFormat& pixelFormat,
                                                  const OpenGLContext* const contextToShareWith);

    /** Returns the context that's currently in active use by the calling thread.

        Returns 0 if there isn't an active context.
    */
    static OpenGLContext* getCurrentContext();

    juce_UseDebuggingNewOperator

protected:
    OpenGLContext() throw();
};

/**
    A component that contains an OpenGL canvas.

    Override this, add it to whatever component you want to, and use the renderOpenGL()
    method to draw its contents.

*/
class JUCE_API  OpenGLComponent  : public Component
{
public:

    /** Creates an OpenGLComponent.
    */
    OpenGLComponent();

    /** Destructor. */
    ~OpenGLComponent();

    /** Changes the pixel format used by this component.

        @see OpenGLPixelFormat::getAvailablePixelFormats()
    */
    void setPixelFormat (const OpenGLPixelFormat& formatToUse);

    /** Returns the pixel format that this component is currently using. */
    const OpenGLPixelFormat getPixelFormat() const;

    /** Specifies an OpenGL context which should be shared with the one that this
        component is using.

        This is an OpenGL feature that lets two contexts share their texture data.

        Note that this pointer is stored by the component, and when the component
        needs to recreate its internal context for some reason, the same context
        will be used again to share lists. So if you pass a context in here,
        don't delete the context while this component is still using it! You can
        call shareWith (0) to stop this component from sharing with it.
    */
    void shareWith (OpenGLContext* contextToShareListsWith);

    /** Returns the context that this component is sharing with.
        @see shareWith
    */
    OpenGLContext* getShareContext() const throw()    { return contextToShareListsWith; }

    /** Flips the openGL buffers over. */
    void swapBuffers();

    /** This replaces the normal paint() callback - use it to draw your openGL stuff.

        When this is called, makeCurrentContextActive() will already have been called
        for you, so you just need to draw.
    */
    virtual void renderOpenGL() = 0;

    /** This method is called when the component creates a new OpenGL context.

        A new context may be created when the component is first used, or when it
        is moved to a different window, or when the window is hidden and re-shown,
        etc.

        You can use this callback as an opportunity to set up things like textures
        that your context needs.

        New contexts are created on-demand by the makeCurrentContextActive() method - so
        if the context is deleted, e.g. by changing the pixel format or window, no context
        will be created until the next call to makeCurrentContextActive(), which will
        synchronously create one and call this method. This means that if you're using
        a non-GUI thread for rendering, you can make sure this method is be called by
        your renderer thread.

        When this callback happens, the context will already have been made current
        using the makeCurrentContextActive() method, so there's no need to call it
        again in your code.
    */
    virtual void newOpenGLContextCreated() = 0;

    /** Returns the context that will draw into this component.

        This may return 0 if the component is currently invisible or hasn't currently
        got a context. The context object can be deleted and a new one created during
        the lifetime of this component, and there may be times when it doesn't have one.

        @see newOpenGLContextCreated()
    */
    OpenGLContext* getCurrentContext() const throw()            { return context; }

    /** Makes this component the current openGL context.

        You might want to use this in things like your resize() method, before calling
        GL commands.

        If this returns false, then the context isn't active, so you should avoid
        making any calls.

        This call may actually create a context if one isn't currently initialised. If
        it does this, it will also synchronously call the newOpenGLContextCreated()
        method to let you initialise it as necessary.

        @see OpenGLContext::makeActive
    */
    bool makeCurrentContextActive();

    /** Stops the current component being the active OpenGL context.

        This is the opposite of makeCurrentContextActive()

        @see OpenGLContext::makeInactive
    */
    void makeCurrentContextInactive();

    /** Returns true if this component is the active openGL context for the
        current thread.

        @see OpenGLContext::isActive
    */
    bool isActiveContext() const throw();

    /** Calls the rendering callback, and swaps the buffers afterwards.

        This is called automatically by paint() when the component needs to be rendered.

        It can be overridden if you need to decouple the rendering from the paint callback
        and render with a custom thread.

        Returns true if the operation succeeded.
    */
    virtual bool renderAndSwapBuffers();

    /** This returns a critical section that can be used to lock the current context.

        Because the context that is used by this component can change, e.g. when the
        component is shown or hidden, then if you're rendering to it on a background
        thread, this allows you to lock the context for the duration of your rendering
        routine.
    */
    CriticalSection& getContextLock() throw()       { return contextLock; }

    /** @internal */
    void paint (Graphics& g);

    /** Returns the native handle of an embedded heavyweight window, if there is one.

        E.g. On windows, this will return the HWND of the sub-window containing
        the opengl context, on the mac it'll be the NSOpenGLView.
    */
    void* getNativeWindowHandle() const;

    juce_UseDebuggingNewOperator

private:
    friend class OpenGLComponentWatcher;
    OpenGLComponentWatcher* componentWatcher;

    OpenGLContext* context;
    OpenGLContext* contextToShareListsWith;

    CriticalSection contextLock;
    OpenGLPixelFormat preferredPixelFormat;
    bool needToUpdateViewport;

    void deleteContext();
    void updateContextPosition();
    void internalRepaint (int x, int y, int w, int h);

    OpenGLComponent (const OpenGLComponent&);
    const OpenGLComponent& operator= (const OpenGLComponent&);
};

#endif
#endif   // __JUCE_OPENGLCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_OpenGLComponent.h *********/

#endif
#ifndef __JUCE_PREFERENCESPANEL_JUCEHEADER__

/********* Start of inlined file: juce_PreferencesPanel.h *********/
#ifndef __JUCE_PREFERENCESPANEL_JUCEHEADER__
#define __JUCE_PREFERENCESPANEL_JUCEHEADER__

/**
    A component with a set of buttons at the top for changing between pages of
    preferences.

    This is just a handy way of writing a Mac-style preferences panel where you
    have a row of buttons along the top for the different preference categories,
    each button having an icon above its name. Clicking these will show an
    appropriate prefs page below it.

    You can either put one of these inside your own component, or just use the
    showInDialogBox() method to show it in a window and run it modally.

    To use it, just add a set of named pages with the addSettingsPage() method,
    and implement the createComponentForPage() method to create suitable components
    for each of these pages.
*/
class JUCE_API  PreferencesPanel  : public Component,
                                    private ButtonListener
{
public:

    /** Creates an empty panel.

        Use addSettingsPage() to add some pages to it in your constructor.
    */
    PreferencesPanel();

    /** Destructor. */
    ~PreferencesPanel();

    /** Creates a page using a set of drawables to define the page's icon.

        Note that the other version of this method is much easier if you're using
        an image instead of a custom drawable.

        @param pageTitle    the name of this preferences page - you'll need to
                            make sure your createComponentForPage() method creates
                            a suitable component when it is passed this name
        @param normalIcon   the drawable to display in the page's button normally
        @param overIcon     the drawable to display in the page's button when the mouse is over
        @param downIcon     the drawable to display in the page's button when the button is down
        @see DrawableButton
    */
    void addSettingsPage (const String& pageTitle,
                          const Drawable* normalIcon,
                          const Drawable* overIcon,
                          const Drawable* downIcon);

    /** Creates a page using a set of drawables to define the page's icon.

        The other version of this method gives you more control over the icon, but this
        one is much easier if you're just loading it from a file.

        @param pageTitle        the name of this preferences page - you'll need to
                                make sure your createComponentForPage() method creates
                                a suitable component when it is passed this name
        @param imageData        a block of data containing an image file, e.g. a jpeg, png or gif.
                                For this to look good, you'll probably want to use a nice
                                transparent png file.
        @param imageDataSize    the size of the image data, in bytes
    */
    void addSettingsPage (const String& pageTitle,
                          const char* imageData,
                          const int imageDataSize);

    /** Utility method to display this panel in a DialogWindow.

        Calling this will create a DialogWindow containing this panel with the
        given size and title, and will run it modally, returning when the user
        closes the dialog box.
    */
    void showInDialogBox (const String& dialogtitle,
                          int dialogWidth,
                          int dialogHeight,
                          const Colour& backgroundColour = Colours::white);

    /** Subclasses must override this to return a component for each preferences page.

        The subclass should return a pointer to a new component representing the named
        page, which the panel will then display.

        The panel will delete the component later when the user goes to another page
        or deletes the panel.
    */
    virtual Component* createComponentForPage (const String& pageName) = 0;

    /** Changes the current page being displayed. */
    void setCurrentPage (const String& pageName);

    /** @internal */
    void resized();
    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void buttonClicked (Button* button);

    juce_UseDebuggingNewOperator

private:

    String currentPageName;
    Component* currentPage;
    int buttonSize;

    PreferencesPanel (const PreferencesPanel&);
    const PreferencesPanel& operator= (const PreferencesPanel&);
};

#endif   // __JUCE_PREFERENCESPANEL_JUCEHEADER__
/********* End of inlined file: juce_PreferencesPanel.h *********/

#endif
#ifndef __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_MagnifierComponent.h *********/
#ifndef __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__
#define __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__

/**
    A component that contains another component, and can magnify or shrink it.

    This component will continually update its size so that it fits the zoomed
    version of the content component that you put inside it, so don't try to
    change the size of this component directly - instead change that of the
    content component.

    To make it all work, the magnifier uses extremely cunning ComponentPeer tricks
    to remap mouse events correctly. This means that the content component won't
    appear to be a direct child of this component, and instead will think its
    on the desktop.
*/
class JUCE_API  MagnifierComponent    : public Component
{
public:

    /** Creates a MagnifierComponent.

        This component will continually update its size so that it fits the zoomed
        version of the content component that you put inside it, so don't try to
        change the size of this component directly - instead change that of the
        content component.

        @param contentComponent     the component to add as the magnified one
        @param deleteContentCompWhenNoLongerNeeded  if true, the content component will
                                    be deleted when this component is deleted. If false,
                                    it's the caller's responsibility to delete it later.
    */
    MagnifierComponent (Component* const contentComponent,
                        const bool deleteContentCompWhenNoLongerNeeded);

    /** Destructor. */
    ~MagnifierComponent();

    /** Returns the current content component. */
    Component* getContentComponent() const throw()          { return content; }

    /** Changes the zoom level.

        The scale factor must be greater than zero. Values less than 1 will shrink the
        image; values greater than 1 will multiply its size by this amount.

        When this is called, this component will change its size to fit the full extent
        of the newly zoomed content.
    */
    void setScaleFactor (double newScaleFactor);

    /** Returns the current zoom factor. */
    double getScaleFactor() const throw()                   { return scaleFactor; }

    /** Changes the quality setting used to rescale the graphics.
    */
    void setResamplingQuality (Graphics::ResamplingQuality newQuality);

    juce_UseDebuggingNewOperator

    /** @internal */
    void childBoundsChanged (Component*);

private:
    Component* content;
    Component* holderComp;
    double scaleFactor;
    ComponentPeer* peer;
    bool deleteContent;
    Graphics::ResamplingQuality quality;

    void paint (Graphics& g);
    void mouseDown (const MouseEvent& e);
    void mouseUp (const MouseEvent& e);
    void mouseDrag (const MouseEvent& e);
    void mouseMove (const MouseEvent& e);
    void mouseEnter (const MouseEvent& e);
    void mouseExit (const MouseEvent& e);
    void mouseWheelMove (const MouseEvent& e, float, float);

    int scaleInt (const int n) const throw();

    MagnifierComponent (const MagnifierComponent&);
    const MagnifierComponent& operator= (const MagnifierComponent&);
};

#endif   // __JUCE_MAGNIFIERCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_MagnifierComponent.h *********/

#endif
#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_WebBrowserComponent.h *********/
#ifndef __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
#define __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__

#if JUCE_WEB_BROWSER

class WebBrowserComponentInternal;

/**
    A component that displays an embedded web browser.

    The browser itself will be platform-dependent. On the Mac, probably Safari, on
    Windows, probably IE.

*/
class JUCE_API  WebBrowserComponent      : public Component
{
public:

    /** Creates a WebBrowserComponent.

        Once it's created and visible, send the browser to a URL using goToURL().
    */
    WebBrowserComponent();

    /** Destructor. */
    ~WebBrowserComponent();

    /** Sends the browser to a particular URL.

        @param url      the URL to go to.
        @param headers  an optional set of parameters to put in the HTTP header. If
                        you supply this, it should be a set of string in the form
                        "HeaderKey: HeaderValue"
        @param postData an optional block of data that will be attached to the HTTP
                        POST request
    */
    void goToURL (const String& url,
                  const StringArray* headers = 0,
                  const MemoryBlock* postData = 0);

    /** Stops the current page loading.
    */
    void stop();

    /** Sends the browser back one page.
    */
    void goBack();

    /** Sends the browser forward one page.
    */
    void goForward();

    /** Refreshes the browser.
    */
    void refresh();

    /** This callback is called when the browser is about to navigate
        to a new location.

        You can override this method to perform some action when the user
        tries to go to a particular URL. To allow the operation to carry on,
        return true, or return false to stop the navigation happening.
    */
    virtual bool pageAboutToLoad (const String& newURL);

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void parentHierarchyChanged();
    /** @internal */
    void visibilityChanged();

    juce_UseDebuggingNewOperator

private:
    WebBrowserComponentInternal* browser;
    bool blankPageShown;

    String lastURL;
    StringArray lastHeaders;
    MemoryBlock lastPostData;

    void reloadLastURL();
    void checkWindowAssociation();

    WebBrowserComponent (const WebBrowserComponent&);
    const WebBrowserComponent& operator= (const WebBrowserComponent&);
};

#endif
#endif   // __JUCE_WEBBROWSERCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_WebBrowserComponent.h *********/

#endif
#ifndef __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_QuickTimeMovieComponent.h *********/
#ifndef __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__
#define __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__

// this is used to disable QuickTime, and is defined in juce_Config.h
#if JUCE_QUICKTIME || DOXYGEN

#if JUCE_WIN32

  typedef ActiveXControlComponent QTCompBaseClass;
#else

  typedef NSViewComponent QTCompBaseClass;
#endif

/**
    A window that can play back a QuickTime movie.

*/
class JUCE_API  QuickTimeMovieComponent     : public QTCompBaseClass
{
public:

    /** Creates a QuickTimeMovieComponent, initially blank.

        Use the loadMovie() method to load a movie once you've added the
        component to a window, (or put it on the desktop as a heavyweight window).
        Loading a movie when the component isn't visible can cause problems, as
        QuickTime needs a window handle to initialise properly.
    */
    QuickTimeMovieComponent();

    /** Destructor. */
    ~QuickTimeMovieComponent();

    /** Returns true if QT is installed and working on this machine.
    */
    static bool isQuickTimeAvailable() throw();

    /** Tries to load a QuickTime movie into the player.

        It's best to call this function once you've added the component to a window,
        (or put it on the desktop as a heavyweight window). Loading a movie when the
        component isn't visible can cause problems, because QuickTime needs a window
        handle to do its stuff.

        @param movieFile    the .mov file to open
        @param isControllerVisible  whether to show a controller bar at the bottom
        @returns true if the movie opens successfully
    */
    bool loadMovie (const File& movieFile,
                    const bool isControllerVisible);

    bool loadMovie (InputStream* movieStream,
                    const bool isControllerVisible);

    /** Closes the movie, if one is open. */
    void closeMovie();

    /** Returns the movie file that is currently open.

        If there isn't one, this returns File::nonexistent
    */
    const File getCurrentMovieFile() const;

    /** Returns true if there's currently a movie open. */
    bool isMovieOpen() const;

    /** Returns the length of the movie, in seconds. */
    double getMovieDuration() const;

    /** Returns the movie's natural size, in pixels.

        You can use this to resize the component to show the movie at its preferred
        scale.

        If no movie is loaded, the size returned will be 0 x 0.
    */
    void getMovieNormalSize (int& width, int& height) const;

    /** This will position the component within a given area, keeping its aspect
        ratio correct according to the movie's normal size.

        The component will be made as large as it can go within the space, and will
        be aligned according to the justification value if this means there are gaps at
        the top or sides.
    */
    void setBoundsWithCorrectAspectRatio (const Rectangle& spaceToFitWithin,
                                          const RectanglePlacement& placement);

    /** Starts the movie playing. */
    void play();

    /** Stops the movie playing. */
    void stop();

    /** Returns true if the movie is currently playing. */
    bool isPlaying() const;

    /** Moves the movie's position back to the start. */
    void goToStart();

    /** Sets the movie's position to a given time. */
    void setPosition (const double seconds);

    /** Returns the current play position of the movie. */
    double getPosition() const;

    /** Changes the movie playback rate.

        A value of 1 is normal speed, greater values play it proportionately faster,
        smaller values play it slower.
    */
    void setSpeed (const float newSpeed);

    /** Changes the movie's playback volume.

        @param newVolume    the volume in the range 0 (silent) to 1.0 (full)
    */
    void setMovieVolume (const float newVolume);

    /** Returns the movie's playback volume.

        @returns the volume in the range 0 (silent) to 1.0 (full)
    */
    float getMovieVolume() const;

    /** Tells the movie whether it should loop. */
    void setLooping (const bool shouldLoop);

    /** Returns true if the movie is currently looping.

        @see setLooping
    */
    bool isLooping() const;

    /** True if the native QuickTime controller bar is shown in the window.

        @see loadMovie
    */
    bool isControllerVisible() const;

    /** @internal */
    void paint (Graphics& g);

    juce_UseDebuggingNewOperator

private:
    File movieFile;
    bool movieLoaded, controllerVisible, looping;

#if JUCE_WIN32
    /** @internal */
    void parentHierarchyChanged();
    /** @internal */
    void visibilityChanged();

    void createControlIfNeeded();
    bool isControlCreated() const;
    void* internal;
#else
    void* movie;
#endif

    QuickTimeMovieComponent (const QuickTimeMovieComponent&);
    const QuickTimeMovieComponent& operator= (const QuickTimeMovieComponent&);
};

#endif
#endif   // __JUCE_QUICKTIMEMOVIECOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_QuickTimeMovieComponent.h *********/

#endif
#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_SystemTrayIconComponent.h *********/
#ifndef __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__
#define __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__

#if JUCE_WIN32 || JUCE_LINUX

/**
    On Windows only, this component sits in the taskbar tray as a small icon.

    To use it, just create one of these components, but don't attempt to make it
    visible, add it to a parent, or put it on the desktop.

    You can then call setIconImage() to create an icon for it in the taskbar.

    To change the icon's tooltip, you can use setIconTooltip().

    To respond to mouse-events, you can override the normal mouseDown(),
    mouseUp(), mouseDoubleClick() and mouseMove() methods, and although the x, y
    position will not be valid, you can use this to respond to clicks. Traditionally
    you'd use a left-click to show your application's window, and a right-click
    to show a pop-up menu.
*/
class JUCE_API  SystemTrayIconComponent  : public Component
{
public:

    SystemTrayIconComponent();

    /** Destructor. */
    ~SystemTrayIconComponent();

    /** Changes the image shown in the taskbar.
    */
    void setIconImage (const Image& newImage);

    /** Changes the tooltip that Windows shows above the icon. */
    void setIconTooltip (const String& tooltip);

#if JUCE_LINUX
    /** @internal */
    void paint (Graphics& g);
#endif

    juce_UseDebuggingNewOperator

private:

    SystemTrayIconComponent (const SystemTrayIconComponent&);
    const SystemTrayIconComponent& operator= (const SystemTrayIconComponent&);
};

#endif
#endif   // __JUCE_SYSTEMTRAYICONCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_SystemTrayIconComponent.h *********/

#endif
#ifndef __JUCE_MIDIKEYBOARDCOMPONENT_JUCEHEADER__

/********* Start of inlined file: juce_MidiKeyboardComponent.h *********/
#ifndef __JUCE_MIDIKEYBOARDCOMPONENT_JUCEHEADER__
#define __JUCE_MIDIKEYBOARDCOMPONENT_JUCEHEADER__

/**
    A component that displays a piano keyboard, whose notes can be clicked on.

    This component will mimic a physical midi keyboard, showing the current state of
    a MidiKeyboardState object. When the on-screen keys are clicked on, it will play these
    notes by calling the noteOn() and noteOff() methods of its MidiKeyboardState object.

    Another feature is that the computer keyboard can also be used to play notes. By
    default it maps the top two rows of a standard querty keyboard to the notes, but
    these can be remapped if needed. It will only respond to keypresses when it has
    the keyboard focus, so to disable this feature you can call setWantsKeyboardFocus (false).

    The component is also a ChangeBroadcaster, so if you want to be informed when the
    keyboard is scrolled, you can register a ChangeListener for callbacks.

    @see MidiKeyboardState
*/
class JUCE_API  MidiKeyboardComponent  : public Component,
                                         public MidiKeyboardStateListener,
                                         public ChangeBroadcaster,
                                         private Timer,
                                         private AsyncUpdater
{
public:

    /** The direction of the keyboard.

        @see setOrientation
    */
    enum Orientation
    {
        horizontalKeyboard,
        verticalKeyboardFacingLeft,
        verticalKeyboardFacingRight,
    };

    /** Creates a MidiKeyboardComponent.

        @param state        the midi keyboard model that this component will represent
        @param orientation  whether the keyboard is horizonal or vertical
    */
    MidiKeyboardComponent (MidiKeyboardState& state,
                           const Orientation orientation);

    /** Destructor. */
    ~MidiKeyboardComponent();

    /** Changes the velocity used in midi note-on messages that are triggered by clicking
        on the component.

        Values are 0 to 1.0, where 1.0 is the heaviest.

        @see setMidiChannel
    */
    void setVelocity (const float velocity);

    /** Changes the midi channel number that will be used for events triggered by clicking
        on the component.

        The channel must be between 1 and 16 (inclusive). This is the channel that will be
        passed on to the MidiKeyboardState::noteOn() method when the user clicks the component.

        Although this is the channel used for outgoing events, the component can display
        incoming events from more than one channel - see setMidiChannelsToDisplay()

        @see setVelocity
    */
    void setMidiChannel (const int midiChannelNumber);

    /** Returns the midi channel that the keyboard is using for midi messages.

        @see setMidiChannel
    */
    int getMidiChannel() const throw()                              { return midiChannel; }

    /** Sets a mask to indicate which incoming midi channels should be represented by
        key movements.

        The mask is a set of bits, where bit 0 = midi channel 1, bit 1 = midi channel 2, etc.

        If the MidiKeyboardState has a key down for any of the channels whose bits are set
        in this mask, the on-screen keys will also go down.

        By default, this mask is set to 0xffff (all channels displayed).

        @see setMidiChannel
    */
    void setMidiChannelsToDisplay (const int midiChannelMask);

    /** Returns the current set of midi channels represented by the component.

        This is the value that was set with setMidiChannelsToDisplay().
    */
    int getMidiChannelsToDisplay() const throw()                    { return midiInChannelMask; }

    /** Changes the width used to draw the white keys. */
    void setKeyWidth (const float widthInPixels);

    /** Returns the width that was set by setKeyWidth(). */
    float getKeyWidth() const throw()                               { return keyWidth; }

    /** Changes the keyboard's current direction. */
    void setOrientation (const Orientation newOrientation);

    /** Returns the keyboard's current direction. */
    const Orientation getOrientation() const throw()                { return orientation; }

    /** Sets the range of midi notes that the keyboard will be limited to.

        By default the range is 0 to 127 (inclusive), but you can limit this if you
        only want a restricted set of the keys to be shown.

        Note that the values here are inclusive and must be between 0 and 127.
    */
    void setAvailableRange (const int lowestNote,
                            const int highestNote);

    /** Returns the first note in the available range.

        @see setAvailableRange
    */
    int getRangeStart() const throw()                               { return rangeStart; }

    /** Returns the last note in the available range.

        @see setAvailableRange
    */
    int getRangeEnd() const throw()                                 { return rangeEnd; }

    /** If the keyboard extends beyond the size of the component, this will scroll
        it to show the given key at the start.

        Whenever the keyboard's position is changed, this will use the ChangeBroadcaster
        base class to send a callback to any ChangeListeners that have been registered.
    */
    void setLowestVisibleKey (int noteNumber);

    /** Returns the number of the first key shown in the component.

        @see setLowestVisibleKey
    */
    int getLowestVisibleKey() const throw()                         { return firstKey; }

    /** Returns the length of the black notes.

        This will be their vertical or horizontal length, depending on the keyboard's orientation.
    */
    int getBlackNoteLength() const throw()                          { return blackNoteLength; }

    /** If set to true, then scroll buttons will appear at either end of the keyboard
        if there are too many notes to fit them all in the component at once.
    */
    void setScrollButtonsVisible (const bool canScroll);

    /** A set of colour IDs to use to change the colour of various aspects of the keyboard.

        These constants can be used either via the Component::setColour(), or LookAndFeel::setColour()
        methods.

        @see Component::setColour, Component::findColour, LookAndFeel::setColour, LookAndFeel::findColour
    */
    enum ColourIds
    {
        whiteNoteColourId               = 0x1005000,
        blackNoteColourId               = 0x1005001,
        keySeparatorLineColourId        = 0x1005002,
        mouseOverKeyOverlayColourId     = 0x1005003,  /**< This colour will be overlaid on the normal note colour. */
        keyDownOverlayColourId          = 0x1005004,  /**< This colour will be overlaid on the normal note colour. */
        textLabelColourId               = 0x1005005,
        upDownButtonBackgroundColourId  = 0x1005006,
        upDownButtonArrowColourId       = 0x1005007
    };

    /** Returns the position within the component of the left-hand edge of a key.

        Depending on the keyboard's orientation, this may be a horizontal or vertical
        distance, in either direction.
    */
    int getKeyStartPosition (const int midiNoteNumber) const;

    /** Deletes all key-mappings.

        @see setKeyPressForNote
    */
    void clearKeyMappings();

    /** Maps a key-press to a given note.

        @param key                  the key that should trigger the note
        @param midiNoteOffsetFromC  how many semitones above C the triggered note should
                                    be. The actual midi note that gets played will be
                                    this value + (12 * the current base octave). To change
                                    the base octave, see setKeyPressBaseOctave()
    */
    void setKeyPressForNote (const KeyPress& key,
                             const int midiNoteOffsetFromC);

    /** Removes any key-mappings for a given note.

        For a description of what the note number means, see setKeyPressForNote().
    */
    void removeKeyPressForNote (const int midiNoteOffsetFromC);

    /** Changes the base note above which key-press-triggered notes are played.

        The set of key-mappings that trigger notes can be moved up and down to cover
        the entire scale using this method.

        The value passed in is an octave number between 0 and 10 (inclusive), and
        indicates which C is the base note to which the key-mapped notes are
        relative.
    */
    void setKeyPressBaseOctave (const int newOctaveNumber);

    /** This sets the octave number which is shown as the octave number for middle C.

        This affects only the default implementation of getWhiteNoteText(), which
        passes this octave number to MidiMessage::getMidiNoteName() in order to
        get the note text. See MidiMessage::getMidiNoteName() for more info about
        the parameter.

        By default this value is set to 3.

        @see getOctaveForMiddleC
    */
    void setOctaveForMiddleC (const int octaveNumForMiddleC) throw();

    /** This returns the value set by setOctaveForMiddleC().
        @see setOctaveForMiddleC
    */
    int getOctaveForMiddleC() const throw()             { return octaveNumForMiddleC; }

    /** @internal */
    void paint (Graphics& g);
    /** @internal */
    void resized();
    /** @internal */
    void mouseMove (const MouseEvent& e);
    /** @internal */
    void mouseDrag (const MouseEvent& e);
    /** @internal */
    void mouseDown (const MouseEvent& e);
    /** @internal */
    void mouseUp (const MouseEvent& e);
    /** @internal */
    void mouseEnter (const MouseEvent& e);
    /** @internal */
    void mouseExit (const MouseEvent& e);
    /** @internal */
    void mouseWheelMove (const MouseEvent& e, float wheelIncrementX, float wheelIncrementY);
    /** @internal */
    void timerCallback();
    /** @internal */
    bool keyStateChanged (const bool isKeyDown);
    /** @internal */
    void focusLost (FocusChangeType cause);
    /** @internal */
    void handleNoteOn (MidiKeyboardState* source, int midiChannel, int midiNoteNumber, float velocity);
    /** @internal */
    void handleNoteOff (MidiKeyboardState* source, int midiChannel, int midiNoteNumber);
    /** @internal */
    void handleAsyncUpdate();
    /** @internal */
    void colourChanged();

    juce_UseDebuggingNewOperator

protected:
    friend class MidiKeyboardUpDownButton;

    /** Draws a white note in the given rectangle.

        isOver indicates whether the mouse is over the key, isDown indicates whether the key is
        currently pressed down.

        When doing this, be sure to note the keyboard's orientation.
    */
    virtual void drawWhiteNote (int midiNoteNumber,
                                Graphics& g,
                                int x, int y, int w, int h,
                                bool isDown, bool isOver,
                                const Colour& lineColour,
                                const Colour& textColour);

    /** Draws a black note in the given rectangle.

        isOver indicates whether the mouse is over the key, isDown indicates whether the key is
        currently pressed down.

        When doing this, be sure to note the keyboard's orientation.
    */
    virtual void drawBlackNote (int midiNoteNumber,
                                Graphics& g,
                                int x, int y, int w, int h,
                                bool isDown, bool isOver,
                                const Colour& noteFillColour);

    /** Allows text to be drawn on the white notes.

        By default this is used to label the C in each octave, but could be used for other things.

        @see setOctaveForMiddleC
    */
    virtual const String getWhiteNoteText (const int midiNoteNumber);

    /** Draws the up and down buttons that change the base note. */
    virtual void drawUpDownButton (Graphics& g, int w, int h,
                                   const bool isMouseOver,
                                   const bool isButtonPressed,
                                   const bool movesOctavesUp);

    /** Callback when the mouse is clicked on a key.

        You could use this to do things like handle right-clicks on keys, etc.

        Return true if you want the click to trigger the note, or false if you
        want to handle it yourself and not have the note played.

        @see mouseDraggedToKey
    */
    virtual bool mouseDownOnKey (int midiNoteNumber, const MouseEvent& e);

    /** Callback when the mouse is dragged from one key onto another.

        @see mouseDownOnKey
    */
    virtual void mouseDraggedToKey (int midiNoteNumber, const MouseEvent& e);

    /** Calculates the positon of a given midi-note.

        This can be overridden to create layouts with custom key-widths.

        @param midiNoteNumber   the note to find
        @param keyWidth         the desired width in pixels of one key - see setKeyWidth()
        @param x                the x position of the left-hand edge of the key (this method
                                always works in terms of a horizontal keyboard)
        @param w                the width of the key
    */
    virtual void getKeyPosition (int midiNoteNumber, float keyWidth,
                                 int& x, int& w) const;

private:

    MidiKeyboardState& state;
    int xOffset, blackNoteLength;
    float keyWidth;
    Orientation orientation;

    int midiChannel, midiInChannelMask;
    float velocity;
    int noteUnderMouse, mouseDownNote;
    BitArray keysPressed, keysCurrentlyDrawnDown;

    int rangeStart, rangeEnd, firstKey;
    bool canScroll, mouseDragging;
    Button* scrollDown;
    Button* scrollUp;

    Array <KeyPress> keyPresses;
    Array <int> keyPressNotes;
    int keyMappingOctave;
    int octaveNumForMiddleC;

    void getKeyPos (int midiNoteNumber, int& x, int& w) const;
    int xyToNote (int x, int y);
    int remappedXYToNote (int x, int y) const;
    void resetAnyKeysInUse();
    void updateNoteUnderMouse (int x, int y);
    void repaintNote (const int midiNoteNumber);

    MidiKeyboardComponent (const MidiKeyboardComponent&);
    const MidiKeyboardComponent& operator= (const MidiKeyboardComponent&);
};

#endif   // __JUCE_MIDIKEYBOARDCOMPONENT_JUCEHEADER__
/********* End of inlined file: juce_MidiKeyboardComponent.h *********/

#endif
#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__

/********* Start of inlined file: juce_LookAndFeel.h *********/
#ifndef __JUCE_LOOKANDFEEL_JUCEHEADER__
#define __JUCE_LOOKANDFEEL_JUCEHEADER__

class ToggleButton;
class TextButton;
class AlertWindow;
class TextLayout;
class ScrollBar;
class BubbleComponent;
class ComboBox;
class Button;
class FilenameComponent;
class DocumentWindow;
class ResizableWindow;
class GroupComponent;
class MenuBarComponent;
class DropShadower;
class GlyphArrangement;
class PropertyComponent;
class TableHeaderComponent;
class Toolbar;
class ToolbarItemComponent;
class PopupMenu;
class ProgressBar;
class FileBrowserComponent;
class DirectoryContentsDisplayComponent;
class FilePreviewComponent;
class ImageButton;

/**
    LookAndFeel objects define the appearance of all the JUCE widgets, and subclasses
    can be used to apply different 'skins' to the application.

*/
class JUCE_API  LookAndFeel
{
public:

    /** Creates the default JUCE look and feel. */
    LookAndFeel();

    /** Destructor. */
    virtual ~LookAndFeel();

    /** Returns the current default look-and-feel for a component to use when it
        hasn't got one explicitly set.

        @see setDefaultLookAndFeel
    */
    static LookAndFeel& getDefaultLookAndFeel() throw();

    /** Changes the default look-and-feel.

        @param newDefaultLookAndFeel    the new look-and-feel object to use - if this is
                                        set to 0, it will revert to using the default one. The
                                        object passed-in must be deleted by the caller when
                                        it's no longer needed.
        @see getDefaultLookAndFeel
    */
    static void setDefaultLookAndFeel (LookAndFeel* newDefaultLookAndFeel) throw();

    /** Looks for a colour that has been registered with the given colour ID number.

        If a colour has been set for this ID number using setColour(), then it is
        returned. If none has been set, it will just return Colours::black.

        The colour IDs for various purposes are stored as enums in the components that
        they are relevent to - for an example, see Slider::ColourIds,
        Label::ColourIds, TextEditor::ColourIds, TreeView::ColourIds, etc.

        If you're looking up a colour for use in drawing a component, it's usually
        best not to call this directly, but to use the Component::findColour() method
        instead. That will first check whether a suitable colour has been registered
        directly with the component, and will fall-back on calling the component's
        LookAndFeel's findColour() method if none is found.

        @see setColour, Component::findColour, Component::setColour
    */
    const Colour findColour (const int colourId) const throw();

    /** Registers a colour to be used for a particular purpose.

        For more details, see the comments for findColour().

        @see findColour, Component::findColour, Component::setColour
    */
    void setColour (const int colourId, const Colour& colour) throw();

    /** Returns true if the specified colour ID has been explicitly set using the
        setColour() method.
    */
    bool isColourSpecified (const int colourId) const throw();

    virtual const Typeface::Ptr getTypefaceForFont (const Font& font);

    /** Allows you to change the default sans-serif font.

        If you need to supply your own Typeface object for any of the default fonts, rather
        than just supplying the name (e.g. if you want to use an embedded font), then
        you should instead override getTypefaceForFont() to create and return the typeface.
    */
    void setDefaultSansSerifTypefaceName (const String& newName);

    /** Draws the lozenge-shaped background for a standard button. */
    virtual void drawButtonBackground (Graphics& g,
                                       Button& button,
                                       const Colour& backgroundColour,
                                       bool isMouseOverButton,
                                       bool isButtonDown);

    virtual const Font getFontForTextButton (TextButton& button);

    /** Draws the text for a TextButton. */
    virtual void drawButtonText (Graphics& g,
                                 TextButton& button,
                                 bool isMouseOverButton,
                                 bool isButtonDown);

    /** Draws the contents of a standard ToggleButton. */
    virtual void drawToggleButton (Graphics& g,
                                   ToggleButton& button,
                                   bool isMouseOverButton,
                                   bool isButtonDown);

    virtual void changeToggleButtonWidthToFitText (ToggleButton& button);

    virtual void drawTickBox (Graphics& g,
                              Component& component,
                              int x, int y, int w, int h,
                              const bool ticked,
                              const bool isEnabled,
                              const bool isMouseOverButton,
                              const bool isButtonDown);

    /* AlertWindow handling..
    */
    virtual AlertWindow* createAlertWindow (const String& title,
                                            const String& message,
                                            const String& button1,
                                            const String& button2,
                                            const String& button3,
                                            AlertWindow::AlertIconType iconType,
                                            int numButtons,
                                            Component* associatedComponent);

    virtual void drawAlertBox (Graphics& g,
                               AlertWindow& alert,
                               const Rectangle& textArea,
                               TextLayout& textLayout);

    virtual int getAlertBoxWindowFlags();

    virtual int getAlertWindowButtonHeight();

    virtual const Font getAlertWindowFont();

    /** Draws a progress bar.

        If the progress value is less than 0 or greater than 1.0, this should draw a spinning
        bar that fills the whole space (i.e. to say that the app is still busy but the progress
        isn't known). It can use the current time as a basis for playing an animation.

        (Used by progress bars in AlertWindow).
    */
    virtual void drawProgressBar (Graphics& g, ProgressBar& progressBar,
                                  int width, int height,
                                  double progress, const String& textToShow);

    // Draws a small image that spins to indicate that something's happening..
    // This method should use the current time to animate itself, so just keep
    // repainting it every so often.
    virtual void drawSpinningWaitAnimation (Graphics& g, int x, int y, int w, int h);

    /** Draws one of the buttons on a scrollbar.

        @param g                    the context to draw into
        @param scrollbar            the bar itself
        @param width                the width of the button
        @param height               the height of the button
        @param buttonDirection      the direction of the button, where 0 = up, 1 = right, 2 = down, 3 = left
        @param isScrollbarVertical  true if it's a vertical bar, false if horizontal
        @param isMouseOverButton    whether the mouse is currently over the button (also true if it's held down)
        @param isButtonDown         whether the mouse button's held down
    */
    virtual void drawScrollbarButton (Graphics& g,
                                      ScrollBar& scrollbar,
                                      int width, int height,
                                      int buttonDirection,
                                      bool isScrollbarVertical,
                                      bool isMouseOverButton,
                                      bool isButtonDown);

    /** Draws the thumb area of a scrollbar.

        @param g                    the context to draw into
        @param scrollbar            the bar itself
        @param x                    the x position of the left edge of the thumb area to draw in
        @param y                    the y position of the top edge of the thumb area to draw in
        @param width                the width of the thumb area to draw in
        @param height               the height of the thumb area to draw in
        @param isScrollbarVertical  true if it's a vertical bar, false if horizontal
        @param thumbStartPosition   for vertical bars, the y co-ordinate of the top of the
                                    thumb, or its x position for horizontal bars
        @param thumbSize            for vertical bars, the height of the thumb, or its width for
                                    horizontal bars. This may be 0 if the thumb shouldn't be drawn.
        @param isMouseOver          whether the mouse is over the thumb area, also true if the mouse is
                                    currently dragging the thumb
        @param isMouseDown          whether the mouse is currently dragging the scrollbar
    */
    virtual void drawScrollbar (Graphics& g,
                                ScrollBar& scrollbar,
                                int x, int y,
                                int width, int height,
                                bool isScrollbarVertical,
                                int thumbStartPosition,
                                int thumbSize,
                                bool isMouseOver,
                                bool isMouseDown);

    /** Returns the component effect to use for a scrollbar */
    virtual ImageEffectFilter* getScrollbarEffect();

    /** Returns the minimum length in pixels to use for a scrollbar thumb. */
    virtual int getMinimumScrollbarThumbSize (ScrollBar& scrollbar);

    /** Returns the default thickness to use for a scrollbar. */
    virtual int getDefaultScrollbarWidth();

    /** Returns the length in pixels to use for a scrollbar button. */
    virtual int getScrollbarButtonSize (ScrollBar& scrollbar);

    /** Returns a tick shape for use in yes/no boxes, etc. */
    virtual const Path getTickShape (const float height);
    /** Returns a cross shape for use in yes/no boxes, etc. */
    virtual const Path getCrossShape (const float height);

    /** Draws the + or - box in a treeview. */
    virtual void drawTreeviewPlusMinusBox (Graphics& g, int x, int y, int w, int h, bool isPlus, bool isMouseOver);

    virtual void fillTextEditorBackground (Graphics& g, int width, int height, TextEditor& textEditor);
    virtual void drawTextEditorOutline (Graphics& g, int width, int height, TextEditor& textEditor);

    // these return an image from the ImageCache, so use ImageCache::release() to free it
    virtual Image* getDefaultFolderImage();
    virtual Image* getDefaultDocumentFileImage();

    virtual void createFileChooserHeaderText (const String& title,
                                              const String& instructions,
                                              GlyphArrangement& destArrangement,
                                              int width);

    virtual void drawFileBrowserRow (Graphics& g, int width, int height,
                                     const String& filename, Image* icon,
                                     const String& fileSizeDescription,
                                     const String& fileTimeDescription,
                                     const bool isDirectory,
                                     const bool isItemSelected,
                                     const int itemIndex);

    virtual Button* createFileBrowserGoUpButton();

    virtual void layoutFileBrowserComponent (FileBrowserComponent& browserComp,
                                             DirectoryContentsDisplayComponent* fileListComponent,
                                             FilePreviewComponent* previewComp,
                                             ComboBox* currentPathBox,
                                             TextEditor* filenameBox,
                                             Button* goUpButton);

    virtual void drawBubble (Graphics& g,
                             float tipX, float tipY,
                             float boxX, float boxY, float boxW, float boxH);

    /** Fills the background of a popup menu component. */
    virtual void drawPopupMenuBackground (Graphics& g, int width, int height);

    /** Draws one of the items in a popup menu. */
    virtual void drawPopupMenuItem (Graphics& g,
                                    int width, int height,
                                    const bool isSeparator,
                                    const bool isActive,
                                    const bool isHighlighted,
                                    const bool isTicked,
                                    const bool hasSubMenu,
                                    const String& text,
                                    const String& shortcutKeyText,
                                    Image* image,
                                    const Colour* const textColour);

    /** Returns the size and style of font to use in popup menus. */
    virtual const Font getPopupMenuFont();

    virtual void drawPopupMenuUpDownArrow (Graphics& g,
                                           int width, int height,
                                           bool isScrollUpArrow);

    /** Finds the best size for an item in a popup menu. */
    virtual void getIdealPopupMenuItemSize (const String& text,
                                            const bool isSeparator,
                                            int standardMenuItemHeight,
                                            int& idealWidth,
                                            int& idealHeight);

    virtual int getMenuWindowFlags();

    virtual void drawMenuBarBackground (Graphics& g, int width, int height,
                                        bool isMouseOverBar,
                                        MenuBarComponent& menuBar);

    virtual int getMenuBarItemWidth (MenuBarComponent& menuBar, int itemIndex, const String& itemText);

    virtual const Font getMenuBarFont (MenuBarComponent& menuBar, int itemIndex, const String& itemText);

    virtual void drawMenuBarItem (Graphics& g,
                                  int width, int height,
                                  int itemIndex,
                                  const String& itemText,
                                  bool isMouseOverItem,
                                  bool isMenuOpen,
                                  bool isMouseOverBar,
                                  MenuBarComponent& menuBar);

    virtual void drawComboBox (Graphics& g, int width, int height,
                               const bool isButtonDown,
                               int buttonX, int buttonY,
                               int buttonW, int buttonH,
                               ComboBox& box);

    virtual const Font getComboBoxFont (ComboBox& box);

    virtual Label* createComboBoxTextBox (ComboBox& box);

    virtual void positionComboBoxText (ComboBox& box, Label& labelToPosition);

    virtual void drawLabel (Graphics& g, Label& label);

    virtual void drawLinearSlider (Graphics& g,
                                   int x, int y,
                                   int width, int height,
                                   float sliderPos,
                                   float minSliderPos,
                                   float maxSliderPos,
                                   const Slider::SliderStyle style,
                                   Slider& slider);

    virtual void drawLinearSliderBackground (Graphics& g,
                                             int x, int y,
                                             int width, int height,
                                             float sliderPos,
                                             float minSliderPos,
                                             float maxSliderPos,
                                             const Slider::SliderStyle style,
                                             Slider& slider);

    virtual void drawLinearSliderThumb (Graphics& g,
                                        int x, int y,
                                        int width, int height,
                                        float sliderPos,
                                        float minSliderPos,
                                        float maxSliderPos,
                                        const Slider::SliderStyle style,
                                        Slider& slider);

    virtual int getSliderThumbRadius (Slider& slider);

    virtual void drawRotarySlider (Graphics& g,
                                   int x, int y,
                                   int width, int height,
                                   float sliderPosProportional,
                                   const float rotaryStartAngle,
                                   const float rotaryEndAngle,
                                   Slider& slider);

    virtual Button* createSliderButton (const bool isIncrement);
    virtual Label* createSliderTextBox (Slider& slider);

    virtual ImageEffectFilter* getSliderEffect();

    virtual void getTooltipSize (const String& tipText, int& width, int& height);

    virtual void drawTooltip (Graphics& g, const String& text, int width, int height);

    virtual Button* createFilenameComponentBrowseButton (const String& text);

    virtual void layoutFilenameComponent (FilenameComponent& filenameComp,
                                          ComboBox* filenameBox, Button* browseButton);

    virtual void drawCornerResizer (Graphics& g,
                                    int w, int h,
                                    bool isMouseOver,
                                    bool isMouseDragging);

    virtual void drawResizableFrame (Graphics& g,
                                    int w, int h,
                                    const BorderSize& borders);

    virtual void fillResizableWindowBackground (Graphics& g, int w, int h,
                                                const BorderSize& border,
                                                ResizableWindow& window);

    virtual void drawResizableWindowBorder (Graphics& g,
                                            int w, int h,
                                            const BorderSize& border,
                                            ResizableWindow& window);

    virtual void drawDocumentWindowTitleBar (DocumentWindow& window,
                                             Graphics& g, int w, int h,
                                             int titleSpaceX, int titleSpaceW,
                                             const Image* icon,
                                             bool drawTitleTextOnLeft);

    virtual Button* createDocumentWindowButton (int buttonType);

    virtual void positionDocumentWindowButtons (DocumentWindow& window,
                                                int titleBarX, int titleBarY,
                                                int titleBarW, int titleBarH,
                                                Button* minimiseButton,
                                                Button* maximiseButton,
                                                Button* closeButton,
                                                bool positionTitleBarButtonsOnLeft);

    virtual int getDefaultMenuBarHeight();

    virtual DropShadower* createDropShadowerForComponent (Component* component);

    virtual void drawStretchableLayoutResizerBar (Graphics& g,
                                                  int w, int h,
                                                  bool isVerticalBar,
                                                  bool isMouseOver,
                                                  bool isMouseDragging);

    virtual void drawGroupComponentOutline (Graphics& g, int w, int h,
                                            const String& text,
                                            const Justification& position,
                                            GroupComponent& group);

    virtual void createTabButtonShape (Path& p,
                                       int width, int height,
                                       int tabIndex,
                                       const String& text,
                                       Button& button,
                                       TabbedButtonBar::Orientation orientation,
                                       const bool isMouseOver,
                                       const bool isMouseDown,
                                       const bool isFrontTab);

    virtual void fillTabButtonShape (Graphics& g,
                                     const Path& path,
                                     const Colour& preferredBackgroundColour,
                                     int tabIndex,
                                     const String& text,
                                     Button& button,
                                     TabbedButtonBar::Orientation orientation,
                                     const bool isMouseOver,
                                     const bool isMouseDown,
                                     const bool isFrontTab);

    virtual void drawTabButtonText (Graphics& g,
                                    int x, int y, int w, int h,
                                    const Colour& preferredBackgroundColour,
                                    int tabIndex,
                                    const String& text,
                                    Button& button,
                                    TabbedButtonBar::Orientation orientation,
                                    const bool isMouseOver,
                                    const bool isMouseDown,
                                    const bool isFrontTab);

    virtual int getTabButtonOverlap (int tabDepth);
    virtual int getTabButtonSpaceAroundImage();

    virtual int getTabButtonBestWidth (int tabIndex,
                                       const String& text,
                                       int tabDepth,
                                       Button& button);

    virtual void drawTabButton (Graphics& g,
                                int w, int h,
                                const Colour& preferredColour,
                                int tabIndex,
                                const String& text,
                                Button& button,
                                TabbedButtonBar::Orientation orientation,
                                const bool isMouseOver,
                                const bool isMouseDown,
                                const bool isFrontTab);

    virtual void drawTabAreaBehindFrontButton (Graphics& g,
                                               int w, int h,
                                               TabbedButtonBar& tabBar,
                                               TabbedButtonBar::Orientation orientation);

    virtual Button* createTabBarExtrasButton();

    virtual void drawImageButton (Graphics& g, Image* image,
                                  int imageX, int imageY, int imageW, int imageH,
                                  const Colour& overlayColour,
                                  float imageOpacity,
                                  ImageButton& button);

    virtual void drawTableHeaderBackground (Graphics& g, TableHeaderComponent& header);

    virtual void drawTableHeaderColumn (Graphics& g, const String& columnName, int columnId,
                                        int width, int height,
                                        bool isMouseOver, bool isMouseDown,
                                        int columnFlags);

    virtual void paintToolbarBackground (Graphics& g, int width, int height, Toolbar& toolbar);

    virtual Button* createToolbarMissingItemsButton (Toolbar& toolbar);

    virtual void paintToolbarButtonBackground (Graphics& g, int width, int height,
                                               bool isMouseOver, bool isMouseDown,
                                               ToolbarItemComponent& component);

    virtual void paintToolbarButtonLabel (Graphics& g, int x, int y, int width, int height,
                                          const String& text, ToolbarItemComponent& component);

    virtual void drawPropertyPanelSectionHeader (Graphics& g, const String& name,
                                                 bool isOpen, int width, int height);

    virtual void drawPropertyComponentBackground (Graphics& g, int width, int height,
                                                  PropertyComponent& component);

    virtual void drawPropertyComponentLabel (Graphics& g, int width, int height,
                                             PropertyComponent& component);

    virtual const Rectangle getPropertyComponentContentPosition (PropertyComponent& component);

    virtual void drawLevelMeter (Graphics& g, int width, int height, float level);

    /**
    */
    virtual void playAlertSound();

    /** Utility function to draw a shiny, glassy circle (for round LED-type buttons). */
    static void drawGlassSphere (Graphics& g,
                                 const float x, const float y,
                                 const float diameter,
                                 const Colour& colour,
                                 const float outlineThickness) throw();

    static void drawGlassPointer (Graphics& g,
                                  const float x, const float y,
                                  const float diameter,
                                  const Colour& colour, const float outlineThickness,
                                  const int direction) throw();

    /** Utility function to draw a shiny, glassy oblong (for text buttons). */
    static void drawGlassLozenge (Graphics& g,
                                  const float x, const float y,
                                  const float width, const float height,
                                  const Colour& colour,
                                  const float outlineThickness,
                                  const float cornerSize,
                                  const bool flatOnLeft, const bool flatOnRight,
                                  const bool flatOnTop, const bool flatOnBottom) throw();

    juce_UseDebuggingNewOperator

protected:
    // xxx the following methods are only here to cause a compiler error, because they've been
    // deprecated or their parameters have changed. Hopefully these definitions should cause an
    // error if you try to build a subclass with the old versions.
    virtual int drawTickBox (Graphics&, int, int, int, int, bool, const bool, const bool, const bool) { return 0; }
    virtual int drawProgressBar (Graphics&, int, int, int, int, float) { return 0; }
    virtual int drawProgressBar (Graphics&, ProgressBar&, int, int, int, int, float) { return 0; }
    virtual void getTabButtonBestWidth (int, const String&, int) {}
    virtual int drawTreeviewPlusMinusBox (Graphics&, int, int, int, int, bool) { return 0; }

private:
    friend void JUCE_PUBLIC_FUNCTION shutdownJuce_GUI();
    static void clearDefaultLookAndFeel() throw(); // called at shutdown

    Array <int> colourIds;
    Array <Colour> colours;

    // default typeface names
    String defaultSans, defaultSerif, defaultFixed;

    void drawShinyButtonShape (Graphics& g,
                               float x, float y, float w, float h, float maxCornerSize,
                               const Colour& baseColour,
                               const float strokeWidth,
                               const bool flatOnLeft,
                               const bool flatOnRight,
                               const bool flatOnTop,
                               const bool flatOnBottom) throw();

    LookAndFeel (const LookAndFeel&);
    const LookAndFeel& operator= (const LookAndFeel&);
};

#endif   // __JUCE_LOOKANDFEEL_JUCEHEADER__
/********* End of inlined file: juce_LookAndFeel.h *********/

#endif
#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__

/********* Start of inlined file: juce_OldSchoolLookAndFeel.h *********/
#ifndef __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__
#define __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__

/**
    The original Juce look-and-feel.

*/
class JUCE_API  OldSchoolLookAndFeel    : public LookAndFeel
{
public:

    /** Creates the default JUCE look and feel. */
    OldSchoolLookAndFeel();

    /** Destructor. */
    virtual ~OldSchoolLookAndFeel();

    /** Draws the lozenge-shaped background for a standard button. */
    virtual void drawButtonBackground (Graphics& g,
                                       Button& button,
                                       const Colour& backgroundColour,
                                       bool isMouseOverButton,
                                       bool isButtonDown);

    /** Draws the contents of a standard ToggleButton. */
    virtual void drawToggleButton (Graphics& g,
                                   ToggleButton& button,
                                   bool isMouseOverButton,
                                   bool isButtonDown);

    virtual void drawTickBox (Graphics& g,
                              Component& component,
                              int x, int y, int w, int h,
                              const bool ticked,
                              const bool isEnabled,
                              const bool isMouseOverButton,
                              const bool isButtonDown);

    virtual void drawProgressBar (Graphics& g, ProgressBar& progressBar,
                                  int width, int height,
                                  double progress, const String& textToShow);

    virtual void drawScrollbarButton (Graphics& g,
                                      ScrollBar& scrollbar,
                                      int width, int height,
                                      int buttonDirection,
                                      bool isScrollbarVertical,
                                      bool isMouseOverButton,
                                      bool isButtonDown);

    virtual void drawScrollbar (Graphics& g,
                                ScrollBar& scrollbar,
                                int x, int y,
                                int width, int height,
                                bool isScrollbarVertical,
                                int thumbStartPosition,
                                int thumbSize,
                                bool isMouseOver,
                                bool isMouseDown);

    virtual ImageEffectFilter* getScrollbarEffect();

    virtual void drawTextEditorOutline (Graphics& g,
                                        int width, int height,
                                        TextEditor& textEditor);

    /** Fills the background of a popup menu component. */
    virtual void drawPopupMenuBackground (Graphics& g, int width, int height);

    virtual void drawMenuBarBackground (Graphics& g, int width, int height,
                                        bool isMouseOverBar,
                                        MenuBarComponent& menuBar);

    virtual void drawComboBox (Graphics& g, int width, int height,
                               const bool isButtonDown,
                               int buttonX, int buttonY,
                               int buttonW, int buttonH,
                               ComboBox& box);

    virtual const Font getComboBoxFont (ComboBox& box);

    virtual void drawLinearSlider (Graphics& g,
                                   int x, int y,
                                   int width, int height,
                                   float sliderPos,
                                   float minSliderPos,
                                   float maxSliderPos,
                                   const Slider::SliderStyle style,
                                   Slider& slider);

    virtual int getSliderThumbRadius (Slider& slider);

    virtual Button* createSliderButton (const bool isIncrement);

    virtual ImageEffectFilter* getSliderEffect();

    virtual void drawCornerResizer (Graphics& g,
                                    int w, int h,
                                    bool isMouseOver,
                                    bool isMouseDragging);

    virtual Button* createDocumentWindowButton (int buttonType);

    virtual void positionDocumentWindowButtons (DocumentWindow& window,
                                                int titleBarX, int titleBarY,
                                                int titleBarW, int titleBarH,
                                                Button* minimiseButton,
                                                Button* maximiseButton,
                                                Button* closeButton,
                                                bool positionTitleBarButtonsOnLeft);

    juce_UseDebuggingNewOperator

private:
    DropShadowEffect scrollbarShadow;

    OldSchoolLookAndFeel (const OldSchoolLookAndFeel&);
    const OldSchoolLookAndFeel& operator= (const OldSchoolLookAndFeel&);
};

#endif   // __JUCE_OLDSCHOOLLOOKANDFEEL_JUCEHEADER__
/********* End of inlined file: juce_OldSchoolLookAndFeel.h *********/

#endif
#ifndef __JUCE_FILEBASEDDOCUMENT_JUCEHEADER__

/********* Start of inlined file: juce_FileBasedDocument.h *********/
#ifndef __JUCE_FILEBASEDDOCUMENT_JUCEHEADER__
#define __JUCE_FILEBASEDDOCUMENT_JUCEHEADER__

/**
    A class to take care of the logic involved with the loading/saving of some kind
    of document.

    There's quite a lot of tedious logic involved in writing all the load/save/save-as
    functions you need for documents that get saved to a file, so this class attempts
    to abstract most of the boring stuff.

    Your subclass should just implement all the pure virtual methods, and you can
    then use the higher-level public methods to do the load/save dialogs, to warn the user
    about overwriting files, etc.

    The document object keeps track of whether it has changed since it was last saved or
    loaded, so when you change something, call its changed() method. This will set a
    flag so it knows it needs saving, and will also broadcast a change message using the
    ChangeBroadcaster base class.

    @see ChangeBroadcaster
*/
class JUCE_API FileBasedDocument  : public ChangeBroadcaster
{
public:
    /** Creates a FileBasedDocument.

        @param fileExtension            the extension to use when loading/saving files, e.g. ".doc"
        @param fileWildCard             the wildcard to use in file dialogs, e.g. "*.doc"
        @param openFileDialogTitle      the title to show on an open-file dialog, e.g. "Choose a file to open.."
        @param saveFileDialogTitle      the title to show on an save-file dialog, e.g. "Choose a file to save as.."
    */
    FileBasedDocument (const String& fileExtension,
                       const String& fileWildCard,
                       const String& openFileDialogTitle,
                       const String& saveFileDialogTitle);

    /** Destructor. */
    virtual ~FileBasedDocument();

    /** Returns true if the changed() method has been called since the file was
        last saved or loaded.

        @see resetChangedFlag, changed
    */
    bool hasChangedSinceSaved() const throw()                   { return changedSinceSave; }

    /** Called to indicate that the document has changed and needs saving.

        This method will also trigger a change message to be sent out using the
        ChangeBroadcaster base class.

        After calling the method, the hasChangedSinceSaved() method will return true, until
        it is reset either by saving to a file or using the resetChangedFlag() method.

        @see hasChangedSinceSaved, resetChangedFlag
    */
    virtual void changed();

    /** Sets the state of the 'changed' flag.

        The 'changed' flag is set to true when the changed() method is called - use this method
        to reset it or to set it without also broadcasting a change message.

        @see changed, hasChangedSinceSaved
    */
    void setChangedFlag (const bool hasChanged);

    /** Tries to open a file.

        If the file opens correctly, the document's file (see the getFile() method) is set
        to this new one; if it fails, the document's file is left unchanged, and optionally
        a message box is shown telling the user there was an error.

        @returns true if the new file loaded successfully
        @see loadDocument, loadFromUserSpecifiedFile
    */
    bool loadFrom (const File& fileToLoadFrom,
                   const bool showMessageOnFailure);

    /** Asks the user for a file and tries to load it.

        This will pop up a dialog box using the title, file extension and
        wildcard specified in the document's constructor, and asks the user
        for a file. If they pick one, the loadFrom() method is used to
        try to load it, optionally showing a message if it fails.

        @returns    true if a file was loaded; false if the user cancelled or if they
                    picked a file which failed to load correctly
        @see loadFrom
    */
    bool loadFromUserSpecifiedFile (const bool showMessageOnFailure);

    /** A set of possible outcomes of one of the save() methods
    */
    enum SaveResult
    {
        savedOk = 0,            /**< indicates that a file was saved successfully. */
        userCancelledSave,      /**< indicates that the user aborted the save operation. */
        failedToWriteToFile     /**< indicates that it tried to write to a file but this failed. */
    };

    /** Tries to save the document to the last file it was saved or loaded from.

        This will always try to write to the file, even if the document isn't flagged as
        having changed.

        @param askUserForFileIfNotSpecified     if there's no file currently specified and this is
                                                true, it will prompt the user to pick a file, as if
                                                saveAsInteractive() was called.
        @param showMessageOnFailure             if true it will show a warning message when if the
                                                save operation fails
        @see saveIfNeededAndUserAgrees, saveAs, saveAsInteractive
    */
    SaveResult save (const bool askUserForFileIfNotSpecified,
                     const bool showMessageOnFailure);

    /** If the file needs saving, it'll ask the user if that's what they want to do, and save
        it if they say yes.

        If you've got a document open and want to close it (e.g. to quit the app), this is the
        method to call.

        If the document doesn't need saving it'll return the value savedOk so
        you can go ahead and delete the document.

        If it does need saving it'll prompt the user, and if they say "discard changes" it'll
        return savedOk, so again, you can safely delete the document.

        If the user clicks "cancel", it'll return userCancelledSave, so if you can abort the
        close-document operation.

        And if they click "save changes", it'll try to save and either return savedOk, or
        failedToWriteToFile if there was a problem.

        @see save, saveAs, saveAsInteractive
    */
    SaveResult saveIfNeededAndUserAgrees();

    /** Tries to save the document to a specified file.

        If this succeeds, it'll also change the document's internal file (as returned by
        the getFile() method). If it fails, the file will be left unchanged.

        @param newFile                      the file to try to write to
        @param warnAboutOverwritingExistingFiles    if true and the file exists, it'll ask
                                            the user first if they want to overwrite it
        @param askUserForFileIfNotSpecified if the file is non-existent and this is true, it'll
                                            use the saveAsInteractive() method to ask the user for a
                                            filename
        @param showMessageOnFailure         if true and the write operation fails, it'll show
                                            a message box to warn the user
        @see saveIfNeededAndUserAgrees, save, saveAsInteractive
    */
    SaveResult saveAs (const File& newFile,
                       const bool warnAboutOverwritingExistingFiles,
                       const bool askUserForFileIfNotSpecified,
                       const bool showMessageOnFailure);

    /** Prompts the user for a filename and tries to save to it.

        This will pop up a dialog box using the title, file extension and
        wildcard specified in the document's constructor, and asks the user
        for a file. If they pick one, the saveAs() method is used to try to save
        to this file.

        @param warnAboutOverwritingExistingFiles    if true and the file exists, it'll ask
                                            the user first if they want to overwrite it
        @see saveIfNeededAndUserAgrees, save, saveAs
    */
    SaveResult saveAsInteractive (const bool warnAboutOverwritingExistingFiles);

    /** Returns the file that this document was last successfully saved or loaded from.

        When the document object is created, this will be set to File::nonexistent.

        It is changed when one of the load or save methods is used, or when setFile()
        is used to explicitly set it.
    */
    const File getFile() const throw()                      { return documentFile; }

    /** Sets the file that this document thinks it was loaded from.

        This won't actually load anything - it just changes the file stored internally.

        @see getFile
    */
    void setFile (const File& newFile);

protected:

    /** Overload this to return the title of the document.

        This is used in message boxes, filenames and file choosers, so it should be
        something sensible.
    */
    virtual const String getDocumentTitle() = 0;

    /** This method should try to load your document from the given file.

        If it fails, it should return an error message. If it succeeds, it should return
        an empty string.
    */
    virtual const String loadDocument (const File& file) = 0;

    /** This method should try to write your document to the given file.

        If it fails, it should return an error message. If it succeeds, it should return
        an empty string.
    */
    virtual const String saveDocument (const File& file) = 0;

    /** This is used for dialog boxes to make them open at the last folder you
        were using.

        getLastDocumentOpened() and setLastDocumentOpened() are used to store
        the last document that was used - you might want to store this value
        in a static variable, or even in your application's properties. It should
        be a global setting rather than a property of this object.

        This method works very well in conjunction with a RecentlyOpenedFilesList
        object to manage your recent-files list.

        As a default value, it's ok to return File::nonexistent, and the document
        object will use a sensible one instead.

        @see RecentlyOpenedFilesList
    */
    virtual const File getLastDocumentOpened() = 0;

    /** This is used for dialog boxes to make them open at the last folder you
        were using.

        getLastDocumentOpened() and setLastDocumentOpened() are used to store
        the last document that was used - you might want to store this value
        in a static variable, or even in your application's properties. It should
        be a global setting rather than a property of this object.

        This method works very well in conjunction with a RecentlyOpenedFilesList
        object to manage your recent-files list.

        @see RecentlyOpenedFilesList
    */
    virtual void setLastDocumentOpened (const File& file) = 0;

public:

    juce_UseDebuggingNewOperator

private:

    File documentFile;
    bool changedSinceSave;
    String fileExtension, fileWildcard, openFileDialogTitle, saveFileDialogTitle;

    FileBasedDocument (const FileBasedDocument&);
    const FileBasedDocument& operator= (const FileBasedDocument&);
};

#endif   // __JUCE_FILEBASEDDOCUMENT_JUCEHEADER__
/********* End of inlined file: juce_FileBasedDocument.h *********/

#endif
#ifndef __JUCE_RECENTLYOPENEDFILESLIST_JUCEHEADER__

/********* Start of inlined file: juce_RecentlyOpenedFilesList.h *********/
#ifndef __JUCE_RECENTLYOPENEDFILESLIST_JUCEHEADER__
#define __JUCE_RECENTLYOPENEDFILESLIST_JUCEHEADER__

/**
    Manages a set of files for use as a list of recently-opened documents.

    This is a handy class for holding your list of recently-opened documents, with
    helpful methods for things like purging any non-existent files, automatically
    adding them to a menu, and making persistence easy.

    @see File, FileBasedDocument
*/
class JUCE_API  RecentlyOpenedFilesList
{
public:

    /** Creates an empty list.
    */
    RecentlyOpenedFilesList();

    /** Destructor. */
    ~RecentlyOpenedFilesList();

    /** Sets a limit for the number of files that will be stored in the list.

        When addFile() is called, then if there is no more space in the list, the
        least-recently added file will be dropped.

        @see getMaxNumberOfItems
    */
    void setMaxNumberOfItems (const int newMaxNumber);

    /** Returns the number of items that this list will store.
        @see setMaxNumberOfItems
    */
    int getMaxNumberOfItems() const throw()                             { return maxNumberOfItems; }

    /** Returns the number of files in the list.

        The most recently added file is always at index 0.
    */
    int getNumFiles() const;

    /** Returns one of the files in the list.

        The most recently added file is always at index 0.
    */
    const File getFile (const int index) const;

    /** Returns an array of all the absolute pathnames in the list.
    */
    const StringArray& getAllFilenames() const throw()                  { return files; }

    /** Clears all the files from the list. */
    void clear();

    /** Adds a file to the list.

        The file will be added at index 0. If this file is already in the list, it will
        be moved up to index 0, but a file can only appear once in the list.

        If the list already contains the maximum number of items that is permitted, the
        least-recently added file will be dropped from the end.
    */
    void addFile (const File& file);

    /** Checks each of the files in the list, removing any that don't exist.

        You might want to call this after reloading a list of files, or before putting them
        on a menu.
    */
    void removeNonExistentFiles();

    /** Adds entries to a menu, representing each of the files in the list.

        This is handy for creating an "open recent file..." menu in your app. The
        menu items are numbered consecutively starting with the baseItemId value,
        and can either be added as complete pathnames, or just the last part of the
        filename.

        If dontAddNonExistentFiles is true, then each file will be checked and only those
        that exist will be added.

        If filesToAvoid is non-zero, then it is considered to be a zero-terminated array of
        pointers to file objects. Any files that appear in this list will not be added to the
        menu - the reason for this is that you might have a number of files already open, so
        might not want these to be shown in the menu.

        It returns the number of items that were added.
    */
    int createPopupMenuItems (PopupMenu& menuToAddItemsTo,
                              const int baseItemId,
                              const bool showFullPaths,
                              const bool dontAddNonExistentFiles,
                              const File** filesToAvoid = 0);

    /** Returns a string that encapsulates all the files in the list.

        The string that is returned can later be passed into restoreFromString() in
        order to recreate the list. This is handy for persisting your list, e.g. in
        a PropertiesFile object.

        @see restoreFromString
    */
    const String toString() const;

    /** Restores the list from a previously stringified version of the list.

        Pass in a stringified version created with toString() in order to persist/restore
        your list.

        @see toString
    */
    void restoreFromString (const String& stringifiedVersion);

    juce_UseDebuggingNewOperator

private:

    StringArray files;
    int maxNumberOfItems;
};

#endif   // __JUCE_RECENTLYOPENEDFILESLIST_JUCEHEADER__
/********* End of inlined file: juce_RecentlyOpenedFilesList.h *********/

#endif
#ifndef __JUCE_SELECTEDITEMSET_JUCEHEADER__

#endif
#ifndef __JUCE_UNDOABLEACTION_JUCEHEADER__

#endif
#ifndef __JUCE_UNDOMANAGER_JUCEHEADER__

#endif

#endif
/********* End of inlined file: juce_app_includes.h *********/

#endif

#if JUCE_MSVC
  #pragma warning (pop)
  #pragma pack (pop)
#endif

#if JUCE_MAC
  #pragma align=reset
#endif

END_JUCE_NAMESPACE

#ifndef DONT_SET_USING_JUCE_NAMESPACE
#ifdef JUCE_NAMESPACE

  // this will obviously save a lot of typing, but can be disabled by
  // defining DONT_SET_USING_JUCE_NAMESPACE, in case there are conflicts.
  using namespace JUCE_NAMESPACE;

  /* On the Mac, these symbols are defined in the Mac libraries, so
     these macros make it easier to reference them without writing out
     the namespace every time.

     If you run into difficulties where these macros interfere with the contents
     of 3rd party header files, you may need to use the juce_WithoutMacros.h file - see
     the comments in that file for more information.
  */
  #if JUCE_MAC && ! JUCE_DONT_DEFINE_MACROS
    #define Component       JUCE_NAMESPACE::Component
    #define MemoryBlock     JUCE_NAMESPACE::MemoryBlock
    #define Point           JUCE_NAMESPACE::Point
    #define Button          JUCE_NAMESPACE::Button
  #endif

  /* "Rectangle" is defined in some of the newer windows header files, so this makes
     it easier to use the juce version explicitly.

     If you run into difficulties where this macro interferes with other 3rd party header
     files, you may need to use the juce_WithoutMacros.h file - see the comments in that
     file for more information.
  */
  #if JUCE_WIN32 && ! JUCE_DONT_DEFINE_MACROS
    #define Rectangle       JUCE_NAMESPACE::Rectangle
  #endif
#endif
#endif

/* Easy autolinking to the right JUCE libraries under win32.

   Note that this can be disabled by defining DONT_AUTOLINK_TO_JUCE_LIBRARY before
   including this header file.
*/
#if JUCE_MSVC

  #ifndef DONT_AUTOLINK_TO_JUCE_LIBRARY

    /** If you want your application to link to Juce as a DLL instead of
        a static library (on win32), just define the JUCE_DLL macro before
        including juce.h
    */
    #ifdef JUCE_DLL
      #ifdef JUCE_DEBUG
        #define AUTOLINKEDLIB "JUCE_debug.lib"
      #else
        #define AUTOLINKEDLIB "JUCE.lib"
      #endif
    #else
      #ifdef JUCE_DEBUG
        #ifdef _WIN64
          #define AUTOLINKEDLIB "jucelib_static_x64_debug.lib"
        #else
          #define AUTOLINKEDLIB "jucelib_static_Win32_debug.lib"
        #endif
      #else
        #ifdef _WIN64
          #define AUTOLINKEDLIB "jucelib_static_x64.lib"
        #else
          #define AUTOLINKEDLIB "jucelib_static_Win32.lib"
        #endif
      #endif
    #endif

    #pragma comment(lib, AUTOLINKEDLIB)

    #if ! DONT_LIST_JUCE_AUTOLINKEDLIBS
      #pragma message("JUCE! Library to link to: " AUTOLINKEDLIB)
    #endif

    // Auto-link the other win32 libs that are needed by library calls..
    #if ! (defined (DONT_AUTOLINK_TO_WIN32_LIBRARIES) || defined (JUCE_DLL))

/********* Start of inlined file: juce_win32_AutoLinkLibraries.h *********/
// Auto-links to various win32 libs that are needed by library calls..
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "vfw32.lib")
#pragma comment(lib, "comdlg32.lib")
#pragma comment(lib, "winmm.lib")
#pragma comment(lib, "wininet.lib")
#pragma comment(lib, "ole32.lib")
#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "comsupp.lib")
#pragma comment(lib, "version.lib")

#if JUCE_OPENGL
 #pragma comment(lib, "OpenGL32.Lib")
 #pragma comment(lib, "GlU32.Lib")
#endif

#if JUCE_QUICKTIME
 #pragma comment (lib, "QTMLClient.lib")
#endif

#if JUCE_USE_CAMERA
 #pragma comment (lib, "Strmiids.lib")
#endif
/********* End of inlined file: juce_win32_AutoLinkLibraries.h *********/

    #endif

  #endif

#endif

/*
    To start a JUCE app, use this macro: START_JUCE_APPLICATION (AppSubClass) where
    AppSubClass is the name of a class derived from JUCEApplication.

    See the JUCEApplication class documentation (juce_Application.h) for more details.

*/
#if defined (JUCE_GCC) || defined (__MWERKS__)

  #define START_JUCE_APPLICATION(AppClass) \
    int main (int argc, char* argv[]) \
    { \
        return JUCE_NAMESPACE::JUCEApplication::main (argc, argv, new AppClass()); \
    }

#elif JUCE_WIN32

  #ifdef _CONSOLE
    #define START_JUCE_APPLICATION(AppClass) \
        int main (int, char* argv[]) \
        { \
            JUCE_NAMESPACE::String commandLineString (JUCE_NAMESPACE::PlatformUtilities::getCurrentCommandLineParams()); \
            return JUCE_NAMESPACE::JUCEApplication::main (commandLineString, new AppClass()); \
        }
  #elif ! defined (_AFXDLL)
    #ifdef _WINDOWS_
      #define START_JUCE_APPLICATION(AppClass) \
          int WINAPI WinMain (HINSTANCE, HINSTANCE, LPSTR, int) \
          { \
              JUCE_NAMESPACE::String commandLineString (JUCE_NAMESPACE::PlatformUtilities::getCurrentCommandLineParams()); \
              return JUCE_NAMESPACE::JUCEApplication::main (commandLineString, new AppClass()); \
          }
    #else
      #define START_JUCE_APPLICATION(AppClass) \
          int __stdcall WinMain (int, int, const char*, int) \
          { \
              JUCE_NAMESPACE::String commandLineString (JUCE_NAMESPACE::PlatformUtilities::getCurrentCommandLineParams()); \
              return JUCE_NAMESPACE::JUCEApplication::main (commandLineString, new AppClass()); \
          }
    #endif
  #endif

#endif

#endif   // __JUCE_JUCEHEADER__
/********* End of inlined file: juce.h *********/

#endif   // __JUCE_AMALGAMATED_TEMPLATE_JUCEHEADER__
