/***************************************************************************
 *   Copyright (C) 2004 by Kazuki Ohta                                     *
 *   mover@hct.zaq.ne.jp                                                   *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "contactxml.h"
#include "kkcontactdata.h"

#include <qdom.h>
#include <qfile.h>
#include <qtextstream.h>
#include <qstringlist.h>

#define DOCUMENT_NAME  "ContactXML"
#define ROOT_ELEM_NAME "ContactXML"

#define _FU8(STR) QString::fromUtf8(STR)

/**
 * Sample Format of ContactXML
 * <?xml version="1.0" encoding="UTF-8"?>
 * <!DOCTYPE ContactXML>
 * <ContactXML xmlns="http://www.xmlns.org/2002/ContactXML" version="1.1" creator="kreetingkard">
 * <ContactXMLItem>
 *     <PersonName>
 *         <PersonNameItem>
 *             <FullName pronunciation="ヤマダ タロウ">山田 太郎</FullName>
 *         </PersonNameItem>
 *     </PersonName>
 *     <Address>
 *         <AddressCode codeDomain="ZIP7">123-4567</AddressCode>
 *         <AddressItem locationType="Home">
 *             <FullAddress>東京都品川区大井町1-2-3アイウエオビル21F</FullAddress>
 *         </AddressItem>
 *     </Address>
 *     <Phone>
 *         <PhoneItem phoneDevice="Phone">xxxx-xx-xxxx</PhoneItem>
 *         <PhoneItem phoneDevice="Cellular">xxx-xxxx-xxxx</PhoneItem>
 *     </Phone>
 *     <Email>
 *         <EmailItem emailDevice="PC">a@a.com</EmailItem>
 *         <EmailItem emailDevice="Cellular">a@a.docomo.ne.jp</EmailItem>
 *     </Email>
 *     <Extention>
 *         <ExtentionItem extentionType="Common" name="Suffix">sama<ExtentionItem>
 *         <ExtentionItem extentionType="Extended" name="Group">friends<ExtentionItem>
 *     </Extention>
 * </ContactXMLItem>
 */

QPtrList<KKContactData> ContactXML::readContactXML( const QString &filename )
{

	QPtrList<KKContactData> datas;
	datas.clear();

	QDomDocument doc( DOCUMENT_NAME );
	QFile file( filename );
	if( file.open( IO_ReadOnly ) )
	{
		if( !doc.setContent( &file ) )
		{
			file.close();
			return datas;
		}
		file.close();
	}
	else
	{
		return datas;
	}

	QDomElement root = doc.documentElement();
	if( root.tagName() != "ContactXML" ) return datas;

	QDomNode ContactXMLItem = root.firstChild();
	while( !ContactXMLItem.isNull() )
	{
		if( ContactXMLItem.toElement().tagName() == "ContactXMLItem" )
		{
			datas.append( parseItem( ContactXMLItem.toElement() ) );
		}
		else
		{
			return datas;
		}

		ContactXMLItem = ContactXMLItem.nextSibling();
	}

	return datas;
}

KKContactData* ContactXML::parseItem( const QDomElement &contactXMLItem )
{
	QString pronunciation = QString::null;
	QString fullname = QString::null;
	QString address1 = QString::null;
        QString address2 = QString::null;
	QString phonenumber = QString::null;
	QString cellularphonenumber = QString::null;
	QString pcemail = QString::null;
	QString cellularphonemail = QString::null;
	QString suffix = QString::null;
	QString group = QString::null;
	QString zipcode = QString::null;

	QDomNode node = contactXMLItem.firstChild();
	while( !node.isNull() )
	{
		QString tagName = node.toElement().tagName();
		if( tagName == "PersonName" )
		{
			QDomElement PersonNameItem = node.toElement().firstChild().toElement();
			QDomElement FullName = PersonNameItem.firstChild().toElement();
			pronunciation = _FU8( FullName.attribute( "pronunciation" ) );
			if( FullName.firstChild().nodeType() == QDomNode::TextNode )
				fullname = _FU8( FullName.firstChild().toText().data() );
		}
		else if( tagName == "Address" )
		{
			QDomNode AddressNode = node.toElement().firstChild();
			while( !AddressNode.isNull() )
			{
				QString addressTagName = AddressNode.toElement().tagName();
				if( addressTagName == "AddressCode" )
				{
					QDomElement AddressCode = AddressNode.toElement();
					if( AddressCode.attribute( "codeDomain" ) == "ZIP7" )
					{
						if( AddressCode.firstChild().nodeType() == QDomNode::TextNode )
						{
							zipcode = _FU8( AddressCode.firstChild().toText().data() );
						}
					}
				}
				else if( addressTagName == "AddressItem" )
				{
					QDomElement AddressItem = AddressNode.toElement();
					QDomElement FullAddress = AddressItem.firstChild().toElement();
					if( FullAddress.firstChild().nodeType() == QDomNode::TextNode )
					{
						// 2004-11-18 Kazuki Ohta <mover@hct.zaq.ne.jp>
						// Address1 and Address2 is splitted by '\t' (tab).
						// Is there any efficiant way to avoid this trick?
						QString fulladdress = _FU8( FullAddress.firstChild().toText().data() );
						QStringList addresses = QStringList::split("\t", fulladdress);

						address1 = addresses[0];
						address2 = addresses[1];
					}
				}

                                AddressNode = AddressNode.nextSibling();
			}
		}
		else if( tagName == "Phone" )
		{
			QDomNode PhoneItemNode = node.toElement().firstChild();
			while( !PhoneItemNode.isNull() )
			{
				QDomElement PhoneItem = PhoneItemNode.toElement();
				QString device = PhoneItem.attribute( "phoneDevice" );
				if( device == "Phone" )
				{
					if( PhoneItem.firstChild().nodeType() == QDomNode::TextNode )
						phonenumber = _FU8( PhoneItem.firstChild().toText().data() );
				}
				else if( device == "Cellular" )
				{
					if( PhoneItem.firstChild().nodeType() == QDomNode::TextNode )
						cellularphonenumber = _FU8( PhoneItem.firstChild().toText().data() );
				}

				PhoneItemNode = PhoneItemNode.nextSibling();
			}
		}
		else if( tagName == "Email" )
		{
			QDomNode EmailItemNode = node.toElement().firstChild();
			while( !EmailItemNode.isNull() )
			{
				QDomElement EmailItem = EmailItemNode.toElement();
				QString device = EmailItem.attribute( "emailDevice" );
				if( device == "PC" )
				{
					if( EmailItem.firstChild().nodeType() == QDomNode::TextNode )
						pcemail = _FU8( EmailItem.firstChild().toText().data() );
				}
				else if( device == "Cellular" )
				{
					if( EmailItem.firstChild().nodeType() == QDomNode::TextNode )
						cellularphonemail = _FU8( EmailItem.firstChild().toText().data() );
				}

				EmailItemNode = EmailItemNode.nextSibling();
			}
		}
		else if( tagName == "Extention" )
		{
			QDomNode ExtentionItemNode = node.toElement().firstChild();
			while( !ExtentionItemNode.isNull() )
			{
				QDomElement ExtentionItem = ExtentionItemNode.toElement();
				QString extentionType = ExtentionItem.attribute( "extentionType" );
				if( extentionType == "Common" )
				{
					QString name = ExtentionItem.attribute( "name" );
					if( name == "Suffix" )
					{
						if( ExtentionItem.firstChild().nodeType() == QDomNode::TextNode )
							suffix = _FU8( ExtentionItem.firstChild().toText().data() );
					}				}
				else if( extentionType == "Extended" )
				{
					QString name = ExtentionItem.attribute( "name" );
					if( name == "Group" )
					{
						if( ExtentionItem.firstChild().nodeType() == QDomNode::TextNode )
							group = _FU8( ExtentionItem.firstChild().toText().data() );
					}

				}

				ExtentionItemNode = ExtentionItemNode.nextSibling();
			}
		}

		node = node.nextSibling();
	}

	return new KKContactData( pronunciation,
				fullname,
				suffix,
				group,
				zipcode,
				address1,
				address2,
				pcemail,
				phonenumber,
				cellularphonenumber,
				cellularphonemail );
}

bool ContactXML::writeContactXML( const QString &filename, QPtrList<KKContactData> &datas )
{
	// construct DOM
	QDomDocument doc( DOCUMENT_NAME );
	doc.appendChild( doc.createProcessingInstruction( "xml", "version=\"1.0\" encoding=\"UTF-8\"" ) );

	QDomElement root = doc.createElement( ROOT_ELEM_NAME );
	root.setAttribute( "xmlns", "http://www.xmlns.org/2002/ContactXML" );
	root.setAttribute( "version", "1.1" );
	root.setAttribute( "creator", "KreetingKard" );

	KKContactData *data;
	for ( data = datas.first(); data; data = datas.next() )
		buildContactXMLItem( doc, root, (*data) );

	doc.appendChild( root );

        // write to file
	QFile file( filename );
	if( !file.open( IO_WriteOnly ) )
	{
		return false;
	}
	QTextStream str( &file );
	str << doc;
	file.close();
	return true;
}

void ContactXML::buildContactXMLItem( QDomDocument &doc, QDomElement &root, const KKContactData& data )
{
	QDomElement ContactXMLItem = doc.createElement( "ContactXMLItem" );
		/* Name Part */
		QDomElement PersonName = doc.createElement( "PersonName" );
			QDomElement PersonNameItem = doc.createElement( "PersonNameItem" );
				QDomElement FullName = doc.createElement( "FullName" );
				FullName.setAttribute( "pronunciation", data.getPronunciation().utf8() );
					QDomText name = doc.createTextNode( data.getFullname().utf8() );
				FullName.appendChild( name );
			PersonNameItem.appendChild( FullName );
		PersonName.appendChild( PersonNameItem );

		/* Address Part */
		QDomElement Address = doc.createElement( "Address" );
			QDomElement AddressCode = doc.createElement( "AddressCode" );
			AddressCode.setAttribute( "codeDomain", "ZIP7" );
				QDomText zipcode = doc.createTextNode( data.getZipCode().utf8() );
			AddressCode.appendChild( zipcode );

			QDomElement AddressItem = doc.createElement( "AddressItem" );
//			AddressItem.setAttribute( "locationType", "Home" );
				QDomElement FullAddress = doc.createElement( "FullAddress" );				
					QDomText fulladdress = doc.createTextNode( data.getAddress1().utf8() + "\t" +data.getAddress2().utf8() );
				FullAddress.appendChild( fulladdress );
			AddressItem.appendChild( FullAddress );
		Address.appendChild( AddressCode );
		Address.appendChild( AddressItem );

		/* Phone Part */
		QDomElement Phone = doc.createElement( "Phone" );
			QDomElement PhoneItem_Phone = doc.createElement( "PhoneItem" );
			PhoneItem_Phone.setAttribute( "phoneDevice", "Phone" );
				QDomText phonenumber_phone = doc.createTextNode( data.getPhoneNumber().utf8() );
			PhoneItem_Phone.appendChild( phonenumber_phone );

			QDomElement PhoneItem_Cellular = doc.createElement( "PhoneItem" );
			PhoneItem_Cellular.setAttribute( "phoneDevice", "Cellular" );
				QDomText phonenumber_cellular = doc.createTextNode( data.getCellularPhoneNumber().utf8() );
			PhoneItem_Cellular.appendChild( phonenumber_cellular );
		Phone.appendChild( PhoneItem_Phone );
		Phone.appendChild( PhoneItem_Cellular );

		/* Email Part */
		QDomElement Email = doc.createElement( "Email" );
			QDomElement EmailItem_PC = doc.createElement( "EmailItem" );
			EmailItem_PC.setAttribute( "emailDevice", "PC" );
				QDomText pcaddress = doc.createTextNode( data.getPCEmail().utf8() );
			EmailItem_PC.appendChild( pcaddress );

			QDomElement EmailItem_Cellular = doc.createElement( "EmailItem" );
			EmailItem_Cellular.setAttribute( "emailDevice", "Cellular" );
				QDomText cellularaddress = doc.createTextNode( data.getCellularPhoneEmail().utf8() );
			EmailItem_Cellular.appendChild( cellularaddress );
		Email.appendChild( EmailItem_PC );
		Email.appendChild( EmailItem_Cellular );

		/* Extention Part */
		QDomElement Extention = doc.createElement( "Extention" );
			QDomElement ExtentionItem_Common_Suffix = doc.createElement( "ExtentionItem" );
			ExtentionItem_Common_Suffix.setAttribute( "extentionType", "Common" );
			ExtentionItem_Common_Suffix.setAttribute( "name", "Suffix" );
				QDomText suffix = doc.createTextNode( data.getNameSuffix().utf8() );
			ExtentionItem_Common_Suffix.appendChild( suffix );

			QDomElement ExtentionItem_Extended_Group = doc.createElement( "ExtentionItem" );
			ExtentionItem_Extended_Group.setAttribute( "extentionType", "Extended" );
			ExtentionItem_Extended_Group.setAttribute( "name", "Group" );
				QDomText group = doc.createTextNode( data.getGroup().utf8() );
			ExtentionItem_Extended_Group.appendChild( group );
		Extention.appendChild( ExtentionItem_Common_Suffix );
		Extention.appendChild( ExtentionItem_Extended_Group );

	ContactXMLItem.appendChild( PersonName );
	ContactXMLItem.appendChild( Address );
	ContactXMLItem.appendChild( Phone );
	ContactXMLItem.appendChild( Email );
	ContactXMLItem.appendChild( Extention );

	root.appendChild( ContactXMLItem );
}
