text: #include "properties.h"
  
  #include <QIcon>
  #include <QLabel>
  #include <QLineEdit>
  #include <QComboBox>
  #include <QMenu>
  
  #include "context.h"
  #include "ecs.h"
  #include "worldmanager.h"
  #include "vec3edit.h"
  #include "collapsesection.h"
  #include "coloredit.h"
  
  Properties::Properties(Context& context, QWidget* parent) : QWidget(parent), context(context) {
      setWindowTitle("Properties");
      setWindowIcon(QIcon::fromTheme("document-properties"));
  
      layout = new QVBoxLayout();
      layout->setAlignment(Qt::AlignTop);
      layout->setSpacing(0);
  
      QMenu* addComponentMenu = new QMenu();
  
      QAction* addMeshComponent = new QAction("Mesh");
      connect(addMeshComponent, &QAction::triggered, [&context] {
          const auto& entity = context.selectedEntities[0];
  
          ECS::addComponent<MeshComponent>(entity);
  
          emit context.entitiesChanged();
      });
      addComponentMenu->addAction(addMeshComponent);
  
      QAction* addLightComponent = new QAction("Light");
      connect(addLightComponent, &QAction::triggered, [&context] {
          const auto& entity = context.selectedEntities[0];
  
          ECS::addComponent<LightComponent>(entity);
  
          emit context.entitiesChanged();
      });
      addComponentMenu->addAction(addLightComponent);
  
      addComponentButton = new QPushButton("Add Component...");
      addComponentButton->setMenu(addComponentMenu);
      layout->addWidget(addComponentButton);
  
      setLayout(layout);
  
      rebuild();
  
      connect(&context, &Context::selectionChanged, this, &Properties::rebuild);
      connect(&context, &Context::entitiesChanged, this, &Properties::rebuild);
  }
  
  void Properties::rebuild() {
      for(auto section : sections) {
          layout->removeWidget(section);
          delete section;
      }
  
      sections.clear();
  
      addComponentButton->setEnabled(context.selectedEntities.size() != 0);
  
      if(context.selectedEntities.size() == 0)
          return;
  
      const auto& entity = context.selectedEntities[0];
  
      InfoComponent* info = ECS::getComponent<InfoComponent>(entity);
      if(info)
          addInfoSection(info);
  
      TransformComponent* transform = ECS::getComponent<TransformComponent>(entity);
      if(transform)
          addTransformSection(transform);
  
      MeshComponent* mesh = ECS::getComponent<MeshComponent>(entity);
      if(mesh)
          addMeshSection(mesh);
  
      LightComponent* light = ECS::getComponent<LightComponent>(entity);
      if(light)
          addLightSection(light);
  }
  
  void Properties::addInfoSection(InfoComponent* info) {
      CollapseSection* section = new CollapseSection("Info");
      layout->addWidget(section);
      sections.push_back(section);
  
      QGridLayout* layout = new QGridLayout();
      section->setLayout(layout);
  
      QLabel* nameLabel = new QLabel("Name");
      layout->addWidget(nameLabel);
  
      QLineEdit* nameEdit = new QLineEdit();
      nameEdit->setText(info->name.c_str());
  
      connect(nameEdit, &QLineEdit::editingFinished, [info, nameEdit, this] {
          info->name = nameEdit->text().toStdString();
  
          emit context.entitiesChanged();
      });
      layout->addWidget(nameEdit, 0, 1);
  }
  
  void Properties::addTransformSection(TransformComponent* transform) {
      CollapseSection* section = new CollapseSection("Transform");
      layout->addWidget(section);
      sections.push_back(section);
  
      QGridLayout* layout = new QGridLayout();
      section->setLayout(layout);
  
      QLabel* positionLabel = new QLabel("Position");
      layout->addWidget(positionLabel);
  
      Vector3Edit* positionEdit = new Vector3Edit(transform->position);
      layout->addWidget(positionEdit, 0, 1);
  }
  
  void Properties::addMeshSection(MeshComponent* mesh) {
      const auto& entity = context.selectedEntities[0];
  
      CollapseSection* section = new CollapseSection("Mesh", true);
      connect(section, &CollapseSection::closeRequested, [entity, this] {
          ECS::removeComponent<MeshComponent>(entity);
  
          emit context.entitiesChanged();
      });
      layout->addWidget(section);
      sections.push_back(section);
  
      QGridLayout* layout = new QGridLayout();
      section->setLayout(layout);
  }
  
  void Properties::addLightSection(LightComponent* light) {
      const auto& entity = context.selectedEntities[0];
  
      CollapseSection* section = new CollapseSection("Light", true);
      connect(section, &CollapseSection::closeRequested, [entity, this] {
          ECS::removeComponent<LightComponent>(entity);
  
          emit context.entitiesChanged();
      });
      layout->addWidget(section);
      sections.push_back(section);
  
      QGridLayout* layout = new QGridLayout();
      section->setLayout(layout);
  
      QLabel* typeLabel = new QLabel("Type");
      layout->addWidget(typeLabel);
  
      QComboBox* typeCombo = new QComboBox();
      typeCombo->addItem("Point");
      typeCombo->addItem("Directional");
      typeCombo->setCurrentIndex((int)light->type);
  
      connect(typeCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), [light](int index) {
          light->type = (LightType)index;
      });
  
      layout->addWidget(typeCombo, 0, 1);
  
      QLabel* colorLabel = new QLabel("Color");
      layout->addWidget(colorLabel, 1, 0);
  
      ColorEdit* colorEdit = new ColorEdit(light->color);
      layout->addWidget(colorEdit, 1, 1);
  }
  