/*!********************************************************************

  Audacity: A Digital Audio Editor

  @file ProjectWindows.cpp

  Paul Licameli split from Project.cpp

**********************************************************************/

#include "ProjectWindows.h"
#include "Project.h"

#include <wx/frame.h>

namespace {
struct ProjectWindows final : ClientData::Base
{
   static ProjectWindows &Get( AudacityProject &project );
   static const ProjectWindows &Get( const AudacityProject &project );
   explicit ProjectWindows(AudacityProject &project)
      : mAttachedWindows{project}
   {}

   wxWeakRef< wxWindow > mPanel{};
   wxWeakRef< wxFrame > mFrame{};

   AttachedWindows mAttachedWindows;
};

const AudacityProject::AttachedObjects::RegisteredFactory key{
   [](AudacityProject &project) {
      return std::make_unique<ProjectWindows>(project);
   }
};

ProjectWindows &ProjectWindows::Get( AudacityProject &project )
{
   return project.AttachedObjects::Get< ProjectWindows >( key );
}

const ProjectWindows &ProjectWindows::Get( const AudacityProject &project )
{
   return Get( const_cast< AudacityProject & >( project ) );
}
}

AUDACITY_DLL_API wxWindow &GetProjectPanel( AudacityProject &project )
{
   auto ptr = ProjectWindows::Get(project).mPanel;
   if ( !ptr )
      THROW_INCONSISTENCY_EXCEPTION;
   return *ptr;
}

AUDACITY_DLL_API const wxWindow &GetProjectPanel(
   const AudacityProject &project )
{
   auto ptr = ProjectWindows::Get(project).mPanel;
   if ( !ptr )
      THROW_INCONSISTENCY_EXCEPTION;
   return *ptr;
}

AUDACITY_DLL_API void SetProjectPanel(
   AudacityProject &project, wxWindow &panel )
{
   ProjectWindows::Get(project).mPanel = &panel;
}

AUDACITY_DLL_API wxFrame &GetProjectFrame( AudacityProject &project )
{
   auto ptr = ProjectWindows::Get(project).mFrame;
   if ( !ptr )
      THROW_INCONSISTENCY_EXCEPTION;
   return *ptr;
}

AUDACITY_DLL_API const wxFrame &GetProjectFrame( const AudacityProject &project )
{
   auto ptr = ProjectWindows::Get(project).mFrame;
   if ( !ptr )
      THROW_INCONSISTENCY_EXCEPTION;
   return *ptr;
}

wxFrame *FindProjectFrame( AudacityProject *project ) {
   if (!project)
      return nullptr;
   return ProjectWindows::Get(*project).mFrame;
}

const wxFrame *FindProjectFrame( const AudacityProject *project ) {
   if (!project)
      return nullptr;
   return ProjectWindows::Get(*project).mFrame;
}

void SetProjectFrame(AudacityProject &project, wxFrame &frame )
{
   ProjectWindows::Get(project).mFrame = &frame;
}

AUDACITY_DLL_API AttachedWindows &GetAttachedWindows(AudacityProject &project)
{
   return ProjectWindows::Get(project).mAttachedWindows;
}
