/*
 * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
 *
 * Copyright @ 2015 Atlassian Pty Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package net.java.sip.communicator.impl.protocol.gibberish;

import net.java.sip.communicator.service.protocol.*;

/**
 * Implements typing notifications for the Gibberish protocol. The operation
 * set would simply mirror all outgoing typing notifications and make them
 * appear as incoming events generated by the contact that we are currently
 * writing a message to.
 *
 * @author Emil Ivov
 */
public class OperationSetTypingNotificationsGibberishImpl
    extends AbstractOperationSetTypingNotifications<ProtocolProviderServiceGibberishImpl>
{

    /**
     * The currently valid persistent presence operation set..
     */
    private OperationSetPersistentPresenceGibberishImpl opSetPersPresence = null;

    /**
     * Creates a new instance of this operation set and keeps the parent
     * provider as a reference.
     *
     * @param provider a ref to the <tt>ProtocolProviderServiceImpl</tt>
     * that created us and that we'll use for retrieving the underlying aim
     * connection.
     * @param opSetPersPresence the currently valid
     * <tt>OperationSetPersistentPresenceGibberishImpl</tt> instance.
     */
    OperationSetTypingNotificationsGibberishImpl(
        ProtocolProviderServiceGibberishImpl provider,
        OperationSetPersistentPresenceGibberishImpl opSetPersPresence)
    {
        super(provider);

        this.opSetPersPresence = opSetPersPresence;
    }

    /**
     * Sends a notification to <tt>notifiedContatct</tt> that we have entered
     * <tt>typingState</tt>.
     *
     * @param notifiedContact the <tt>Contact</tt> to notify
     * @param typingState the typing state that we have entered.
     *
     * @throws java.lang.IllegalStateException if the underlying stack is
     * not registered and initialized.
     * @throws java.lang.IllegalArgumentException if <tt>notifiedContact</tt> is
     * not an instance belonging to the underlying implementation.
     */
    public void sendTypingNotification(Contact notifiedContact, int typingState)
        throws IllegalStateException, IllegalArgumentException
    {
        if( !(notifiedContact instanceof ContactGibberishImpl) )
           throw new IllegalArgumentException(
               "The specified contact is not a Gibberish contact."
               + notifiedContact);


        String userID = notifiedContact.getAddress();

        //if the user id is owr own id, then this message is being routed to us
        //from another instance of the gibberish provider.
        if (userID.equals(this.parentProvider.getAccountID().getUserID()))
        {
            //check who is the provider sending the message
            String sourceUserID = notifiedContact.getProtocolProvider()
                .getAccountID().getUserID();

            //check whether they are in our contact list
            Contact from = opSetPersPresence.findContactByID(sourceUserID);

            //and if not - add them there as volatile.
            if (from == null)
            {
                from = opSetPersPresence.createVolatileContact(sourceUserID);
            }

            //and now fire the message received event.
            fireTypingNotificationsEvent(from, typingState);
        }
        else
        {
            //if userID is not our own, try a check whether another provider
            //has that id and if yes - deliver the message to them.
            ProtocolProviderServiceGibberishImpl gibberishProvider
                = this.opSetPersPresence.findProviderForGibberishUserID(userID);
            if (gibberishProvider != null)
            {
                OperationSetTypingNotificationsGibberishImpl opSetTN
                    = (OperationSetTypingNotificationsGibberishImpl)
                    gibberishProvider.getOperationSet(
                        OperationSetTypingNotifications.class);
                opSetTN.sendTypingNotification(notifiedContact, typingState);
            }
            else
            {
                //if we got here then "to" is simply someone in our contact
                //list so let's just echo the message.
                fireTypingNotificationsEvent(notifiedContact, typingState);
            }
        }
    }

}
