//==============================================================================
void HostFilterComponent::changeListenerCallback (void* source)
{
    if (source == this)
    {
        closePluginEditorWindows ();
    }
    else if (source == getFilter())
    {
        clearComponents ();
        rebuildComponents ();

        // reopen windows saved with session
        Host* host = getFilter()->host;
        for (int j = 0; j < host->getPluginsCount(); j++)
        {
            BasePlugin* plugin = host->getPluginByIndex (j);
            if (plugin && plugin->getIntValue (PROP_WINDOWOPEN, 0))
                openPluginEditorWindow (plugin);
        }

        resized ();
    }
    else if (source == getFilter()->getTransport())
    {
        // update transport !
        CommandManager::getInstance()->commandStatusChanged ();
    }
    else if (source == &knownPluginList)
    {
       // save the plugin list every time it gets changed, so that if we're scanning
       // and it crashes, we've still saved the previous ones
       XmlElement* const savedPluginList = knownPluginList.createXml();

       if (savedPluginList != 0)
       {
           ApplicationProperties::getInstance()->getUserSettings()
                 ->setValue (T("pluginList"), savedPluginList);

           delete savedPluginList;

           ApplicationProperties::getInstance()->saveIfNeeded();
       }    
    }
    else
    {
        for (int i = pluginWindows.size(); --i >= 0;)
        {
            VstPluginWindow* window = pluginWindows.getUnchecked (i);
            if (window)
                window->updateParameters ();
        }
    }
}
//==============================================================================
bool HostFilterComponent::isPluginEditorWindowOpen (BasePlugin* plugin) const
{
    for (int i = pluginWindows.size(); --i >= 0;)
    {
        VstPluginWindow* window = pluginWindows.getUnchecked (i);
        if (window && window->getPlugin() == plugin)
            return window->isVisible ();
    }
    for (int i = jucePluginWindows.size(); --i >= 0;)
    {
        WrappedJuceVSTPluginWindow* window = jucePluginWindows.getUnchecked (i);
        if (window && window->getPlugin() == plugin)
            return window->isVisible ();
    }
    return false;
}
void HostFilterComponent::resizePluginEditorWindow (BasePlugin* plugin,
                                                    const int width,
                                                    const int height)
{
    DBG ("HostFilterComponent::resizePluginEditorWindow");

    for (int i = pluginWindows.size(); --i >= 0;)
    {
        VstPluginWindow* window = pluginWindows.getUnchecked (i);
        if (window && window->getPlugin() == plugin)
        {
            window->resizeContentComponent (width, height);
            break;
        }
    }
    
    // TODO support hostcomponent resizing jucevst plugin editor windows, i think this is here so size can be saved/loaded
}
void HostFilterComponent::closePluginEditorWindow (BasePlugin* plugin)
{
    DBG ("HostFilterComponent::closePluginEditorWindow");

   if (plugin)
   {
      if (plugin->getType() == JOST_PLUGINTYPE_WRAPPEDJUCEVST)
      {
         // special behaviour for wrapped Juce plugin
         for (int i = jucePluginWindows.size(); --i >= 0;)
         {
            WrappedJuceVSTPluginWindow* window = jucePluginWindows.getUnchecked (i);
            if (window && window->getPlugin() == plugin)
            {
               // save property with plugin
               plugin->setValue (PROP_WINDOWOPEN, 0);

               jucePluginWindows.removeObject (window, true);
               break;
            }
         }

      }
      else 
      {
         // normal Jost plugin behaviour
         for (int i = pluginWindows.size(); --i >= 0;)
         {
            VstPluginWindow* window = pluginWindows.getUnchecked (i);
            if (window && window->getPlugin() == plugin)
            {
               // save property with plugin
               plugin->setValue (PROP_WINDOWOPEN, 0);

               pluginWindows.removeObject (window, true);
               break;
            }
         }
      }
   }
}
//==============================================================================
void VstPluginWindowTabPanel::currentTabChanged (const int newCurrentTabIndex,
                                                 const String &newCurrentTabName)
{
    DBG ("VstPluginWindowTabPanel::currentTabChanged " + newCurrentTabName);

    VstPluginWindow* window = findParentComponentOfClass<VstPluginWindow> ();
    if (window)
    {
        int lastPageIndex = 0;

        // plugins have an external XLib gui editor
        if (newCurrentTabName == T("Interface"))
        {
            if (externalEditor)
            {
                window->setResizable (false, false);
                window->resizeContentComponent (externalEditor->getPreferredWidth (),
                                                externalEditor->getPreferredHeight (),
                                                false);
#ifdef JUCE_MAC
				externalEditor->showGUI(true);
#else				
				plugin->openEditor(window->getWindowHandle (), (void*) 0);
				externalEditor->resized();
#endif
            }
        }
        // plugins have internal parameters gui
        else if (newCurrentTabName == T("Parameters"))
        {
            if (nativeEditor)
            {
                window->setResizable (true, true);
                window->resizeContentComponent (nativeEditor->getPreferredWidth (),
                                                nativeEditor->getPreferredHeight () + 1,
                                                true);

#ifdef JUCE_MAC
				externalEditor->showGUI(false);
#else				
				plugin->closeEditor();
#endif
            }

            // lastPageIndex = (externalEditor) ? 1 : 0;
			lastPageIndex = 0;
        }

        // save property
        plugin->setValue (PROP_WINDOWPAGE, lastPageIndex);
    }
}
void HostFilterComponent::openPluginEditorWindow (BasePlugin* plugin)
{
   // Because the mouse event that invokes this routine is asynchronous, if user double clicks twice in quick succession, we get called again while we are bringing the editor up, and crash in the vst gui show code.
   // This boolean is will prevent entering that code while it is still in progress.
   // (it's possible that we may miss a double-click if user tries to open 2 plugins in quick succession - in which case they can double-click again..)
    static bool creatingWindowNow = false;
    
    DBG ("HostFilterComponent::openPluginEditorWindow");

    if (plugin)
    {
      if (plugin->getType() == JOST_PLUGINTYPE_WRAPPEDJUCEVST)
      {
         WrappedJuceVSTPluginWindow* jucePlugWindow = 0;
         for (int i = jucePluginWindows.size(); --i >= 0;)
         {
            WrappedJuceVSTPluginWindow* window = jucePluginWindows.getUnchecked (i);
            if (window && window->getPlugin() == plugin)
            {
                jucePlugWindow = window;
                break;
            }
         }
         if (!jucePlugWindow && !creatingWindowNow)
         {
            creatingWindowNow = true;
            jucePlugWindow = WrappedJuceVSTPluginWindow::CreateWindowFor(plugin, this); 
            jucePluginWindows.add(jucePlugWindow);
            creatingWindowNow = false;
         }
         
         if (jucePlugWindow)
         {
            if (! jucePlugWindow->isVisible ())
                jucePlugWindow->setVisible (true);
            jucePlugWindow->toFront (false);
         }
      }
      else 
      {
      // normal Jost plugin behaviour
        VstPluginWindow* pluginWindow = 0;
        for (int i = pluginWindows.size(); --i >= 0;)
        {
            VstPluginWindow* window = pluginWindows.getUnchecked (i);
            if (window && window->getPlugin() == plugin)
            {
                pluginWindow = window;
                break;
            }
        }

        if (! pluginWindow)
        {
            pluginWindow = new VstPluginWindow (this, plugin);
            pluginWindows.add (pluginWindow);
        }
        else
        {
            if (pluginWindow->getPlugin () != plugin)
                pluginWindow->setPlugin (plugin);

            if (! pluginWindow->isVisible ())
                pluginWindow->setVisible (true);
            pluginWindow->toFront (false);
        }

      }
      
        // save property with plugin
        plugin->setValue (PROP_WINDOWOPEN, 1);
    }
}