/*
 * Contacts.cpp
 *
 *  Created on: Mar 25, 2011
 *      Author: Anis Kadri
 */

#include "../inc/Contacts.h"

Contacts::Contacts(Web* pWeb) : CordovaCommand(pWeb) {
}

Contacts::~Contacts() {
}

void
Contacts::Run(const String& command) {
	if(!command.IsEmpty()) {
		Uri commandUri;
		commandUri.SetUri(command);
		String method = commandUri.GetHost();
		StringTokenizer strTok(commandUri.GetPath(), L"/");
		if(strTok.GetTokenCount() < 2) {
			AppLogException("Not enough params");
			return;
		}
		strTok.GetNextToken(callbackId);
		// Saving a new contact
		if(method == L"com.cordova.Contacts.save" && !callbackId.IsEmpty()) {
			String contactId;
			strTok.GetNextToken(contactId);
			int cid = -1;
			result r = E_SUCCESS;
			r = Integer::Parse(contactId, cid);
			if(IsFailed(r)) {
				AppLogException("Could not retrieve contact ID");
			}
			AppLogDebug("Method %S callbackId %S contactId %d", method.GetPointer(), callbackId.GetPointer(), cid);
			Create(cid);
		// Finding an exisiting contact by Name/Phone Number/Email
		} else if(method == L"com.cordova.Contacts.find" && !callbackId.IsEmpty()) {
			String filter;
			strTok.GetNextToken(filter);
			AppLogDebug("Method %S callbackId %S filter %S", method.GetPointer(), callbackId.GetPointer(), filter.GetPointer());
			Find(filter);
		} else if(method == L"com.cordova.Contacts.remove" && !callbackId.IsEmpty()) {
			String id;
			strTok.GetNextToken(id);
			AppLogDebug("Method %S callbackId %S ID to remove %S", method.GetPointer(), callbackId.GetPointer(), id.GetPointer());
			Remove(id);
		}

	}
}

void
Contacts::SetNickname(Contact& contact, const int cid) {
	String* value = NULL;
	String eval;
	eval.Format(128, L"navigator.service.contacts.records[%d].nickname", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("nickname: %S", value->GetPointer());
		contact.SetValue(CONTACT_PROPERTY_ID_NICK_NAME, *value);
	}
	delete value;
}

void
Contacts::SetFirstName(Contact& contact, const int cid) {
	String* value = NULL;
	String eval;
	eval.Format(128, L"navigator.service.contacts.records[%d].name.givenName", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("First Name: %S", value->GetPointer());
		contact.SetValue(CONTACT_PROPERTY_ID_FIRST_NAME, *value);
	}
	delete value;
}

void
Contacts::SetLastName(Contact& contact, const int cid) {
	String* value = NULL;
	String eval;
	eval.Format(128, L"navigator.service.contacts.records[%d].name.familyName", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("Last Name: %S", value->GetPointer());
		contact.SetValue(CONTACT_PROPERTY_ID_LAST_NAME, *value);
	}
	delete value;
}

void
Contacts::SetPhoneNumbers(Contact& contact, const int cid) {
	// Getting phone numbers length
	String* lengthStr = NULL;
	String eval;
	eval.Format(128, L"navigator.service.contacts.records[%d].phoneNumbers.length", cid);
	lengthStr = pWeb->EvaluateJavascriptN(eval);
	if(!lengthStr->IsEmpty()) {
		int length;
		result r = Integer::Parse(*lengthStr, length);
		if(IsFailed(r)) {
			AppLogException("Could not get phoneNumbers length");
			return;
		}
		delete lengthStr;
		for(int i = 0 ; i < length ; i++) {
			String* type = NULL;
			String* number = NULL;

			// Getting phone number type
			eval.Clear();
			eval.Format(128, L"navigator.service.contacts.records[%d].phoneNumbers[%d].type", cid, i);
			type = pWeb->EvaluateJavascriptN(eval);

			// Getting phone number
			eval.Clear();
			eval.Format(128, L"navigator.service.contacts.records[%d].phoneNumbers[%d].value", cid, i);
			number = pWeb->EvaluateJavascriptN(eval);

			if(!type->IsEmpty() && !number->IsEmpty()) {
				if(*type == "Home") {
					AppLogDebug("Adding HOME phone number %S", number->GetPointer());
					PhoneNumber phoneNumber(PHONENUMBER_TYPE_HOME, *number);
					contact.AddPhoneNumber(phoneNumber);
				} else if(*type == "Mobile") {
					AppLogDebug("Adding MOBILE phone number %S", number->GetPointer());
					PhoneNumber phoneNumber(PHONENUMBER_TYPE_MOBILE, *number);
					contact.AddPhoneNumber(phoneNumber);
				} else if(*type == "Pager") {
					AppLogDebug("Adding PAGER phone number %S", number->GetPointer());
					PhoneNumber phoneNumber(PHONENUMBER_TYPE_PAGER, *number);
					contact.AddPhoneNumber(phoneNumber);
				} else if(*type == "Work") {
					AppLogDebug("Adding WORK phone number %S", number->GetPointer());
					PhoneNumber phoneNumber(PHONENUMBER_TYPE_WORK, *number);
					contact.AddPhoneNumber(phoneNumber);
				} else if(*type == "Other") {
					AppLogDebug("Adding OTHER phone number %S", number->GetPointer());
					PhoneNumber phoneNumber(PHONENUMBER_TYPE_OTHER, *number);
					contact.AddPhoneNumber(phoneNumber);
				}
			}
			delete type;
			delete number;
		}
	}
}

void
Contacts::SetEmails(Contact& contact, const int cid) {
	// Getting emails length
	String* lengthStr = NULL;
	String eval;
	eval.Format(128, L"navigator.service.contacts.records[%d].emails.length", cid);
	lengthStr = pWeb->EvaluateJavascriptN(eval);
	if(!lengthStr->IsEmpty()) {
		int length;
		result r = Integer::Parse(*lengthStr, length);
		if(IsFailed(r)) {
			AppLogException("Could not get emails length");
			return;
		}
		delete lengthStr;
		for(int i = 0 ; i < length ; i++) {
			String* type = NULL;
			String* address = NULL;

			// Getting email type
			eval.Clear();
			eval.Format(128, L"navigator.service.contacts.records[%d].emails[%d].type", cid, i);
			type = pWeb->EvaluateJavascriptN(eval);

			// Getting email
			eval.Clear();
			eval.Format(128, L"navigator.service.contacts.records[%d].emails[%d].value", cid, i);
			address = pWeb->EvaluateJavascriptN(eval);

			if(!type->IsEmpty() && !address->IsEmpty()) {
				if(*type == "Personal") {
					AppLogDebug("Adding PERSONAL email %S", address->GetPointer());
			        Email email(EMAIL_TYPE_PERSONAL, *address);
			        contact.AddEmail(email);
				} else if(*type == "Work") {
					AppLogDebug("Adding WORK email %S", address->GetPointer());
			        Email email(EMAIL_TYPE_WORK, *address);
			        contact.AddEmail(email);
				} else if(*type == "Other") {
					AppLogDebug("Adding OTHER email %S", address->GetPointer());
			        Email email(EMAIL_TYPE_OTHER, *address);
			        contact.AddEmail(email);
				}
			}
			delete type;
			delete address;
		}
	}
}

void
Contacts::SetUrls(Contact& contact, const int cid) {
	// Getting emails length
	String* lengthStr = NULL;
	String eval;
	eval.Format(128, L"navigator.service.contacts.records[%d].urls.length", cid);
	lengthStr = pWeb->EvaluateJavascriptN(eval);
	if(!lengthStr->IsEmpty()) {
		int length;
		result r = Integer::Parse(*lengthStr, length);
		if(IsFailed(r)) {
			AppLogException("Could not get urls length");
			return;
		}
		delete lengthStr;
		for(int i = 0 ; i < length ; i++) {
			String* type = NULL;
			String* address = NULL;

			// Getting url type
			eval.Clear();
			eval.Format(128, L"navigator.service.contacts.records[%d].urls[%d].type", cid, i);
			type = pWeb->EvaluateJavascriptN(eval);

			// Getting url
			eval.Clear();
			eval.Format(128, L"navigator.service.contacts.records[%d].urls[%d].value", cid, i);
			address = pWeb->EvaluateJavascriptN(eval);

			if(!type->IsEmpty() && !address->IsEmpty()) {
				if(*type == "Personal") {
					AppLogDebug("Adding PERSONAL URL %S", address->GetPointer());
			        Url url(URL_TYPE_PERSONAL, *address);
			        contact.AddUrl(url);
				} else if(*type == "Work") {
					AppLogDebug("Adding WORK URL %S", address->GetPointer());
			        Url url(URL_TYPE_WORK, *address);
			        contact.AddUrl(url);
				} else if(*type == "Other") {
					AppLogDebug("Adding OTHER URL %S", address->GetPointer());
			        Url url(URL_TYPE_OTHER, *address);
			        contact.AddUrl(url);
				}
			}
			delete type;
			delete address;
		}
	}
}

void
Contacts::SetOrganization(Contact& contact, const int cid) {
	// Setting Organization Name
	String* value = NULL;
	String eval;
	eval.Format(128, L"navigator.service.contacts.records[%d].organization.name", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("Organization Name: %S", value->GetPointer());
		contact.SetValue(CONTACT_PROPERTY_ID_COMPANY, *value);
	}
	delete value;

	// Setting Organization Title
	eval.Clear();
	eval.Format(128, L"navigator.service.contacts.records[%d].organization.title", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("Organization Title: %S", value->GetPointer());
		contact.SetValue(CONTACT_PROPERTY_ID_JOB_TITLE, *value);
	}
	delete value;
}
void
Contacts::SetBirthday(Contact& contact, const int cid) {
	String* value;
	String eval;
	int year, month, day;
	DateTime birthday;

	// Setting Year
	eval.Format(128, L"navigator.service.contacts.records[%d].birthday.getFullYear()", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		result r = Integer::Parse(*value, year);
		if(IsFailed(r)) {
			AppLogException("Could not get birthday Year");
			return;
		}
		AppLogDebug("Birthday Year: %S", value->GetPointer());
	}
	delete value;

	// Setting Month
	eval.Clear();
	eval.Format(128, L"navigator.service.contacts.records[%d].birthday.getMonth() + 1", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		result r = Integer::Parse(*value, month);
		if(IsFailed(r)) {
			AppLogException("Could not get birthday Month");
			return;
		}
		AppLogDebug("Birthday Month: %S", value->GetPointer());
	}
	delete value;

	// Setting Day
	eval.Clear();
	eval.Format(128, L"navigator.service.contacts.records[%d].birthday.getDate()", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		result r = Integer::Parse(*value, day);
		if(IsFailed(r)) {
			AppLogException("Could not get birthday Day");
			return;
		}
		AppLogDebug("Birthday Day: %S", value->GetPointer());
	}
	delete value;

	birthday.SetValue(year, month, day);
	contact.SetValue(CONTACT_PROPERTY_ID_BIRTHDAY, birthday);
	AppLogDebug("Birthday %d/%d/%d added", year, month, day);
}

void
Contacts::SetAddress(Contact& contact, const int cid) {
	Address address;
	String* value;
	String eval;
	// Setting Street Address
	eval.Format(128, L"navigator.service.contacts.records[%d].address.streetAddress", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("Street Address: %S", value->GetPointer());
		address.SetStreet(*value);
	}
	delete value;

	// Setting City
	eval.Format(128, L"navigator.service.contacts.records[%d].address.locality", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("City: %S", value->GetPointer());
		address.SetCity(*value);
	}
	delete value;

	// Setting State
	eval.Format(128, L"navigator.service.contacts.records[%d].address.region", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("State: %S", value->GetPointer());
		address.SetState(*value);
	}
	delete value;

	// Setting Postal Code
	eval.Format(128, L"navigator.service.contacts.records[%d].address.postalCode", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("Postal Code: %S", value->GetPointer());
		address.SetPostalCode(*value);
	}
	delete value;

	// Setting Country
	eval.Format(128, L"navigator.service.contacts.records[%d].address.country", cid);
	value = pWeb->EvaluateJavascriptN(eval);
	if(!value->IsEmpty()) {
		AppLogDebug("County: %S", value->GetPointer());
		address.SetPostalCode(*value);
	}
	delete value;

	contact.AddAddress(address);
	AppLogDebug("Address Added");
}

void
Contacts::Create(const int cid) {
	result r = E_SUCCESS;
	Addressbook addressbook;

	r = addressbook.Construct();

	if(IsFailed(r)) {
		AppLogException("Could not create AddressBook");
		return;
	}

	Contact contact;
	SetNickname(contact, cid);
	SetFirstName(contact, cid);
	SetLastName(contact, cid);
	SetPhoneNumbers(contact, cid);
	SetEmails(contact, cid);
	SetUrls(contact, cid);
	SetOrganization(contact, cid);
	SetBirthday(contact, cid);
	SetAddress(contact, cid);

	r = addressbook.AddContact(contact);

	String eval;

	if(IsFailed(r)) {
		AppLogException("Could not add contact");
		eval.Format(128, L"Cordova.callbacks['%S'].fail({message:'%s',code:%d})", callbackId.GetPointer(), r, GetErrorMessage(r));
		pWeb->EvaluateJavascriptN(eval);
	} else {
		AppLogDebug("Contact Successfully Added");
		eval.Format(128, L"Cordova.callbacks['%S'].success({message:'Contact added successfully'})", callbackId.GetPointer());
		AppLogDebug("%S", eval.GetPointer());
		pWeb->EvaluateJavascriptN(eval);
	}
}

void
Contacts::UpdateSearch(Contact* pContact) const {
	// TODO: update this add other fields too (emails, urls, phonenumbers, etc...)
	String eval, displayName, firstName, lastName;
	RecordId recordId = pContact->GetRecordId();
	LongLong test(recordId);
	pContact->GetValue(CONTACT_PROPERTY_ID_DISPLAY_NAME, displayName);
	pContact->GetValue(CONTACT_PROPERTY_ID_FIRST_NAME, firstName);
	pContact->GetValue(CONTACT_PROPERTY_ID_LAST_NAME, lastName);
	eval.Format(256, L"navigator.service.contacts._findCallback({id:'%S', displayName:'%S', name:{firstName:'%S',lastName:'%S'}})",
				test.ToString().GetPointer(),
				displayName.GetPointer(),
				firstName.GetPointer(),
				lastName.GetPointer());
	//AppLogDebug("%S", eval.GetPointer());
	pWeb->EvaluateJavascriptN(eval);
}

void
Contacts::FindByName(const String& filter) {
	Addressbook addressbook;
	Contact* pContact = null;
	IList* pContactList = null;
	IEnumerator* pContactEnum = null;
	String displayName, firstName, lastName;

	result r = addressbook.Construct();
	if(IsFailed(r))
	{
		return;
	}

	// Searching by Email
	pContactList = addressbook.SearchContactsByNameN(filter);
	AppLogDebug("Names Matched %d", pContactList->GetCount());
	pContactEnum = pContactList->GetEnumeratorN();
	while (E_SUCCESS == pContactEnum->MoveNext())
	{
		pContact = (Contact*) pContactEnum->GetCurrent();
		UpdateSearch(pContact);
	}
	delete pContactEnum;
	pContactList->RemoveAll(true);
	delete pContactList;
}
void
Contacts::FindByEmail(const String& filter) {
	Addressbook addressbook;
	Contact* pContact = null;
	IList* pContactList = null;
	IEnumerator* pContactEnum = null;
	String displayName, firstName, lastName;

	result r = addressbook.Construct();
	if(IsFailed(r))
	{
		return;
	}

	// Searching by Email
	pContactList = addressbook.SearchContactsByEmailN(filter);
	AppLogDebug("Emails Matched %d", pContactList->GetCount());
	pContactEnum = pContactList->GetEnumeratorN();
	while (E_SUCCESS == pContactEnum->MoveNext())
	{
		pContact = (Contact*) pContactEnum->GetCurrent();
		UpdateSearch(pContact);
	}
	delete pContactEnum;
	pContactList->RemoveAll(true);
	delete pContactList;
}
void
Contacts::FindByPhoneNumber(const String& filter) {
	Addressbook addressbook;
	Contact* pContact = null;
	IList* pContactList = null;
	IEnumerator* pContactEnum = null;
	String displayName, firstName, lastName;

	result r = addressbook.Construct();
	if(IsFailed(r))
	{
		return;
	}
	// Searching by Email
	pContactList = addressbook.SearchContactsByPhoneNumberN(filter);
	AppLogDebug("Phone Number Matched %d", pContactList->GetCount());
	pContactEnum = pContactList->GetEnumeratorN();
	while (E_SUCCESS == pContactEnum->MoveNext())
	{
		pContact = (Contact*) pContactEnum->GetCurrent();
		UpdateSearch(pContact);
	}
	delete pContactEnum;
	pContactList->RemoveAll(true);
	delete pContactList;
}

void
Contacts::Find(const String& filter) {
	String eval;
	String* value;
	int length = 0;

	// Resetting previous results
	pWeb->EvaluateJavascriptN(L"navigator.service.contacts.results = new Array();");

	// Searching by Name
	FindByName(filter);
	// Searching by PhoneNumber
	FindByPhoneNumber(filter);
	// Searching by Email
	FindByEmail(filter);

	value = pWeb->EvaluateJavascriptN(L"navigator.service.contacts.results.length");
	AppLogDebug("Results length: %S", value->GetPointer());
	result r = Integer::Parse(*value, length);
	if(IsFailed(r)) {
		AppLogException("Could not get Contact Results Length");
		return;
	}

	delete value;
	if(length > 0) {
		eval.Format(128, L"Cordova.callbacks['%S'].success(navigator.service.contacts.results)", callbackId.GetPointer());
		pWeb->EvaluateJavascriptN(eval);
	} else {
		eval.Format(128, L"Cordova.callbacks['%S'].fail({message:'no contacts found',code:00})", callbackId.GetPointer());
		pWeb->EvaluateJavascriptN(eval);
	}
}

void
Contacts::Remove(const String& idStr) {
	String eval;
	Addressbook addressbook;
	RecordId id;
	result r = addressbook.Construct();
	if(IsFailed(r))
	{
		AppLogException("Could not construct Address Book");
		return;
	}
	r = LongLong::Parse(idStr, id);
	if(IsFailed(r)) {
		AppLogException("Could not parse ID");
	} else {
		AppLogDebug("Trying to remove contact with ID %S", idStr.GetPointer());
		r = addressbook.RemoveContact(id);
		if(IsFailed(r)) {
			AppLogDebug("Contact Could not be removed %s %d", GetErrorMessage(r), r);
			eval.Format(256, L"Cordova.callbacks['%S'].fail({message:'%s', code:ContactError.NOT_FOUND_ERROR})",
															 callbackId.GetPointer(), GetErrorMessage(r));
			pWeb->EvaluateJavascriptN(eval);
		} else {
			AppLogDebug("Contact %S removed", idStr.GetPointer());
			eval.Format(256, L"Cordova.callbacks['%S'].success({message:'Contact with ID %d removed', code:01})", callbackId.GetPointer(), id);
			pWeb->EvaluateJavascriptN(eval);
		}
	}
}
