import java.net.*;
/**
 * Klasa interpretujaca wiadomosci przychodzace do master servera.
 * W zaleznosci od wiadomosci podejmuje odpowiednie akcje.
 */
public class MClientStatementInterpreter extends StatementInterpreter
{
	/**
	 * Obiekt glownej klasy master servera. Przy pomocy niego kalasa
	 * komunikuje sie z golwna klasa master servera.
	 */
	private MasterClient mc;
	
	/**
	 * Obiekt interpretowanej wiadomosci.
	 */
	private MClientMessageReader Message;
    
    /**
     * Adres servera z ktorego przyszedl ostatni komunikat.
     */
    private InetAddress AServerAddress;
    private int AServerNr;
    private MClientASConnector ASConnector;
	
    private InetAddress GLServerAddress;
    private int GLServerNr;
    private MClientGLSConnector GLSConnector;
	/**
	 * Konstruktor kalsy.
	 * 
	 * @param ms	obietk master servera
	 */
	public MClientStatementInterpreter(MasterClient mc)
	{
		this.mc = mc;
	}
	
	/**
	 * Metoda interpretujaca wiadomosc.
	 * 
	 * @param Message wiadomowsc do zinterpretowania
	 */
	public void InterpretStatement(MClientMessageReader Message)
	{
	    this.Message = Message;
        
        if (Message.GetPort() == NetSettings.GLServerPort)
        {
            for (int GLServerNr = 0; GLServerNr<mc.GLServerAddresses.length; GLServerNr++)
            {
                if (mc.GLServerAddresses[GLServerNr] != null &&
                    Message.GetAddress().equals(mc.GLServerAddresses[GLServerNr]))
                {
                    GLServerAddress = mc.GLServerAddresses[GLServerNr];
                    this.GLServerNr = GLServerNr;
                    GLSConnector = mc.GetGLSConnector(GLServerNr);
                    if (GLSConnector!=null)
                    {
                        MCLog.MessageLn(MCLog.MESSAGE_DEBUG,
                                      "[MClientStatementInterpreter.InterpretStatement] IN message form " + GLServerNr + " GLS: " +
                                      new StatementToText().GetText(Message.GetStatement()) );
        
		                super.InterpretStatement(Message.GetStatement());
        
                        MCLog.MessageLn(MCLog.MESSAGE_DEBUG,
                                "[MClientStatementInterpreter.InterpretStatement] OUT");
                    }
                }
            }
        }
        else if (Message.GetPort() == NetSettings.AServerPort)
        {
            for (int AServerNr = 0; AServerNr<mc.AServerAddresses.length; AServerNr++)
            {
                //TODO: a co jezeli bedzie null w mc.AServerAddresses[AServerNr]?
                if (mc.AServerAddresses[AServerNr] != null &&
                    Message.GetAddress().equals(mc.AServerAddresses[AServerNr]))
                {
                    AServerAddress = mc.AServerAddresses[AServerNr];
                    this.AServerNr = AServerNr;
                    ASConnector = mc.GetASConnector(AServerNr);
                    if (ASConnector!=null)
                    {
                        MCLog.MessageLn(MCLog.MESSAGE_DEBUG,
                                      "[MClientStatementInterpreter.InterpretStatement] IN message from " + AServerNr +" AS: " +
                                      new StatementToText().GetText(Message.GetStatement()) );
                    
	                    super.InterpretStatement(Message.GetStatement());
                    
                        MCLog.MessageLn(MCLog.MESSAGE_DEBUG,
                                      "[MClientStatementInterpreter.InterpretStatement] OUT");
                    }
                }
            }
        }
	}
    
	protected void Method_S_FREE_ANSWER()
	{
        GLSConnector.SetAnswer(MClientGLSConnector.GLSAnswer_SERVER_FREE_ANSWER);
        GLSConnector.SetAnswered(true);
        GLSConnector.SetFreeAnswer(Message.Data_S_FREE_ANSWER.GetAnswer());
/*        
        mc.GLSAnswer = mc.GLSAnswer_SERVER_FREE_ANSWER;        
        mc.GLServerAnswer = true;
        mc.GLSFreeAnswer = Message.Data_S_FREE_ANSWER.GetAnswer();        
*/        
	}
	
	protected void Method_S_AS_FOUND()
	{
        ASConnector.SetAnswer(MClientASConnector.ASAnswer_SERVER_FOUND);
        ASConnector.SetAnswered(true);
        mc.SetCurrentASConnector(AServerNr);
        
	}
	protected void Method_S_GLS_FOUND()
	{
        GLSConnector.SetAnswer(MClientGLSConnector.GLSAnswer_SERVER_FOUND);
        GLSConnector.SetAnswered(true);
/*        
        mc.GLServerAnswer = true;
        mc.GLSAnswer = mc.GLSAnswer_SERVER_FOUND;        
*/        
	}
    	
	protected void Method_S_GS_LIST()
	{
        GLSConnector.SetAnswered(true);
		if (GLSConnector.GetMessageNr() == Message.Data_S_GS_LIST.GetMessageNr())
			mc.GameServers.AddGameServers(Message);
	}
    
	protected void Method_S_GAME_CREATED()
	{
        GLSConnector.SetState(MClientGLSConnector.GLSState_GS);        
        GLSConnector.SetAnswer(MClientGLSConnector.GLSAnswer_GAME_CREATED);
        GLSConnector.SetAnswered(true);
	}
    
    protected void Method_S_GC_ACTIVITY()
    {
        if (Message.Data_S_GC_ACTIVITY.IsClientActive() == true)
        {
            mc.JoinersList.SetState(Message.Data_S_GC_ACTIVITY.GetClientID(),
                                    MClientJoiner.STATE_ACTIVE,
                                    Message.Data_S_GC_ACTIVITY.GetClientPID());
        }
        else
        {
            mc.JoinersList.SetState(Message.Data_S_GC_ACTIVITY.GetClientID(),
                                    MClientJoiner.STATE_INACTIVE,
                                    Message.Data_S_GC_ACTIVITY.GetClientPID());
        }
		ASConnector.SetAnswered(true);
    }
    
    protected void Method_S_RU_ACTIVE()
    {
        if (Message.Data_S_RU_ACTIVE.GetID() == ASConnector.GetID())
        {
            if (AServerAddress != null)
            {
		        mc.Talker.AddMessageToSend(new MClientMessageComposer(mc.VersionNr,
		        												   Statements.C_IM_ACTIVE,
		        												   AServerAddress,
		        												   NetSettings.AServerPort,
                                                                   ASConnector.GetID()));
            }
        }
    }

	protected void Method_S_YOUR_ID()
 	{
        if (mc.CancelAuthorization == false)
        {
            if (AServerAddress !=null &&
                ASConnector.GetState() == MClientASConnector.ASState_WAITING_AUTHORIZATION)
            {
                ASConnector.SetID(Message.Data_S_YOUR_ID.GetID());
                        
                byte temp[] = mc.CommonPublicKey.Decrypt(Message.Data_S_YOUR_ID.GetN());
                if (temp[temp.length-1] != NetSettings.Digest1 &&
                    temp[temp.length-2] != NetSettings.Digest2)
                    return;
                byte en[] = new byte[temp.length-2];
                int i;
                for (i = 0; i<en.length; i++)
                {
                    en[i] = temp[i];
                }
                        
                temp = mc.CommonPublicKey.Decrypt(Message.Data_S_YOUR_ID.GetE());
                if (temp[temp.length-1] != NetSettings.Digest1 &&
                    temp[temp.length-2] != NetSettings.Digest2)
                    return;
                byte e[] = new byte[temp.length-2];
                for (i =0; i<e.length; i++)
                {
                    e[i] = temp[i];
                }
                        
    		    PublicKey key  = new PublicKey(en,e);
                MClientMessageComposer m = new MClientMessageComposer(mc.VersionNr,
        	    						                              Statements.C_CDKEY,
    		    						                              AServerAddress,
    		    						                              NetSettings.AServerPort);
                m.Get_CDKEY_Data().SetData(ASConnector.GetID(), key.Encrypt(mc.Key));
    		    mc.Talker.AddMessageToSend(m);
                ASConnector.SetState(MClientASConnector.ASState_KEY_SEND);
                mc.Sleep = NetSettings.ActivityTime_FREE;
            }
        }
	}
    
	protected void Method_S_AUTHORIZED()
	{
        if (mc.CancelAuthorization == false)
        {
            ASConnector.SetState(MClientASConnector.ASState_AUTHORIZED);
            ASConnector.SetAnswer(MClientASConnector.ASAnswer_AUTHORIZED);
            ASConnector.SetAnswered(true);
            if (mc.GetCurrentASConnector() == null)
            {
                mc.SetCurrentASConnector(AServerNr);
                mc.Sleep = NetSettings.ActivityTime_IS_GC;
                mc.start();
            }
        }
	}
    
	protected void Method_S_KEY_IN_USE()
	{
        ASConnector.SetAnswerInfo(Message.Data_S_KEY_IN_USE.GetHost());
        ASConnector.SetState(MClientASConnector.ASState_NOT_AUTHORIZED);
        ASConnector.SetAnswer(MClientASConnector.ASAnswer_KEY_IN_USE);
        ASConnector.SetAnswered(true);
        if (mc.GetCurrentASConnector() == null)
            mc.SetCurrentASConnector(AServerNr);
	}
    
	protected void Method_S_INVALID_KEY()
	{
        ASConnector.SetAnswerInfo(Message.Data_S_INVALID_KEY.GetReason());
        ASConnector.SetState(MClientASConnector.ASState_NOT_AUTHORIZED);
        ASConnector.SetAnswer(MClientASConnector.ASAnswer_INVALID_KEY);
        ASConnector.SetAnswered(true);
        if (mc.GetCurrentASConnector() == null)
            mc.SetCurrentASConnector(AServerNr);
	}
}
