/***************************************************************************
 *   Copyright (C) 2005 by David Saxton                                    *
 *   david@bluehaze.org                                                    *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 ***************************************************************************/

#ifndef ITEMDOCUMENTDATA_H
#define ITEMDOCUMENTDATA_H

#include "item.h"
#include "microsettings.h"

#include <tqdom.h>

class Connector;
class ECSubcircuit;
class KURL;
class Node;
class PinMapping;

typedef TQValueList<TQGuardedPtr<Connector> > ConnectorList;
typedef TQValueList<TQGuardedPtr<Item> > ItemList;
typedef TQValueList<TQGuardedPtr<Node> > NodeList;
typedef TQMap< TQString, PinMapping > PinMappingMap;

typedef TQValueList<TQPoint> TQPointList;
typedef TQMap<TQString, bool> BoolMap;
typedef TQMap<TQString, double> DoubleMap;
typedef TQMap<TQString, int> IntMap;
typedef TQMap<TQString, TQColor> TQColorMap;
typedef TQMap<TQString, TQString> TQStringMap;
typedef TQMap<TQString, TQBitArray> TQBitArrayMap;


class ItemData
{
	public:
		ItemData();
		
		TQString type;
		double x;
		double y;
		int z;
		TQRect size;
		bool setSize;
		int orientation; // used for flowparts, should be set to -1 if not used.
		double angleDegrees;
		bool flipped;
		BoolMap buttonMap;
		IntMap sliderMap;
		TQString parentId;
		BoolMap dataBool;
		DoubleMap dataNumber;
		TQColorMap dataColor;
		TQStringMap dataString;
		TQBitArrayMap dataRaw;
};
typedef TQMap< TQString, ItemData > ItemDataMap;


class ConnectorData
{
	public:
		ConnectorData();
		
		TQPointList route;
		bool manualRoute;
		
		bool startNodeIsChild;
		bool endNodeIsChild;
		
		TQString startNodeCId;
		TQString endNodeCId;
		
		TQString startNodeParent;
		TQString endNodeParent;
		
		TQString startNodeId;
		TQString endNodeId;
};
typedef TQMap< TQString, ConnectorData > ConnectorDataMap;


class NodeData
{
	public:
		NodeData();
		
		double x;
		double y;
};
typedef TQMap< TQString, NodeData > NodeDataMap;


class PinData
{
	public:
		PinData();
		
		PinSettings::pin_type type;
		PinSettings::pin_state state;
};
typedef TQMap< TQString, PinData > PinDataMap;


class MicroData
{
	public:
		MicroData();
		void reset();
		
		TQString id;
		PinDataMap pinMap;
		TQStringMap variableMap;
		PinMappingMap pinMappings;
};


/**
This class encapsulates all or part of an ItemDocument. It is used for writing
the document to file / reading from file, as well as for the clipboard and
undo/redo system.
@author David Saxton
*/
class ItemDocumentData
{
	public:
		ItemDocumentData( uint documentType );
		~ItemDocumentData();
		/**
		 * Erases / resets all data to defaults
		 */
		void reset();
		/**
		 * Read in data from a saved file. Any existing data in this class will
		 * be deleted first.
		 * @returns true iff successful
		 */
		bool loadData( const KURL &url );
		/**
		 * Write the data to the given file.
		 * @returns true iff successful
		 */
		bool saveData( const KURL &url );
		/**
		 * Returns the xml used for describing the data
		 */
		TQString toXML();
		/**
		 * Restore the document from the given xml
		 * @return true if successful
		 */
		bool fromXML( const TQString &xml );
		/**
		 * Saves the document to the data
		 */
		void saveDocumentState( ItemDocument *itemDocument );
		/**
		 * Restores a document to the state stored in this class
		 */
		void restoreDocument( ItemDocument *itemDocument );
		/**
		 * Merges the stuff stored here with the given document. If this is
		 * being used for e.g. pasting, you should call generateUniqueIDs()
		 * @param selectNew if true then the newly created items & connectors will be selected
		 */
		void mergeWithDocument( ItemDocument *itemDocument, bool selectNew );
		/**
		 * Replaces the IDs of everything with unique ones for the document.
		 * Used in pasting.
		 */
		void generateUniqueIDs( ItemDocument *itemDocument );
		/**
		 * Move all the items, connectors, nodes, etc by the given amount
		 */
		void translateContents( int dx, int dy );
		/**
		 * Returns the document type.
		 * @see Document::DocumentType
		 */
		uint documentType() const { return m_documentType; }
		
		//BEGIN functions for adding data
		void setMicroData( const MicroData &data );
		void addItems( const ItemList &itemList );
		void addConnectors( const ConnectorList &connectorList );
		void addNodes( const NodeList &nodeList );
		
		/**
		 * Add the given ItemData to the stored data
		 */
		void addItemData( ItemData itemData, TQString id );
		/**
		 * Add the given ConnectorData to the stored data
		 */
		void addConnectorData( ConnectorData connectorData, TQString id );
		/**
		 * Add the given NodeData to the stored data
		 */
		void addNodeData( NodeData nodeData, TQString id );
		//END functions for adding data
		
		//BEGIN functions for returning strings for saving to xml
		TQString documentTypeString() const;
		TQString revisionString() const;
		//END functions for returning strings for saving to xml
		
	protected:
		//BEGIN functions for generating TQDomElements
		TQDomElement microDataToElement( TQDomDocument &doc );
		TQDomElement itemDataToElement( TQDomDocument &doc, const ItemData &itemData );
		TQDomElement nodeDataToElement( TQDomDocument &doc, const NodeData &nodeData );
		TQDomElement connectorDataToElement( TQDomDocument &doc, const ConnectorData &connectorData );
		//END functions for generating TQDomElements
		
		//BEGIN functions for reading TQDomElements to stored data
		void elementToMicroData( TQDomElement element );
		void elementToItemData( TQDomElement element );
		void elementToNodeData( TQDomElement element );
		void elementToConnectorData( TQDomElement element );
		//END functions for reading TQDomElements to stored data
		
		ItemDataMap m_itemDataMap;
		ConnectorDataMap m_connectorDataMap;
		NodeDataMap m_nodeDataMap;
		MicroData m_microData;
		uint m_documentType; // See Document::DocumentType
};


class SubcircuitData : public ItemDocumentData
{
	public:
		SubcircuitData();
		void initECSubcircuit( ECSubcircuit * ecSubcircuit );
};

#endif
