/**
 * 
 */
package com.beem.project.beem;

import java.util.LinkedList;
import java.util.List;

import android.app.Activity;
import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

import com.beem.project.beem.service.aidl.IXMPPFacade;

/**
 * @author darisk
 */
public class BeemApplication extends Application {

    private IXMPPFacade mFacade;

    private Context mApplicationContext;
    private Resources mPrivateResources;
    private static BeemApplication mBeemApp;
    private List<Message> mQueue = new LinkedList<Message>();
    private boolean mIsConnected;

    public static BeemApplication getApplication(Activity activity) {
	if (mBeemApp == null) {
	    mBeemApp = new BeemApplication();
	    mBeemApp.mApplicationContext = activity.getApplication();
	    mBeemApp.mPrivateResources = activity.getResources();
	    mBeemApp.onCreate();
	}
	return mBeemApp;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
	// TODO Auto-generated method stub
	super.onConfigurationChanged(newConfig);
    }

    @Override
    public void onCreate() {
	// TODO Auto-generated method stub
	super.onCreate();
	mFacade = null;
    }

    @Override
    public void onLowMemory() {
	// TODO Auto-generated method stub
	super.onLowMemory();
    }

    @Override
    public void onTerminate() {
	// TODO Auto-generated method stub
	super.onTerminate();
    }

    public synchronized void startBeemService() {
	if (!mIsConnected) {
	    Intent intent = new Intent();
	    intent.setComponent(new ComponentName("com.beem.project.beem",
		    "com.beem.project.beem.BeemService"));
	    mApplicationContext.startService(intent);
	    mApplicationContext
		    .bindService(intent, mServConn, BIND_AUTO_CREATE);
	    mIsConnected = true;
	}
    }

    private ServiceConnection mServConn = new ServiceConnection() {

	@Override
	public void onServiceDisconnected(ComponentName name) {
	    mFacade = null;
	    mIsConnected = false;
	}

	@Override
	public void onServiceConnected(ComponentName name, IBinder service) {
	    // TODO Auto-generated method stub
	    mFacade = IXMPPFacade.Stub.asInterface(service);
	    synchronized (mQueue) {
		for (Message msg : mQueue) {
		    msg.sendToTarget();
		}
		mQueue.clear();
	    }
	}
    };

    public synchronized void stopBeemService() {
	if (mIsConnected) {
	    Intent intent = new Intent();
	    intent.setComponent(new ComponentName("com.beem.project.beem",
		    "com.beem.project.beem.BeemService"));
	    mApplicationContext.unbindService(mServConn);
	    mApplicationContext.stopService(intent);
	    mIsConnected = false;
	}
    }

    public IXMPPFacade getXmppFacade() {
	return mFacade;
    }

    public void callWhenServiceConnected(Handler target, Runnable callback) {
	Message msg = Message.obtain(target, callback);
	if (!mIsConnected) {
	    msg.sendToTarget();
	} else {
	    startBeemService();
	    synchronized (mQueue) {
		mQueue.add(msg);
	    }
	}
    }

    /**
     * Indique si on est connecte au service.
     */
    public boolean isConnected() {
	return mIsConnected;
    }

}
