/////////////////////////////////////////////////////////////////////////////
// Name:        dbconstraint.cc
// Purpose:     Database Objects
// Author:      Daniel Horak
// Modified by:
// RCS-ID:      $Id: dbconstraint.cc,v 1.4 2004/01/04 18:32:16 horakdan Exp $
// Copyright:   (c) Daniel Horak
// Licence:     GPL
/////////////////////////////////////////////////////////////////////////////

// ============================================================================
// declarations
// ============================================================================

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

// For compilers that support precompilation, includes "wx/wx.h".
#include <wx/wxprec.h>

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWindows headers
#ifndef WX_PRECOMP
#include <wx/wx.h>
#endif

#include <wx/notebook.h>
#include "config.h"
#include "xml.h"
#include "dbobject.h"
#include "dbconstraint.h"
#include "dbsimpleattr.h"
#include "dbattribute.h"


wxString DBConstraint::m_type_val[] = { "primarykey", "foreignkey", "unique", "check" };

DBConstraint::DBConstraint(DataDesignerProject *project, DataDesignerContainer *container)
	:DBObject(DBConstraintType, "constraint", project, container),
	m_type(DBO_CONSTRAINT_TYPE_CHECK), m_deferrable(FALSE), m_immediate(FALSE), m_attrs(NULL)
{
}

DBConstraint::~DBConstraint()
{
	if (m_attrs) {
		m_project->DeleteChildren(m_attrs->GetTreeItemId());
		delete m_attrs;
	}
}

wxDialog *DBConstraint::Editor(bool edit)
{
	return new DBConstraintEditor(this, edit);
}

void DBConstraint::LoadXmlNode(wxXmlNode *node)
{
	if (node->GetName() == m_typestr) {
		DBObject::LoadXmlNode(node);
		
		LoadBoolProperty(node, "deferrable", m_deferrable, FALSE);
		LoadBoolProperty(node, "immediate", m_immediate, FALSE);
		m_relation = node->GetPropVal("relation", wxEmptyString);
	
		wxXmlNode *child = node->GetChildren();
		wxString name;
		
		while (child) {
			name = child->GetName();
			if (name == "type") {
				wxString type;
				LoadTextNode(child, "type", type);
				if (type == "primarykey")
					m_type = DBO_CONSTRAINT_TYPE_PRIMARY_KEY;
				else if (type == "foreignkey")
					m_type = DBO_CONSTRAINT_TYPE_FOREIGN_KEY;
				else if (type == "unique")
					m_type = DBO_CONSTRAINT_TYPE_UNIQUE;
				else if (type == "check")
					m_type = DBO_CONSTRAINT_TYPE_CHECK;
				else
					wxLogMessage("Unknown constraint type specification '%s'", type.c_str());
			} else if (name == "deferrable") {
				LoadBoolNode(child, "deferrable", m_deferrable, FALSE);
			} else if (name == "immediate") {
				LoadBoolNode(child, "immediate", m_immediate, FALSE);
			} else if (name == "relation") {
				LoadTextNode(child, "relation", m_relation);
			} else if (name == "simpleattributes") {
				m_attrs->LoadXmlNode(child);
			}
			child = child->GetNext();
		}
	} else {
		wxLogMessage("wrong type '%s'", node->GetName().c_str());
	}
}

wxTreeItemId DBConstraint::AppendItem()
{
	if (! m_appended) {
		m_treeitemid	= m_project->AppendItem(m_container->GetTreeItemId(), m_name, -1, -1, new DataDesignerItemData(this));
		m_attrs		= new DBSimpleAttributeContainer(m_project, m_project->AppendItem(m_treeitemid, _("Constraint's Attributes")));
		m_appended	= TRUE;
	}

	return m_treeitemid;
}

wxXmlNode *DBConstraint::GetXmlNode()
{
	wxXmlNode *node = DBObject::GetXmlNode();
	
	node->AddChild(GetTextNode("type", m_type_val[m_type]));
	node->AddChild(GetBoolNode("deferrable", m_deferrable));
	node->AddChild(GetBoolNode("immediate", m_immediate));
	node->AddChild(GetTextNode("relation", m_relation));
	node->AddChild(m_attrs->GetXmlNode());
	
	return node;
}

void DBConstraint::AddAttribute(const wxString &name)
{
	DBSimpleAttribute *sa;

#ifdef ENABLE_DEBUG
	wxLogMessage("DBConstraint::AddAttribute(wxString name)");
#endif
	
	sa = (DBSimpleAttribute *)m_attrs->CreateObject();
	if (sa == NULL) {
		wxLogMessage("DBConstraint::AddAttribute - cannot create simpleattr");
		return;
	}
	sa->m_name = name;
	sa->AppendItem();
}

void DBConstraint::AddAttribute(DBAttribute *attr)
{
	DBSimpleAttribute *sa;

#ifdef ENABLE_DEBUG
	wxLogMessage("DBConstraint::AddAttribute(DBAttribute *attr)");
#endif
	
	sa = (DBSimpleAttribute *)m_attrs->CreateObject();
	if (sa == NULL) {
		wxLogMessage("DBConstraint::AddAttribute - cannot create simpleattr");
		return;
	}
	sa->m_name = attr->GetName();
	sa->AppendItem();
	sa->SetRealAttribute(attr);
	attr->AddSimpleAttribute(sa);
}

void DBConstraint::DeleteAttribute(const wxString &name)
{
	DBSimpleAttribute *sa;
	
	sa = (DBSimpleAttribute *)m_attrs->GetObjectByName(name);
	if (sa) {
		delete sa;
	}
}

/*
 * Editor
 */
BEGIN_EVENT_TABLE(DBConstraintEditor, DBObjectEditor)
	EVT_BUTTON(wxID_APPLY, DBConstraintEditor::OnApply)
END_EVENT_TABLE()

wxString	DBConstraintEditor::m_type_str[] = { _("Primary Key"), _("Foreign Key"), _("Unique"), _("Check") };
int DBConstraintEditor::m_types_count = sizeof(DBConstraintEditor::m_type_str) / sizeof(wxString);

DBConstraintEditor::DBConstraintEditor(DBObject *object, bool edit)
	: DBObjectEditor(_("Constraint"), wxSize(500,300), object, edit)
{
	int		i;
	
	m_page_attrs = new wxPanel(m_notebook);

        m_list_attrs = new DBSimpleAttributeListCtrl(m_page_attrs,((DBConstraint *)GetObject())->m_attrs);
	
	if (m_edit) {
		((DBConstraint *)GetObject())->m_attrs->SetList(m_list_attrs);
		((DBConstraint *)GetObject())->m_attrs->AddObjectsToList();
	}

	wxLayoutConstraints *c = new wxLayoutConstraints;
	c->top.SameAs   (m_page_attrs, wxTop);
	c->left.SameAs  (m_page_attrs, wxLeft);
	c->right.SameAs (m_page_attrs, wxRight);
	c->bottom.SameAs(m_page_attrs, wxBottom);
	m_list_attrs->SetConstraints(c);

	m_page_attrs->SetAutoLayout(TRUE);
	
	m_notebook->InsertPage(m_notebook->GetPageCount() - 1, m_page_attrs, _("Attributes"));
		
	new wxStaticText(m_page_general, -1, _("Type"), wxPoint(10,60), wxSize(80,-1), wxALIGN_RIGHT);
	c1 = new wxComboBox(m_page_general, -1, wxEmptyString, wxPoint(100,60), wxSize(100,-1), m_types_count, m_type_str);

	c2 = new wxCheckBox(m_page_general, -1, "Deferrable", wxPoint(20,85), wxSize(100,-1));
	c3 = new wxCheckBox(m_page_general, -1, "Immediate", wxPoint(20,110), wxSize(100,-1));
	
	new wxStaticText(m_page_general, -1, _("Relation"), wxPoint(10,135), wxSize(80,-1), wxALIGN_RIGHT);
	t4 = new wxTextCtrl(m_page_general, -1, wxEmptyString, wxPoint(100,135), wxSize(100,-1));
	t4->Disable();
	
	m_button_apply = AddButton(wxID_APPLY, _("Apply"), wxSize(60,-1));

	if (m_edit) {
		m_button_ok->SetDefault();
	} else {
		m_button_apply->SetDefault();
		
		m_page_attrs->Disable();
	}
}

DBConstraintEditor::~DBConstraintEditor()
{
}

bool DBConstraintEditor::TransferDataFromWindow()
{
	DBConstraint	*object = (DBConstraint *)GetObject();

	DBObjectEditor::TransferDataFromWindow();
	
	object->m_type		= c1->FindString(c1->GetValue());
	object->m_deferrable	= c2->GetValue();
	object->m_immediate	= c3->GetValue();
	
	return TRUE;
}

bool DBConstraintEditor::TransferDataToWindow()
{
	DBConstraint	*object = (DBConstraint *)GetObject();
	
	DBObjectEditor::TransferDataToWindow();
	
	c1->SetValue(c1->GetString(object->m_type));
	c2->SetValue(object->m_deferrable);
	c3->SetValue(object->m_immediate);
	t4->SetValue(object->m_relation);

	return TRUE;
}

void DBConstraintEditor::OnApply(wxCommandEvent& event)
{
	DBConstraint	*object = (DBConstraint *)GetObject();
	
	if (Validate() == FALSE)
		return;
	
	TransferDataFromWindow();
	
	object->AppendItem();
	m_list_attrs->SetContainer(object->m_attrs);

	m_page_attrs->Enable();
	
	m_button_apply->Disable();
	m_button_ok->SetDefault();

	m_edit = TRUE;
}

/*
 * Container
 */
DBConstraintContainer::DBConstraintContainer(DataDesignerProject *project, const wxTreeItemId& parent)
	: DataDesignerContainer(project, parent, "constraints")
{
}

DBObject *DBConstraintContainer::CreateObject()
{
	return new DBConstraint(GetProject(), this);
}

void DBConstraintContainer::ShowList()
{
	SetList(new DBConstraintListCtrl(GetProject()->GetSplitter(), this));
	
	DataDesignerContainer::AddObjectsToListAndShow();
}

/*
 * ObjectList
 */
DBConstraintListCtrl::DBConstraintListCtrl(wxWindow *parent, DataDesignerContainer *container)
	: DBObjectListCtrl(parent, container)
{
}

DBConstraintListCtrl::~DBConstraintListCtrl()
{
}

void DBConstraintListCtrl::SetObject(long item, DBObject *object)
{
	DBConstraint *constraint = (DBConstraint *)object;
}


syntax highlighted by Code2HTML, v. 0.9.1