
/*
	Contacts and groups management
*/

// the map containing all the groups and the contacts
var map;
// contains a pairs address:group
var groupsForContacts;
// all contacts are stored here
var allContacts;
// after a couple of seconds it update the page
var contactsIsShowed = false;


/*
	CONTACTS SORTING -----------------------------------------------------------------------
*/
// create an Object with all the contacts sorted and divided by groups
function sortContacts( enumerator )
{
	var contact;
	var displayName;
	var groups;
	var group;
	var groupName;
	var groupNameFounded;
	var address;	
	var i;
	var j;
	var favouritesGroupString = localizatedFavouritesGroupString();
	var othersGroupString = localizatedOthersGroupString();
	
	//console.group( "sortContacts" );
	
	groupsForContacts = {};
	allContacts = new Array();
	
	map = [
		{ id:"group_" + favouritesGroupString, displayName:favouritesGroupString },
		{ id:"group_" + othersGroupString, displayName:othersGroupString} ];
	map[0].contacts = new Array();
	map[1].contacts = new Array();
	groupNameFounded = [ map[0].displayName, map[1].displayName ];
	

	groupNames = [ map[0].id + "_name", map[1].id + "_name" ];
	
	while ( enumerator.moveNext() ) 
	{
		group = null;
      contact = enumerator.get_current();	
		address = getContactAddress( contact );

		if( address.indexOf( "@" ) == -1  )
			continue;

		allContacts.push( contact );
		addContactByAddress( address, contact );
		
		// it retireves the best group of the contact
		groupName = getGroup( contact );
		
		
		// it checks if the current group is a new one
		if( groupNameFounded.indexOf( groupName ) == -1 )
		{
			////console.group( "adding group " + groupName );
			addThisGroupToGroups( groupName, map );			
			////console.groupEnd( "adding group " + groupName );
			groupNameFounded.push( groupName );	
		}
		
		
		// retrieve the correct group for the contact
		for( i = 0; i < map.length - 1; i++ )
			if( map[i].displayName == groupName )
				group = map[i];
		if( group == null )
			group = map[ map.length - 1 ];
		
				
		// it adds the contact to the group 
		////console.log( contact.get_displayName() + " will be placed into ", groupName );		
		addContactToGroup( group, contact );
		groupsForContacts[ address ] = groupName;
		
		addOnContactPresenceUpdated( contact );
	}
	
	//console.groupEnd( "sortContacts" );
	//for( i = 0; i < map.length; i++ ) { //console.dir( map[i] ); }
}

// it returns the correct group for the contact
function getGroup ( contact )
{
	var groupFounded;
	var groupName;
	var groups = contact.get_groups();
	var group ;

	for( var i = 0; i < groups.length; i++)
	{
		group = groups[i];
		groupName = group.get_name();

		if( i == 0 )
			groupFounded = groupName;
			
		// it checks if the contact is a favourite one
		if( groupName == localizatedFavouritesGroupString() )
			return groupName;

		if( groupName.charAt(0) == "!" )
			groupFounded = groupName;
	}
	
	// if the contacts has no-one group, it's a "others" one
	if( groupName == null || groupName == undefined )
		groupName = localizatedOthersGroupString();

	return groupName;
}


function addThisGroupToGroups ( newGroupName, map )
{
	var i;
	var group;
	var groupName;
	var groupNameSimple;
	var newGroupNameSimple;
	var indexAtPlacingGroup = -1;
	var newGroupObject = { id:"group_" + newGroupName, displayName:newGroupName };
	var specialGroup = newGroupName.charAt( 0 ) == "!";
	
	newGroupObject.contacts = new Array();
	// the last group is jumped because is the "others contacts" group
	for( i = 0; i < map.length - 1; i++ )
	{
		group = map[ i ];
		groupName = group.displayName;

		// "Preferiti" must be the first category of the list
		if( groupName == localizatedFavouritesGroupString() )
			continue;
		
		if( specialGroup )
		{
			if( groupName.charAt( 0 ) == "!" )
			{
				newGroupNameSimple = newGroupName.slice( 1, newGroupName.length - 1 );
				groupNameSimple = groupName.slice( 1, groupName.length - 1 );
				
				if( comeBefore( newGroupNameSimple, groupNameSimple, false, true ) )
				{
					////console.log( "before of", groupNameSimple );
					indexAtPlacingGroup = i;
					break;
				}
			}
			else
			{
				////console.log( "this is ! but it's the last" );
				indexAtPlacingGroup = i;
				break;
			}
		}
		else
		{
			if( comeBefore( newGroupName, groupName, false, true ) )
			{
				////console.log( "before of", groupName );
				indexAtPlacingGroup = i;
				break;
			}
		}						
	}
		
	if( indexAtPlacingGroup == -1 )
	{
		////console.log( "just before Altri Contatti" );
		indexAtPlacingGroup = map.length - 1;
	}
	
	map.splice( indexAtPlacingGroup, 0, newGroupObject );
	groupNames.push( "group_" + newGroupName + "_name" );
}


function addContactToGroup ( group, contact )
{
	var i;
	var displayName = contact.get_displayName();
	var contacts = group.contacts;

	for( i = 0; i < contacts.length; i++ )
	{
		if( comeBefore( displayName, contacts[ i ].get_displayName(), true, true ) )
		{
			contacts.splice( i, 0, contact );
			return;
		}
	}

	contacts.push( contact );
}
/*
	END CONTACTS SORTING -----------------------------------------------------------------------
*/


/*
	CONTACTS UPDATING -----------------------------------------------------------------------
*/
function addOnContactPresenceUpdated( contact )
{
	////console.time( "time"+getContactAddress( contact ) );
    contact.add_propertyChanged(
        function(sender, e)
        {
				var presence = contact.get_presence();	
            switch (e.get_propertyName())
            {
                case "DisplayName":
						if( contactsIsShowed )
						{
							//console.warn( contact.get_displayName(), "IGNORED" );
							return;
						}
						// no actions are required, the html page is not yet built!						
                break;
            }
        });

    contact.get_presence().add_propertyChanged(
        function(sender, e)
        {
            var presence = contact.get_presence();

				if( !contactsIsShowed )
					return;

            switch (e.get_propertyName())
            {
                case "Status":
						displayStatus(presence.get_status(), contact);
						showGroupNames();
						
						if( contact.get_isOnline() )
							showContactDiv( null, "contact_" + getContactAddress( contact ) );
						else
							hideContactDiv( null, "contact_" + getContactAddress( contact ) );
                 break;
                case "PersonalMessage":
						displayDisplayName(contact.get_displayName(), contact, presence.get_personalMessage() );
					break;
            }
        });
}



function checkIfThisContactAlreadyExist ( contact )
{
	var i;
	var group;
	var groupDiv;
	var innerStr;
	var contactString;
	var address = getContactAddress( contact );
	var isJustDeleted = false;
	
	for( i = 0; i < contactsDeleted.length; i++ )
	{
		if( contactsDeleted[i] == address )
		{
			isJustDeleted = true;
			break;
		}
	}
	
	if( !isJustDeleted )
		for( i = 0; i < allContacts.length; i++ )
			if( getContactAddress( allContacts[i] ) == address )
				return;

	// it has to manage a new contact
	if( !isJustDeleted )
	{
		//console.warn( address, " is a new contact" );
		
		allContacts.push( contact );
		group = map[ map.length - 1 ];
		group.contacts.push( contact );

		contactString = createContactDivString( contact );

		groupDiv = document.getElementById( "list_" + group.id );
		innerStr = groupDiv.innerHTML;
		innerStr += contactString;
		groupDiv.innerHTML = innerStr;

		addOnContactPresenceUpdated( contact );
		
		addContactByAddress( address, contact );
	}
	else
	{
		//console.warn( address, " has just been deleted" );
		
		contactsDeleted.splice( i, 1 );
		showContactDiv( null, htmlIdFromContact( contact, "contactDiv" ) );		
	}
	
	showContactGroupIfNecessary( address );
}
/*
	END CONTACTS UPDATING -----------------------------------------------------------------------
*/


function numberOfContactsForGroup ( groupId )
{
	var i;
	var j;
	var contact;
	var contactsOnLine = 0;
	
	for( i = 0; i < map.length; i++ )
	{
		if( map[i].id != groupId )
			continue;
			
		for( j = 0; j < map[i].contacts.length; j++ )
		{
			contact = map[i].contacts[ j ];
			if( map[i].contacts[j].get_isOnline() && contactsDeleted.indexOf( getContactAddress( contact ) ) == -1 )
				contactsOnLine++;
		}
		
		break;
	}
	
	return contactsOnLine;
}
