// Copyright (C) 2016 Jochen Becher
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0

#include "dflatassignmentvisitor.h"

#include "qmt/diagram/delement.h"
#include "qmt/diagram/dobject.h"
#include "qmt/diagram/dpackage.h"
#include "qmt/diagram/dclass.h"
#include "qmt/diagram/dcomponent.h"
#include "qmt/diagram/ddiagram.h"
#include "qmt/diagram/ditem.h"
#include "qmt/diagram/drelation.h"
#include "qmt/diagram/dinheritance.h"
#include "qmt/diagram/ddependency.h"
#include "qmt/diagram/dassociation.h"
#include "qmt/diagram/dconnection.h"
#include "qmt/diagram/dannotation.h"
#include "qmt/diagram/dboundary.h"
#include "qmt/diagram/dswimlane.h"
#include "qmt/infrastructure/qmtassert.h"

namespace qmt {

// TODO may flat assignment visitor use operator=() ?

DFlatAssignmentVisitor::DFlatAssignmentVisitor(DElement *target)
    : m_target(target)
{
    QMT_CHECK(target);
}

void DFlatAssignmentVisitor::visitDElement(const DElement *element)
{
    Q_UNUSED(element)
}

void DFlatAssignmentVisitor::visitDObject(const DObject *object)
{
    visitDElement(object);
    auto target = dynamic_cast<DObject *>(m_target);
    QMT_ASSERT(target, return);
    target->setStereotypes(object->stereotypes());
    target->setName(object->name());
    target->setPos(object->pos());
    target->setRect(object->rect());
    target->setAutoSized(object->isAutoSized());
    target->setDepth(object->depth());
    target->setVisualPrimaryRole(object->visualPrimaryRole());
    target->setVisualSecondaryRole(object->visualSecondaryRole());
    target->setVisualEmphasized(object->isVisualEmphasized());
    target->setStereotypeDisplay(object->stereotypeDisplay());
}

void DFlatAssignmentVisitor::visitDPackage(const DPackage *package)
{
    visitDObject(package);
}

void DFlatAssignmentVisitor::visitDClass(const DClass *klass)
{
    visitDObject(klass);
    auto target = dynamic_cast<DClass *>(m_target);
    QMT_ASSERT(target, return);
    target->setUmlNamespace(klass->umlNamespace());
    target->setTemplateParameters(klass->templateParameters());
    target->setTemplateDisplay(klass->templateDisplay());
    target->setMembers(klass->members());
    target->setShowAllMembers(klass->showAllMembers());
    target->setVisibleMembers(klass->visibleMembers());
}

void DFlatAssignmentVisitor::visitDComponent(const DComponent *component)
{
    visitDObject(component);
    auto target = dynamic_cast<DComponent *>(m_target);
    QMT_ASSERT(target, return);
    target->setPlainShape(component->isPlainShape());
}

void DFlatAssignmentVisitor::visitDDiagram(const DDiagram *diagram)
{
    visitDObject(diagram);
}

void DFlatAssignmentVisitor::visitDItem(const DItem *item)
{
    visitDObject(item);
    auto target = dynamic_cast<DItem *>(m_target);
    QMT_ASSERT(target, return);
    target->setVariety(target->variety());
    target->setShapeEditable(target->isShapeEditable());
    target->setShape(target->shape());
}

void DFlatAssignmentVisitor::visitDRelation(const DRelation *relation)
{
    visitDElement(relation);
    auto target = dynamic_cast<DRelation *>(m_target);
    QMT_ASSERT(target, return);
    target->setStereotypes(relation->stereotypes());
    target->setIntermediatePoints(relation->intermediatePoints());
}

void DFlatAssignmentVisitor::visitDInheritance(const DInheritance *inheritance)
{
    visitDRelation(inheritance);
}

void DFlatAssignmentVisitor::visitDDependency(const DDependency *dependency)
{
    visitDRelation(dependency);
    auto target = dynamic_cast<DDependency *>(m_target);
    QMT_ASSERT(target, return);
    target->setDirection(dependency->direction());
}

void DFlatAssignmentVisitor::visitDAssociation(const DAssociation *association)
{
    visitDRelation(association);
    auto target = dynamic_cast<DAssociation *>(m_target);
    QMT_ASSERT(target, return);
    target->setEndA(association->endA());
    target->setEndB(association->endB());
    // TODO assign assoziation class?
}

void DFlatAssignmentVisitor::visitDConnection(const DConnection *connection)
{
    visitDRelation(connection);
    auto target = dynamic_cast<DConnection *>(m_target);
    QMT_ASSERT(target, return);
    target->setCustomRelationId(connection->customRelationId());
    target->setEndA(connection->endA());
    target->setEndB(connection->endB());
}

void DFlatAssignmentVisitor::visitDAnnotation(const DAnnotation *annotation)
{
    visitDElement(annotation);
    auto target = dynamic_cast<DAnnotation *>(m_target);
    QMT_ASSERT(target, return);
    target->setText(annotation->text());
    target->setPos(annotation->pos());
    target->setRect(annotation->rect());
    target->setAutoSized(annotation->isAutoSized());
    target->setVisualRole(annotation->visualRole());
}

void DFlatAssignmentVisitor::visitDBoundary(const DBoundary *boundary)
{
    visitDElement(boundary);
    auto target = dynamic_cast<DBoundary *>(m_target);
    QMT_ASSERT(target, return);
    target->setText(boundary->text());
    target->setPos(boundary->pos());
    target->setRect(boundary->rect());
}

void DFlatAssignmentVisitor::visitDSwimlane(const DSwimlane *swimlane)
{
    visitDElement(swimlane);
    auto target = dynamic_cast<DSwimlane *>(m_target);
    QMT_ASSERT(target, return);
    target->setText(swimlane->text());
    target->setHorizontal(swimlane->isHorizontal());
    target->setPos(swimlane->pos());
}

} // namespace qmt
