package com.zsoft.SignalA.transport.longpolling;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.json.JSONObject;

import android.util.Log;

import com.turbomanage.httpclient.AsyncCallback;
import com.turbomanage.httpclient.HttpResponse;
import com.turbomanage.httpclient.ParameterMap;
import com.zsoft.SignalA.ConnectionBase;
import com.zsoft.SignalA.ConnectionState;
import com.zsoft.SignalA.SignalAUtils;
import com.zsoft.SignalA.SendCallback;
import com.zsoft.SignalA.Transport.ProcessResult;
import com.zsoft.SignalA.Transport.TransportHelper;
import com.zsoft.parallelhttpclient.ParallelHttpClient;

public class ConnectedState extends StopableStateWithCallback {
	protected static final String TAG = "ConnectedState";
	private Object mCallbackLock = new Object();
	//@SuppressWarnings("unused")
	//private AjaxCallback<JSONObject> mCurrentCallback = null;
	private boolean mUseConnect = true;
	
	public ConnectedState(ConnectionBase connection) {
		super(connection);
	}

	@Override
	public ConnectionState getState() {
		return ConnectionState.Connected;
	}

	@Override
	public void Start() {
	}

	@Override
	public void Stop() {
		mConnection.SetNewState(new DisconnectingState(mConnection));
		super.Stop();
	}

	@Override
	public void Send(final CharSequence text, final SendCallback sendCb) {
		if(DoStop())
		{
			sendCb.OnError(new Exception("Connection is about to close"));
			return; 
		}

	    String url = SignalAUtils.EnsureEndsWith(mConnection.getUrl(), "/");
	    url +=  "send?transport=" + TRANSPORT_NAME;
		try {
			url += "&connectionToken=" + URLEncoder.encode(mConnection.getConnectionToken(), "utf-8");
		} catch (UnsupportedEncodingException e) {
			Log.e(TAG, "Unsupported message encoding error, when encoding connectionToken.");
		}

		AsyncCallback cb = new AsyncCallback() 
		{
            @Override
            public void onComplete(HttpResponse httpResponse) 
            {
            	if(httpResponse.getStatus() == 200)
            	{
					Log.v(TAG, "Message sent: " + text);
					sendCb.OnSent(text);
					
					JSONObject json = JSONHelper.ToJSONObject(httpResponse.getBodyAsString());
					
					if(json!=null && json.length()>0)
            		{
            			mConnection.setMessage(json);
            		}
            	}
				else
				{
					Exception ex = new Exception("Error sending message");
					mConnection.setError(ex);
					sendCb.OnError(ex);
				}
            }
            @Override
            public void onError(Exception ex) {
				mConnection.setError(ex);
				sendCb.OnError(ex);
            }
		};

		ParallelHttpClient httpClient = new ParallelHttpClient();
		ParameterMap params = httpClient.newParams()
		        						.add("data", text.toString());
        httpClient.setMaxRetries(1);
        httpClient.post(url, params, cb);
	}

	@Override
	protected void OnRun() {

		if(DoStop()) return; 

	    String baseUrl = SignalAUtils.EnsureEndsWith(mConnection.getUrl(), "/");
	    String url = "";

	    //if (mConnection.getMessageId() == null)
		if (mUseConnect)
		{
			url += "connect";
			mUseConnect = false;
		}
	    else
	    {
			url += "reconnect";
	    }

//	    url += TransportHelper.GetReceiveQueryString(mConnection, null, TRANSPORT_NAME);
		String connectionData = mConnection.OnSending();
	    url += TransportHelper.GetReceiveQueryString(mConnection, connectionData, TRANSPORT_NAME);

	    AsyncCallback cb = new AsyncCallback() {
            @Override
            public void onComplete(HttpResponse httpResponse) {
    			if(DoStop()) return; 

            	try
            	{
        			if(httpResponse != null && httpResponse.getStatus() == 200)
        			{
                		JSONObject json = JSONHelper.ToJSONObject(httpResponse.getBodyAsString());
                    	if (json!=null)
                   		{
                			ProcessResult result = TransportHelper.ProcessResponse(mConnection, json);

                			if(result.processingFailed)
                			{
                				mConnection.setError(new Exception("Error while proccessing response."));
                				mConnection.SetNewState(new ReconnectingState(mConnection));
                			}
                			else if(result.disconnected)
                			{
	      						mConnection.SetNewState(new DisconnectedState(mConnection));
	    						return;
                			}
                		}
                		else
                		{
						    mConnection.setError(new Exception("Error when calling endpoint. Returncode: " + httpResponse.getStatus()));
							mConnection.SetNewState(new ReconnectingState(mConnection));
                   		}
        			}
            		else
            		{
					    mConnection.setError(new Exception("Error when calling endpoint."));
						mConnection.SetNewState(new ReconnectingState(mConnection));
               		}
            	}
            	finally
            	{
					mIsRunning.set(false);
	
					// Loop if we are still connected
					if(mConnection.getCurrentState() == ConnectedState.this)
						Run();
            	}
            }
            @Override
            public void onError(Exception ex) {
			    mConnection.setError(ex);
				mConnection.SetNewState(new ReconnectingState(mConnection));
            }
	    };

		
		synchronized (mCallbackLock) {
			//mCurrentCallback = cb;
		}

		ParallelHttpClient httpClient = new ParallelHttpClient(baseUrl);
		httpClient.setMaxRetries(1);
		httpClient.setConnectionTimeout(5000);
		httpClient.setReadTimeout(115000);
		ParameterMap params = httpClient.newParams();
		httpClient.post(url, params, cb);
	}

}

@@ -898,45 +898,8 @@
 ll;%0A
-%09private boolean mUseConnect = true;%0A
 %09%0A%09p
@@ -2962,18 +2962,16 @@
 ;%0A%0A%09    
-//
 if (mCon
@@ -3004,27 +3004,50 @@
 null
-)%0A%09%09if (mUseConnect
+ %7C%7C mConnection.getMessageId().length()==0
 )%0A%09%09
@@ -3073,32 +3073,8 @@
 t%22;%0A
-%09%09%09mUseConnect = false;%0A
 %09%09%7D%0A
@@ -3105,17 +3105,12 @@
 += %22
-reconnect
+poll
 %22;%0A%09

use poll instead of reconnect