/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.networks;

import android.app.Dialog;
import android.content.Context;
import com.socialize.auth.AuthProviderType;
import com.socialize.concurrent.ManagedAsyncTask;
import com.socialize.i18n.I18NConstants;
import com.socialize.networks.facebook.FacebookUtils;
import com.socialize.networks.twitter.TwitterUtils;
import com.socialize.ui.dialog.ProgressDialogFactory;
import com.socialize.util.IAsyncTask;

import java.lang.ref.WeakReference;

/**
 * @author Jason Polites
 *
 */
public class SocialNetworkSignOutTask extends ManagedAsyncTask<Void, Void, Void> implements IAsyncTask<Void, Void, Void> {

	private WeakReference<Context> context;
	private ProgressDialogFactory dialogFactory;
	private SocialNetworkSignOutListener signOutListener;

	private Dialog dialog;

	private AuthProviderType type;

	public SocialNetworkSignOutTask(Context context) {
		super();
		this.context = new WeakReference<Context>(context);
	}

	@Override
	protected void onPreExecute() {
		dialog = dialogFactory.show(context.get(), I18NConstants.DLG_AUTH_SIGNOUT, I18NConstants.PLEASE_WAIT);
	}

	@Override
	public void doExecute(Void... params) {
		execute(params);
	}

	/* (non-Javadoc)
	 * @see android.os.AsyncTask#doInBackground(Params[])
	 */
	@Override
	protected Void doInBackground(Void... args) {
		switch (type) {
		case FACEBOOK:
			FacebookUtils.unlink(context.get());
			break;
		case TWITTER:
			TwitterUtils.unlink(context.get());
			break;
		}
		return null;
	}

	@Override
	protected void onPostExecuteManaged(Void result) {
		dialog.dismiss();

		if(signOutListener != null) {
			signOutListener.onSignOut();
		}
	}

	public void setDialogFactory(ProgressDialogFactory dialogFactory) {
		this.dialogFactory = dialogFactory;
	}

	public void setSignOutListener(SocialNetworkSignOutListener facebookSignOutListener) {
		this.signOutListener = facebookSignOutListener;
	}

	public void setType(AuthProviderType type) {
		this.type = type;
	}

	public void setType(String type) {
		this.type = AuthProviderType.valueOf(type.toUpperCase().trim());
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.launcher.task;

import android.content.Context;
import android.os.Bundle;
import com.socialize.error.SocializeException;
import com.socialize.launcher.LaunchTask;
import com.socialize.log.SocializeLogger;

import java.util.List;

/**
 * @author Jason Polites
 *
 */
public class NotificationLaunchTask implements LaunchTask {

	private List<LaunchTask> tasks;
	private SocializeLogger logger;

	/* (non-Javadoc)
	 * @see com.socialize.launcher.LaunchTask#execute(android.content.Context, android.os.Bundle)
	 */
	@Override
	public void execute(Context context, Bundle extras) throws SocializeException {
		if(tasks != null) {
			for (LaunchTask task : tasks) {
				try {
					task.execute(context, extras);
				}
				catch (SocializeException e) {
					if(logger != null) {
						logger.error("Error executing launcher task", e);
					}
					else {
						SocializeLogger.e(e.getMessage(), e);
					}
				}
			}
		}
	}

	public void setTasks(List<LaunchTask> tasks) {
		this.tasks = tasks;
	}

	public void setLogger(SocializeLogger logger) {
		this.logger = logger;
	}

}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.demo.implementations.facebook;

import com.socialize.api.SocializeSession;
import com.socialize.auth.AuthProviderType;
import com.socialize.auth.UserProviderCredentials;
import com.socialize.demo.SDKDemoActivity;
import com.socialize.error.SocializeException;
import com.socialize.listener.SocializeAuthListener;
import com.socialize.networks.facebook.FacebookUtils;

/**
 * @author Jason Polites
 *
 */
public class GetTokenActivity extends SDKDemoActivity {

	/* (non-Javadoc)
	 * @see com.socialize.demo.DemoActivity#executeDemo()
	 */
	@Override
	public void executeDemo(String text) {

		FacebookUtils.linkForRead(this, new SocializeAuthListener() {

			@Override
			public void onError(SocializeException error) {
				handleError(GetTokenActivity.this, error);
			}

			@Override
			public void onCancel() {
				handleCancel();
			}

			@Override
			public void onAuthSuccess(SocializeSession session) {
				UserProviderCredentials userProviderCredentials = session.getUserProviderCredentials(AuthProviderType.FACEBOOK);
				handleResult(userProviderCredentials.getAccessToken());
			}

			@Override
			public void onAuthFail(SocializeException error) {
				handleError(GetTokenActivity.this, error);
			}
		});
	}

	@Override
	public boolean isTextEntryRequired() {
		return false;
	}

	/* (non-Javadoc)
	 * @see com.socialize.demo.DemoActivity#getButtonText()
	 */
	@Override
	public String getButtonText() {
		return "Get Access Token";
	}
}


package com.socialize.view;

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.LinearLayout;
import android.widget.Toast;
import com.socialize.Socialize;
import com.socialize.SocializeService;
import com.socialize.error.SocializeErrorHandler;
import com.socialize.log.SocializeLogger;

public abstract class BaseView extends LinearLayout implements SocializeView {

	private SocializeErrorHandler errorHandler;

	private int loadCount = 0;
	private int lastId = 0;

	private boolean rendered = false;

	private Toast toast;

	public BaseView(Context context, AttributeSet attrs) {
		super(context, attrs);
	}

	public BaseView(Context context) {
		super(context);
	}

	public void showErrorToast(Context context, Exception e) {
		if(toast != null) toast.cancel();
		toast = Toast.makeText(context, "Error: " + e.getMessage(), Toast.LENGTH_LONG);
		toast.show();
	}

	public void showError(Context context, Exception e) {
		if(errorHandler != null) {
			errorHandler.handleError(context, e);
		}
		else {
			SocializeLogger.e("", e);
		}
	}

	public SocializeErrorHandler getErrorHandler() {
		return errorHandler;
	}

	public void setErrorHandler(SocializeErrorHandler errorHandler) {
		this.errorHandler = errorHandler;
	}

	protected SocializeService getSocialize() {
		return Socialize.getSocialize();
	}

	/* (non-Javadoc)
	 * @see com.socialize.view.SocializeView#getActivity()
	 */
	@Override
	public Activity getActivity() {
		Context context = getContext();
		if(context instanceof Activity) {
			return (Activity) context;
		}
		return null;
	}

	@Override
	protected void onWindowVisibilityChanged(int visibility) {
		super.onWindowVisibilityChanged(visibility);

		if(!isInEditMode()) {
			if(visibility == VISIBLE) {
				try {
					if(!checkLoaded()) {
						onViewLoad();
					}
					else {
						onViewUpdate();
					}
				}
				catch (Exception e) {
					onViewError(e);
				}
			}
			else {
				rendered = false;
			}
		}
		else {
			// Add the default Socialize View for display
			View editView = getEditModeView();
			if(editView != null) {
				addView(editView);
			}
		}
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		onRender(w, h);
	}

	protected void onRender(int w, int h) {
		if(!rendered) {
			rendered = true;
			try {
				onViewRendered(w, h);
			}
			catch (Exception e) {
				onViewError(e);
			}
		}
	}

	protected void incrementLoaded() {
		loadCount++;
	}

	protected boolean checkLoaded() {
		boolean loaded = (loadCount > 0);
		incrementLoaded();
		return loaded;
	}

	// Subclasses override
	protected View getEditModeView() {
		return null;
	}

	public void assignId(View parent) {
		setId(getNextViewId(parent));
	}

	/* (non-Javadoc)
	 * @see com.socialize.view.SocializeView#onViewUpdate()
	 */
	@Override
	public void onViewUpdate() {}

	/* (non-Javadoc)
	 * @see com.socialize.view.SocializeView#onViewLoad()
	 */
	@Override
	public void onViewLoad() {}

	@Override
	public void onViewError(Exception e) {
		setVisibility(View.GONE);
	}

	/* (non-Javadoc)
	 * @see com.socialize.view.SocializeView#onViewRendered(int, int)
	 */
	@Override
	public void onViewRendered(int width, int height) {}

	protected View getParentView() {
		ViewParent parent = getParent();
		if(parent instanceof View) {
			return (View) parent;
		}
		return this;
	}

	protected int getNextViewId(View parent) {
		if(parent instanceof ViewGroup) {
			ViewGroup group = (ViewGroup) parent;
			int childCount = group.getChildCount();

			if(childCount > 0) {
				int id = 0;

				for (int i = 0; i < childCount; i++) {
					View child = group.getChildAt(i);
					int childId = child.getId();
					if(childId > id) {
						id = childId;
					}
				}

				while(id < lastId) {
					id++;
				}

				lastId = id+1;
				return lastId;
			}
		}

		return ++lastId;
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.ui.comment;

import android.text.util.Linkify;
import android.view.MenuItem;
import com.socialize.entity.Comment;
import com.socialize.error.SocializeException;

import java.util.List;

/**
 * @author Jason Polites
 *
 */
public class LinkifyCommentViewActionListener implements OnCommentViewActionListener {

	int mask = Linkify.ALL;

	public LinkifyCommentViewActionListener() {
		super();
	}

	public LinkifyCommentViewActionListener(int mask) {
		super();
		this.mask = mask;
	}

	/* (non-Javadoc)
	 * @see com.socialize.listener.SocializeListener#onError(com.socialize.error.SocializeException)
	 */
	@Override
	public void onError(SocializeException error) {
	}

	/* (non-Javadoc)
	 * @see com.socialize.ui.comment.OnCommentViewActionListener#onCreate(com.socialize.ui.comment.CommentListView)
	 */
	@Override
	public void onCreate(CommentListView view) {}

	/* (non-Javadoc)
	 * @see com.socialize.ui.comment.OnCommentViewActionListener#onRender(com.socialize.ui.comment.CommentListView)
	 */
	@Override
	public void onRender(CommentListView view) {}

	/* (non-Javadoc)
	 * @see com.socialize.ui.comment.OnCommentViewActionListener#onCommentList(com.socialize.ui.comment.CommentListView, java.util.List, int, int)
	 */
	@Override
	public void onCommentList(CommentListView view, List<Comment> comments, int start, int end) {}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.ui.comment.OnCommentViewActionListener#onBeforeSetComment(com.socialize.entity.Comment, com.socialize.ui.comment.CommentListItem)
	 */
	@Override
	public void onBeforeSetComment(Comment comment, CommentListItem item) {}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.ui.comment.OnCommentViewActionListener#onAfterSetComment(com.socialize.entity.Comment, com.socialize.ui.comment.CommentListItem)
	 */
	@Override
	public void onAfterSetComment(Comment comment, CommentListItem item) {
		Linkify.addLinks(item.getCommentText(), mask);
	}

	/* (non-Javadoc)
	 * @see com.socialize.ui.comment.OnCommentViewActionListener#onReload(com.socialize.ui.comment.CommentListView)
	 */
	@Override
	public void onReload(CommentListView view) {}

	/* (non-Javadoc)
	 * @see com.socialize.ui.comment.OnCommentViewActionListener#onPostComment(com.socialize.entity.Comment)
	 */
	@Override
	public void onPostComment(Comment comment) {}

	@Override
	public boolean onRefreshMenuItemClick(MenuItem item) {
		return false;
	}

	@Override
	public boolean onSettingsMenuItemClick(MenuItem item) {
		return false;
	}

	@Override
	public boolean onCommentIconClicked(CommentListItem item) {
		return false;
	}

	@Override
	public boolean onCommentItemClicked(CommentListItem item) {
		return false;
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.demo.implementations.view;

import com.socialize.ViewUtils;
import com.socialize.demo.SDKDemoActivity;
import com.socialize.entity.View;
import com.socialize.error.SocializeException;
import com.socialize.listener.view.ViewAddListener;

/**
 * @author Jason Polites
 *
 */
public class AddViewActivity extends SDKDemoActivity {

	/* (non-Javadoc)
	 * @see com.socialize.demo.DemoActivity#executeDemo()
	 */
	@Override
	public void executeDemo(String text) {

		// usually the name parameter would be a human readable name (i.e. not the same as the key).
		ViewUtils.view(this, entity, new ViewAddListener() {

			@Override
			public void onError(SocializeException error) {
				handleError(AddViewActivity.this, error);
			}

			@Override
			public void onCreate(View entity) {
				handleSocializeResult(entity);
			}
		});
	}

	@Override
	public boolean isTextEntryRequired() {
		return false;
	}

	/* (non-Javadoc)
	 * @see com.socialize.demo.DemoActivity#getButtonText()
	 */
	@Override
	public String getButtonText() {
		return "Add View";
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.net;

import com.socialize.android.ioc.IBeanFactory;
import com.socialize.config.SocializeConfig;
import com.socialize.error.SocializeException;
import com.socialize.log.SocializeLogger;
import org.apache.http.HttpVersion;
import org.apache.http.client.HttpClient;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;

import java.security.KeyStore;

/**
 * Produces HttpClients with appropriate config.
 * @author Jason Polites
 *
 */
public class DefaultHttpClientFactory implements HttpClientFactory {

	private HttpParams params;

	private ClientConnectionManager connectionManager;

	private SocializeLogger logger;

	private IBeanFactory<DefaultHttpClient> apacheHttpClientFactory;

	private DefaultHttpClient client; // This should be thread safe

	private IdleConnectionMonitorThread monitor;

	private boolean destroyed = false;

	/* (non-Javadoc)
	 * @see com.socialize.net.HttpClientFactory#init()
	 */
	@Override
	public void init(SocializeConfig config) throws SocializeException  {

		try {
			if(logger != null && logger.isDebugEnabled()) {
				logger.debug("Initializing " + getClass().getSimpleName());
			}

	        params = new BasicHttpParams();
	        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
	        HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);

	        HttpConnectionParams.setConnectionTimeout(params, config.getIntProperty(SocializeConfig.HTTP_CONNECTION_TIMEOUT, 10000));
	        HttpConnectionParams.setSoTimeout(params, config.getIntProperty(SocializeConfig.HTTP_SOCKET_TIMEOUT, 10000));

	        SchemeRegistry registry = new SchemeRegistry();
	        registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
	        registry.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));

	        connectionManager = new ThreadSafeClientConnManager(params, registry);

	        monitor = new IdleConnectionMonitorThread(connectionManager);
	        monitor.setDaemon(true);
	        monitor.start();

	        if(logger != null && logger.isDebugEnabled()) {
				logger.debug("Initialized " + getClass().getSimpleName());
			}

	        destroyed = false;
		}
		catch (Exception e) {
			throw new SocializeException(e);
		}
	}

	/* (non-Javadoc)
	 * @see com.socialize.net.HttpClientFactory#destroy()
	 */
	@Override
	public void destroy() {
		if(logger != null && logger.isDebugEnabled()) {
			logger.debug("Destroying " + getClass().getSimpleName());
		}
		if(monitor != null) {
			monitor.shutdown();
		}

		if(connectionManager != null) {
			connectionManager.shutdown();
		}

		if(logger != null && logger.isDebugEnabled()) {
			logger.debug("Destroyed " + getClass().getSimpleName());
		}

		destroyed = true;
	}

	/* (non-Javadoc)
	 * @see com.socialize.net.HttpClientFactory#getClient()
	 */
	@Override
	public synchronized HttpClient getClient() {
		if(client == null) {
			if(apacheHttpClientFactory != null) {
				client = apacheHttpClientFactory.getBean(connectionManager, params);
			}
			else {
				client = new DefaultHttpClient(connectionManager, params);
			}
		}
		else {
			monitor.trigger();
		}
		return client;
	}

	public void setLogger(SocializeLogger logger) {
		this.logger = logger;
	}

	@Override
	public boolean isDestroyed() {
		return destroyed;
	}

	public void setApacheHttpClientFactory(IBeanFactory<DefaultHttpClient> apacheHttpClientFactory) {
		this.apacheHttpClientFactory = apacheHttpClientFactory;
	}

}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.api.action.comment;

import com.socialize.api.SocializeApi;
import com.socialize.api.SocializeSession;
import com.socialize.config.SocializeConfig;
import com.socialize.entity.Comment;
import com.socialize.entity.Entity;
import com.socialize.listener.comment.CommentListener;
import com.socialize.networks.SocialNetwork;
import com.socialize.provider.SocializeProvider;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Jason Polites
 */
public class SocializeCommentSystem extends SocializeApi<Comment, SocializeProvider<Comment>> implements CommentSystem {

	public SocializeCommentSystem(SocializeProvider<Comment> provider) {
		super(provider);
	}

	@Override
	public void addComment(SocializeSession session, Comment comment, CommentOptions commentOptions, CommentListener listener, SocialNetwork... networks) {

		if(commentOptions != null) {
			comment.setNotificationsEnabled(commentOptions.isSubscribeToUpdates());
		}

		setPropagationData(comment, commentOptions, networks);
		setLocation(comment);

		List<Comment> list = new ArrayList<Comment>(1);
		list.add(comment);

		postAsync(session, ENDPOINT, list, listener);
	}

	@Override
	public void deleteComment(SocializeSession session, long id, CommentListener listener) {
		deleteAsync(session, ENDPOINT, String.valueOf(id), listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.CommentSystem#addComment(com.socialize.api.SocializeSession, com.socialize.entity.Entity, java.lang.String, android.location.Location, com.socialize.networks.ShareOptions, com.socialize.listener.comment.CommentListener)
	 */
	@Override
	public void addComment(SocializeSession session, Entity entity, String comment, CommentOptions commentOptions, CommentListener listener, SocialNetwork... networks) {
		Comment c = new Comment();
		c.setText(comment);
		c.setEntitySafe(entity);
		addComment(session, c, commentOptions, listener, networks);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.CommentSystem#getCommentsByEntity(com.socialize.api.SocializeSession, java.lang.String, com.socialize.listener.comment.CommentListener)
	 */
	@Override
	public void getCommentsByEntity(SocializeSession session, String key, CommentListener listener) {
		listAsync(session, ENDPOINT, key, listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.CommentSystem#getCommentsByEntity(com.socialize.api.SocializeSession, java.lang.String, int, int, com.socialize.listener.comment.CommentListener)
	 */
	@Override
	public void getCommentsByEntity(SocializeSession session, String key, int startIndex, int endIndex, CommentListener listener) {
		listAsync(session, ENDPOINT, key, null, null, startIndex, endIndex, listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.comment.CommentSystem#getCommentsByApplication(com.socialize.api.SocializeSession, int, int, com.socialize.listener.comment.CommentListener)
	 */
	@Override
	public void getCommentsByApplication(SocializeSession session, int startIndex, int endIndex, CommentListener listener) {
		listAsync(session, ENDPOINT, null, null, null, startIndex, endIndex, listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.CommentSystem#getCommentsByUser(com.socialize.api.SocializeSession, long, com.socialize.listener.comment.CommentListener)
	 */
	@Override
	public void getCommentsByUser(SocializeSession session, long userId, CommentListener listener) {
		String endpoint = "/user/" + userId + ENDPOINT;
		listAsync(session, endpoint, listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.CommentSystem#getCommentsByUser(com.socialize.api.SocializeSession, long, int, int, com.socialize.listener.comment.CommentListener)
	 */
	@Override
	public void getCommentsByUser(SocializeSession session, long userId, int startIndex, int endIndex, CommentListener listener) {
		String endpoint = "/user/" + userId + ENDPOINT;
		listAsync(session, endpoint, startIndex, endIndex, listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.CommentSystem#getCommentsById(com.socialize.api.SocializeSession, com.socialize.listener.comment.CommentListener, int)
	 */
	@Override
	public void getCommentsById(SocializeSession session, CommentListener listener, long...ids) {
		String[] strIds = new String[ids.length];

		for (int i = 0; i < ids.length; i++) {
			strIds[i] = String.valueOf(ids[i]);
		}

		// No need for pagination here really
		listAsync(session, ENDPOINT, null, 0, SocializeConfig.MAX_LIST_RESULTS, listener, strIds);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.CommentSystem#getComment(com.socialize.api.SocializeSession, long, com.socialize.listener.comment.CommentListener)
	 */
	@Override
	public void getComment(SocializeSession session, long id, CommentListener listener) {
		getAsync(session, ENDPOINT, String.valueOf(id), listener);
	}

}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.launcher;

import android.app.Activity;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.DialogInterface.OnDismissListener;
import android.content.DialogInterface.OnKeyListener;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebView;
import com.socialize.Socialize;
import com.socialize.android.ioc.IBeanFactory;
import com.socialize.log.SocializeLogger;
import com.socialize.ui.dialog.FullScreenDialogFactory;
import com.socialize.ui.notifications.DirectUrlListener;
import com.socialize.ui.notifications.DirectUrlWebView;
import com.socialize.util.DefaultAppUtils;
import com.socialize.util.StringUtils;

/**
 * @author Jason Polites
 *
 */
public class SocializeUrlLauncher extends BaseLauncher implements UrlLauncher {

	private SocializeLogger logger;
	private FullScreenDialogFactory dialogFactory;
	private IBeanFactory<DirectUrlWebView> directUrlWebViewFactory;
	private DirectUrlListener directUrlListener;

	/* (non-Javadoc)
	 * @see com.socialize.launcher.Launcher#launch(android.app.Activity, android.os.Bundle)
	 */
	@Override
	public boolean launch(final Activity context, Bundle data) {
		String url = data.getString(Socialize.DIRECT_URL);

		if(!StringUtils.isEmpty(url)) {

			final DirectUrlWebView webView = directUrlWebViewFactory.getBean();
			webView.setListener(directUrlListener);

			Dialog dialog = dialogFactory.build(context, webView, true);

			dialog.setOnCancelListener(new OnCancelListener() {
				@Override
				public void onCancel(DialogInterface dialog) {
					handleCloseEvent(webView, context);
				}
			});

			dialog.setOnDismissListener(new OnDismissListener() {

				@Override
				public void onDismiss(DialogInterface dialog) {
					handleCloseEvent(webView, context);
				}
			});

			dialog.setOnKeyListener(new OnKeyListener() {
				@Override
				public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
					if(keyCode == KeyEvent.KEYCODE_BACK) {
						if(webView.canGoBack()) {
							webView.goBack();
							return true;
						}
					}
					return false;
				}
			});

			boolean show = true;

			if(directUrlListener != null) {
				show = directUrlListener.onBeforePageLoaded(webView, url);
			}

			if(show) {
				dialog.show();
				webView.loadUrl(url);
			}

			return show;
		}
		else {
			handleWarn("No url found under key [" +
					Socialize.DIRECT_URL +
					"]");
		}

		return false;
	}

	protected void handleCloseEvent(WebView webView, Activity context) {

		if(directUrlListener != null) {
			directUrlListener.onDialogClose();
		}

		if(webView != null) {
			try {
				webView.destroy();
			}
			catch (Throwable ignore) {}
		}

		DefaultAppUtils.launchMainApp(context);
		context.finish();
	}

	protected void handleWarn(String msg) {
		if(logger != null) {
			logger.warn(msg);
		}
		else {
			System.err.println(msg);
		}
	}

	/* (non-Javadoc)
	 * @see com.socialize.launcher.Launcher#shouldFinish()
	 */
	@Override
	public boolean shouldFinish(Activity context) {
		// Don't finish!
		return false;
	}

	@Override
	public boolean isAsync() {
		return false;
	}

	public void setLogger(SocializeLogger logger) {
		this.logger = logger;
	}

	public void setDialogFactory(FullScreenDialogFactory dialogFactory) {
		this.dialogFactory = dialogFactory;
	}

	public void setDirectUrlWebViewFactory(IBeanFactory<DirectUrlWebView> directUrlWebViewFactory) {
		this.directUrlWebViewFactory = directUrlWebViewFactory;
	}

	public void setDirectUrlListener(DirectUrlListener directUrlListener) {
		this.directUrlListener = directUrlListener;
	}

}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize;

import android.app.Activity;
import android.content.Context;
import com.socialize.api.action.user.UserUtilsProxy;
import com.socialize.entity.SocializeAction;
import com.socialize.entity.User;
import com.socialize.error.SocializeException;
import com.socialize.listener.user.UserGetListener;
import com.socialize.listener.user.UserSaveListener;
import com.socialize.log.SocializeLogger;
import com.socialize.networks.SocialNetwork;
import com.socialize.ui.action.OnActionDetailViewListener;
import com.socialize.ui.profile.UserSettings;

import java.lang.reflect.Proxy;

/**
 * @author Jason Polites
 *
 */
public class UserUtils {

	static UserUtilsProxy proxy;

	static {
		proxy = (UserUtilsProxy) Proxy.newProxyInstance(
				UserUtilsProxy.class.getClassLoader(),
				new Class[]{UserUtilsProxy.class},
				new SocializeActionProxy("userUtils"));	// Bean name
	}

	/**
	 * Gets the Social Networks the user has elected to auto-post to.
	 * @param context The current context.
	 * @return An array of SocialNetworks, or null if the user has not elected to auto post to any.
	 */
	public static SocialNetwork[] getAutoPostSocialNetworks(Context context) throws SocializeException {
		return proxy.getAutoPostSocialNetworks(context);
	}

	/**
	 * Returns the current logged in user.  If no user is currently authenticated this will authenticate synchronously.
	 * @param context The current context.
	 * @return The current logged in user
	 * @throws SocializeException
	 */
	public static User getCurrentUser(Context context) throws SocializeException  {
		return proxy.getCurrentUser(context);
	}

	/**
	 * Returns the current logged in user.  If no user is currently authenticated this will authenticate asynchronously.
	 * @param context The current context.
	 * @param listener A listener to handle the result.
	 */
	public static void getCurrentUserAsync(Context context, UserGetListener listener)  {
		proxy.getCurrentUserAsync(context, listener);
	}

	/**
	 * Saves the given user.
	 * @param context The current context.
	 * @param user The user to be saved.
	 * @param listener A listener to handle the result.
	 */
	public static void saveUserAsync(Context context, User user, UserSaveListener listener) {
		proxy.saveUserAsync(context, user, listener);
	}

	/**
	 * Returns the settings for the current user.
	 * @param context The current context.
	 * @return The settings for the current user.
	 */
	public static UserSettings getUserSettings(Context context) throws SocializeException {
		return proxy.getUserSettings(context);
	}

	/**
	 * Retrieves a User based on the given ID.
	 * @param context The current context.
	 * @param id The id of the user.
	 * @param listener A listener to handle the GET.
	 */
	public static void getUser(Context context, long id, UserGetListener listener) {
		proxy.getUser(context, id, listener);
	}

	/**
	 * Shows the user profile UI for the given user.
	 * @param context The current context.
	 * @param user The user for whom the profile will be shown.
	 */
	public static void showUserProfile (Activity context, User user) {
		proxy.showUserProfileView(context, user, null, null);
	}

	/**
	 * Shows the user profile UI for the given user.
	 * @param context The current context.
	 * @param user The user for whom the profile will be shown.
	 * @param action The action (comment/share/like) that was performed.
	 */
	public static void showUserProfileWithAction (Activity context, User user, SocializeAction action) {
		proxy.showUserProfileView(context, user, action, null);
	}

	/**
	 * Shows the user profile UI for the given user.
	 * @param context The current context.
	 * @param user The user for whom the profile will be shown.
	 * @param onActionDetailViewListener A listener to handle UI view events.
	 */
	public static void showUserProfile (Activity context, User user, OnActionDetailViewListener onActionDetailViewListener) {
		proxy.showUserProfileView(context, user, null, onActionDetailViewListener);
	}

	/**
	 * Shows the user profile UI for the given user.
	 * @param context The current context.
	 * @param user The user for whom the profile will be shown.
	 * @param action The action (comment/share/like) that was performed.
	 * @param onActionDetailViewListener A listener to handle UI view events.
	 */
	public static void showUserProfileWithAction (Activity context, User user, SocializeAction action, OnActionDetailViewListener onActionDetailViewListener) {
		proxy.showUserProfileView(context, user, action, onActionDetailViewListener);
	}

	/**
	 * Shows the settings UI for the current user.
	 * @param context The current context.
	 */
	public static void showUserSettings (Activity context)  {
		try {
			proxy.showUserSettingsView(context, UserUtils.getCurrentUser(context).getId());
		}
		catch (SocializeException e) {
			SocializeLogger.e("Error displaying user settings", e);
		}
	}

	/**
	 * Shows the settings UI for the current user.
	 * @param context The current context.
	 * @param requestCode (Optional)  Set as the result on the UserSettings activity.
	 */
	public static void showUserSettingsForResult(Activity context, int requestCode) {
		try {
			proxy.showUserSettingsViewForResult(context, UserUtils.getCurrentUser(context).getId(), requestCode);
		}
		catch (SocializeException e) {
			SocializeLogger.e("Error displaying user settings", e);
		}
	}

	/**
	 * Saves the profile for the given user.
	 * @param context The current context.
	 * @param userSettings The user settings to be saved.
	 * @param listener A listener to handle the save.
	 */
	public static void saveUserSettings (Context context, UserSettings userSettings, UserSaveListener listener) {
		proxy.saveUserSettings(context, userSettings, listener);
	}

	/**
	 * Clears the saved session state for the user.
	 * WARNING: This will wipe any locally saved preferences for this user.
	 * @param context The current context.
	 */
	public static void clearLocalSessionData(Context context) {
		proxy.clearSession(context);
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.launcher;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.socialize.ConfigUtils;
import com.socialize.Socialize;
import com.socialize.SocializeService;
import com.socialize.config.SocializeConfig;
import com.socialize.log.SocializeLogger;

/**
 * @author Jason Polites
 *
 */
public class ActionDelegateLauncher extends BaseLauncher {

	private Launcher actionLauncher;
	private Launcher commentListLauncher;
	private SocializeLogger logger;

	/* (non-Javadoc)
	 * @see com.socialize.launcher.Launcher#launch(android.app.Activity, android.os.Bundle)
	 */
	@Override
	public boolean launch(Activity context, Bundle data) {
		return getLauncher(context).launch(context, data);
	}

	/* (non-Javadoc)
	 * @see com.socialize.launcher.Launcher#onResult(android.app.Activity, int, int, android.content.Intent, android.content.Intent)
	 */
	@Override
	public void onResult(Activity context, int requestCode, int resultCode, Intent returnedIntent, Intent originalIntent) {
		getLauncher(context).onResult(context, requestCode, resultCode, returnedIntent, originalIntent);
	}

	/* (non-Javadoc)
	 * @see com.socialize.launcher.Launcher#shouldFinish()
	 */
	@Override
	public boolean shouldFinish(Activity context) {
		return getLauncher(context).shouldFinish(context);
	}

	public void setActionLauncher(Launcher actionLauncher) {
		this.actionLauncher = actionLauncher;
	}

	public void setCommentListLauncher(Launcher commentListLauncher) {
		this.commentListLauncher = commentListLauncher;
	}

	public void setLogger(SocializeLogger logger) {
		this.logger = logger;
	}

	protected Launcher getLauncher(Context context) {
		try {
			if(getConfig(context).getBooleanProperty(SocializeConfig.SOCIALIZE_SHOW_COMMENT_LIST_ON_NOTIFY, false)) {
				return commentListLauncher;
			}
		}
		catch (Exception e) {
			if(logger != null) {
				logger.error("Failed to inspect socialize config", e);
			}
			else {
				SocializeLogger.e(e.getMessage(), e);
			}
		}

		return actionLauncher;
	}

	// Mockable
	protected SocializeConfig getConfig(Context context) {
		return ConfigUtils.getConfig(context);
	}

	// Mockable
	protected SocializeService getSocialize() {
		return Socialize.getSocialize();
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.entity;

import com.socialize.networks.SocialNetwork;
import com.socialize.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Jason Polites
 */
public class User extends SocializeObject {

	private static final long serialVersionUID = 235116049047552159L;

	private String firstName;
	private String lastName;
	private String username;
	private String description;
	private String location;
	private String smallImageUri;
	private String mediumImageUri;
	private String largeImageUri;
	private Stats stats;
	private List<UserAuthData> authData;
	private String displayName;
	private String profilePicData;

	@Deprecated
	private boolean autoPostToFacebook = false;

	@Deprecated
	private boolean autoPostToTwitter = false;

	@Deprecated
	private boolean shareLocation = true;

	@Deprecated
	private boolean notificationsEnabled = true;

	private String metaData;

	public void update(User user) {
		setFirstName(user.getFirstName());
		setLastName(user.getLastName());
		setUsername(user.getUsername());
		setLocation(user.getLocation());
		setSmallImageUri(user.getSmallImageUri());
		setMediumImageUri(user.getMediumImageUri());
		setLargeImageUri(user.getLargeImageUri());
		setStats(user.getStats());
		setAuthData(user.getAuthData());
		setProfilePicData(user.getProfilePicData());
		setMetaData(user.getMetaData());

		// Set to null to re-create
		displayName = null;
	}

	public String getShortDisplayName() {
		String fname = getFirstName();
		if(!StringUtils.isEmpty(fname)) {
			return fname;
		}
		return getUsername();
	}

	public String getDisplayName() {
		if(displayName == null) {
			String fname = getFirstName();
			String sname = getLastName();
			String uname = getUsername();
			if(!StringUtils.isEmpty(fname)) {
				displayName = fname;

				if(!StringUtils.isEmpty(sname)) {
					displayName += " " + sname;
				}
			}
			else if(!StringUtils.isEmpty(sname)) {
				displayName = sname;
			}
			else if (!StringUtils.isEmpty(uname)) {
				displayName = uname;
			}
		}

		return displayName;
	}

	public String getFirstName() {
		return firstName;
	}
	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}
	public String getLastName() {
		return lastName;
	}
	public void setLastName(String lastName) {
		this.lastName = lastName;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public String getLocation() {
		return location;
	}
	public void setLocation(String location) {
		this.location = location;
	}
	public String getSmallImageUri() {
		return smallImageUri;
	}
	public void setSmallImageUri(String smallImageUri) {
		this.smallImageUri = smallImageUri;
	}
	public String getMediumImageUri() {
		return mediumImageUri;
	}
	public void setMediumImageUri(String mediumImageUri) {
		this.mediumImageUri = mediumImageUri;
	}
	public String getLargeImageUri() {
		return largeImageUri;
	}
	public void setLargeImageUri(String largeImageUri) {
		this.largeImageUri = largeImageUri;
	}
	public Stats getStats() {
		return stats;
	}
	public void setStats(Stats stats) {
		this.stats = stats;
	}

	/**
	 * Base64 encoded image data.
	 * @return
	 */
	public String getProfilePicData() {
		return profilePicData;
	}

	public void setProfilePicData(String profilePicData) {
		this.profilePicData = profilePicData;
	}

	@Deprecated
	public void setDisplayName(String displayName) {
		this.displayName = displayName;
	}

	public List<UserAuthData> getAuthData() {
		return authData;
	}

	public synchronized void addUserAuthData(UserAuthData authData) {
		if(this.authData == null) {
			this.authData = new ArrayList<UserAuthData>(5);
		}
		this.authData.add(authData);
	}

	public void setAuthData(List<UserAuthData> authData) {
		this.authData = authData;
	}

	@Deprecated
	public boolean isAutoPostToFacebook() {
		return autoPostToFacebook;
	}

	@Deprecated
	public void setAutoPostToFacebook(boolean autoPostToFacebook) {
		this.autoPostToFacebook = autoPostToFacebook;
	}

	@Deprecated
	public boolean isAutoPostToTwitter() {
		return autoPostToTwitter;
	}

	@Deprecated
	public void setAutoPostToTwitter(boolean autoPostToTwitter) {
		this.autoPostToTwitter = autoPostToTwitter;
	}

	@Deprecated
	public boolean isNotificationsEnabled() {
		return notificationsEnabled;
	}

	@Deprecated
	public void setNotificationsEnabled(boolean notificationsEnabled) {
		this.notificationsEnabled = notificationsEnabled;
	}

	@Deprecated
	public boolean isShareLocation() {
		return shareLocation;
	}

	@Deprecated
	public void setShareLocation(boolean shareLocation) {
		this.shareLocation = shareLocation;
	}

	public String getMetaData() {
		return metaData;
	}

	public void setMetaData(String metaData) {
		this.metaData = metaData;
	}

	@Override
	public int hashCode() {
		return super.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		return super.equals(obj);
	}

	/**
	 * Sets the auto post preferences for the user.
	 * @param networks
	 * @return true if the new settings differed from the old ones.
	 */
	@Deprecated
	public boolean setAutoPostPreferences(SocialNetwork...networks) {

		boolean tw = isAutoPostToTwitter();
		boolean fb = isAutoPostToFacebook();

		setAutoPostToFacebook(false);
		setAutoPostToTwitter(false);
		if(networks != null) {
			for (SocialNetwork network : networks) {
				if(network.equals(SocialNetwork.FACEBOOK)) {
					setAutoPostToFacebook(true);
				}
				else if(network.equals(SocialNetwork.TWITTER)) {
					setAutoPostToTwitter(true);
				}
			}
		}

		return tw != isAutoPostToTwitter() || fb != isAutoPostToFacebook();
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.auth.twitter;

import com.socialize.auth.AuthProviderInfo;
import com.socialize.auth.AuthProviderType;
import com.socialize.error.SocializeException;
import com.socialize.util.StringUtils;

/**
 * @author Jason Polites
 *
 */
public class TwitterAuthProviderInfo implements AuthProviderInfo {

	private static final long serialVersionUID = 2029759815212317302L;

	private String consumerKey;
	private String consumerSecret;

	/* (non-Javadoc)
	 * @see com.socialize.auth.AuthProviderInfo#getType()
	 */
	@Override
	public AuthProviderType getType() {
		return AuthProviderType.TWITTER;
	}

	/* (non-Javadoc)
	 * @see com.socialize.auth.AuthProviderInfo#validate()
	 */
	@Override
	public void validate() throws SocializeException {
		if(StringUtils.isEmpty(consumerKey)) {
			throw new SocializeException("No twitter consumer key found.");
		}
		if(StringUtils.isEmpty(consumerSecret)) {
			throw new SocializeException("No twitter consumer secret found.");
		}
	}

	@Override
	public boolean isValid() {
		return !StringUtils.isEmpty(consumerKey) && !StringUtils.isEmpty(consumerSecret);
	}

	/* (non-Javadoc)
	 * @see com.socialize.auth.AuthProviderInfo#matches(com.socialize.auth.AuthProviderInfo)
	 */
	@Override
	public boolean matches(AuthProviderInfo info) {
		return this.equals(info);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.auth.AuthProviderInfo#merge(com.socialize.auth.AuthProviderInfo)
	 */
	@Override
	public boolean merge(AuthProviderInfo info) {
		if(info instanceof TwitterAuthProviderInfo) {
			TwitterAuthProviderInfo that = (TwitterAuthProviderInfo) info;
			this.consumerKey = that.consumerKey;
			this.consumerSecret = that.consumerSecret;
			return true;
		}
		return false;
	}

	public String getConsumerKey() {
		return consumerKey;
	}

	public void setConsumerKey(String consumerKey) {
		this.consumerKey = consumerKey;
	}

	public String getConsumerSecret() {
		return consumerSecret;
	}

	public void setConsumerSecret(String consumerSecret) {
		this.consumerSecret = consumerSecret;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((consumerKey == null) ? 0 : consumerKey.hashCode());
		result = prime * result + ((consumerSecret == null) ? 0 : consumerSecret.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		TwitterAuthProviderInfo other = (TwitterAuthProviderInfo) obj;
		if (consumerKey == null) {
			if (other.consumerKey != null)
				return false;
		} else if (!consumerKey.equals(other.consumerKey))
			return false;
		if (consumerSecret == null) {
			if (other.consumerSecret != null)
				return false;
		} else if (!consumerSecret.equals(other.consumerSecret))
			return false;
		return true;
	}

}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.api.action.entity;

import android.app.Activity;
import com.socialize.EntityUtils.SortOrder;
import com.socialize.Socialize;
import com.socialize.entity.Entity;
import com.socialize.error.SocializeException;
import com.socialize.listener.entity.EntityAddListener;
import com.socialize.listener.entity.EntityGetListener;
import com.socialize.listener.entity.EntityListListener;
import com.socialize.log.SocializeLogger;
import com.socialize.ui.SocializeEntityLoader;
import com.socialize.util.DefaultAppUtils;
import com.socialize.util.EntityLoaderUtils;

/**
 * @author Jason Polites
 *
 */
public class SocializeEntityUtils implements EntityUtilsProxy {

	private EntitySystem entitySystem;
	private EntityLoaderUtils entityLoaderUtils;
	private SocializeLogger logger;

	@Override
	public void getEntity(Activity context, long id, EntityGetListener listener) {
		entitySystem.getEntity(Socialize.getSocialize().getSession(), id, listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.entity.EntityUtilsProxy#saveEntity(android.app.Activity, com.socialize.entity.Entity, com.socialize.listener.entity.EntityAddListener)
	 */
	@Override
	public void saveEntity(Activity context, Entity e, EntityAddListener listener) {
		entitySystem.addEntity(Socialize.getSocialize().getSession(), e, listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.entity.EntityUtilsProxy#getEntity(android.app.Activity, java.lang.String, com.socialize.listener.entity.EntityGetListener)
	 */
	@Override
	public void getEntity(Activity context, String key, EntityGetListener listener) {
		entitySystem.getEntity(Socialize.getSocialize().getSession(), key, listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.entity.EntityUtilsProxy#getEntities(android.app.Activity, int, int, com.socialize.listener.entity.EntityListListener)
	 */
	@Override
	public void getEntities(Activity context, int start, int end, SortOrder sortOrder, EntityListListener listener) {
		entitySystem.getEntities(Socialize.getSocialize().getSession(), start, end, sortOrder, listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.api.action.entity.EntityUtilsProxy#getEntities(android.app.Activity, int, int, com.socialize.listener.entity.EntityListListener, java.lang.String[])
	 */
	@Override
	public void getEntities(Activity context, SortOrder sortOrder, EntityListListener listener, String... keys) {
		entitySystem.getEntities(Socialize.getSocialize().getSession(), sortOrder, listener, keys);
	}

	public void setEntitySystem(EntitySystem entitySystem) {
		this.entitySystem = entitySystem;
	}

	public void setEntityLoaderUtils(EntityLoaderUtils entityLoaderUtils) {
		this.entityLoaderUtils = entityLoaderUtils;
	}

	public void setLogger(SocializeLogger logger) {
		this.logger = logger;
	}

	@Override
	public void showEntity(final Activity context, String key, final EntityGetListener listener) {
		getEntity(context, key, new EntityGetListener() {

			@Override
			public void onGet(Entity entity) {
				showEntity(context, entity, listener);
			}

			@Override
			public void onError(SocializeException error) {
				if(listener != null) {
					listener.onError(error);
				}
			}
		});
	}

	@Override
	public void showEntity(final Activity context, long id, final EntityGetListener listener) {
		getEntity(context, id, new EntityGetListener() {

			@Override
			public void onGet(Entity entity) {
				showEntity(context, entity, listener);
			}

			@Override
			public void onError(SocializeException error) {
				if(listener != null) {
					listener.onError(error);
				}
			}
		});
	}

	protected void showEntity(Activity context, Entity entity, EntityGetListener listener) {
		final SocializeEntityLoader entityLoader = entityLoaderUtils.initEntityLoader();

		if(entityLoader != null) {
			if(entityLoader.canLoad(context, entity)) {
				entityLoader.loadEntity(context, entity);
			}
			else {
				if(logger != null && logger.isDebugEnabled()) {
					logger.debug("Entity loader indicates that entity with key [" +
							entity.getKey() +
							"] cannot be loaded.  Redirecting to home activity");
				}

				DefaultAppUtils.launchMainApp(context);
			}
		}
		else {
			if(listener != null) {
				listener.onError(new SocializeException("No entity loader defined"));
			}
		}
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.demo.snippets;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.google.android.gcm.GCMBaseIntentService;
import com.socialize.SmartAlertUtils;

/**
 * @author Jason Polites
 *
 */
public class SmartAlertSnippets extends BroadcastReceiver {
// begin-snippet-0
/*
 * (non-Javadoc)
 * @see android.content.BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)
 */
@Override
public void onReceive(Context context, Intent intent) {
	if(!SmartAlertUtils.handleBroadcastIntent(context, intent)) {
		// Message was NOT handled by Socialize.
	}
}
// end-snippet-0
// begin-snippet-1

public class MyGCMIntentService extends GCMBaseIntentService {

	@Override
	protected void onMessage(Context context, Intent intent) {

		if(!SmartAlertUtils.onMessage(context, intent)) {
			// Your code here
		}
	}

	@Override
	protected void onRegistered(Context context, String registrationId) {

		SmartAlertUtils.onRegister(context, registrationId);

		// Your code here
	}

	@Override
	protected void onUnregistered(Context context, String registrationId) {

		SmartAlertUtils.onUnregister(context, registrationId);

		// Your code here
	}

	@Override
	protected void onError(Context context, String errorId) {

		SmartAlertUtils.onError(context, errorId);

		// Your code here
	}
}
//end-snippet-1
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.auth.facebook;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.widget.Toast;
import com.socialize.auth.AuthProviderResponse;
import com.socialize.error.SocializeException;
import com.socialize.facebook.Facebook;
import com.socialize.listener.AuthProviderListener;
import com.socialize.log.SocializeLogger;
import com.socialize.networks.facebook.FacebookFacade;
import com.socialize.util.DialogFactory;

/**
 * @author Jason Polites
 */
@SuppressWarnings("deprecation")
public class FacebookService {

	private FacebookFacade facebookFacade;
	private AuthProviderListener listener;
	private SocializeLogger logger;
	private String appId;
	private FacebookSessionStore facebookSessionStore;
	private Facebook facebook;
	private DialogFactory dialogFactory;

	public FacebookService() {
		super();
	}

	@Deprecated
	public FacebookService(
			Facebook facebook,
			FacebookSessionStore facebookSessionStore,
			AuthProviderListener listener,
			DialogFactory dialogFactory,
			SocializeLogger logger) {
		super();
		this.facebook = facebook;
		this.facebookSessionStore = facebookSessionStore;
		this.listener = listener;
		this.dialogFactory = dialogFactory;
		this.logger = logger;
	}

	public FacebookService(
			String appId,
			FacebookFacade facebookFacade,
			AuthProviderListener listener,
			SocializeLogger logger) {
		super();
		this.appId = appId;
		this.facebookFacade = facebookFacade;
		this.listener = listener;
		this.logger = logger;
	}

	/**
	 * Authenticates with default permissions and Single Sign On.
	 */
	@Deprecated
	public void authenticate(Activity context) {
		authenticate(context, FacebookFacade.DEFAULT_PERMISSIONS, true, false);
	}

	@Deprecated
	public void authenticate(Activity context, boolean sso) {
		authenticate(context, FacebookFacade.DEFAULT_PERMISSIONS, sso, false);
	}

	@Deprecated
	public void authenticate(Activity context, boolean sso, String...permissions) {
		if(permissions != null && permissions.length > 0) {
			authenticate(context, permissions, sso, false);
		}
		else {
			authenticate(context, FacebookFacade.DEFAULT_PERMISSIONS, sso, false);
		}
	}

	/**
	 * Authenticates with Single Sign On.
	 */
	public void authenticateForRead(Activity context, boolean sso, String[] permissions) {
		authenticate(context, permissions, sso, true);
	}

	public void authenticateForWrite(Activity context, boolean sso, String[] permissions) {
		authenticate(context, permissions, sso, false);
	}

	protected void authenticate(final Activity context, final String[] permissions, final boolean sso, final boolean read) {
		if(facebookFacade != null) {

			facebookFacade.authenticate(context, appId, permissions, sso, read, new AuthProviderListener() {
				@Override
				public void onError(SocializeException error) {
					finish(context);
					if(listener != null) {
						listener.onError(error);
					}
				}

				@Override
				public void onCancel() {
					finish(context);
					if(listener != null) {
						listener.onCancel();
					}
				}

				@Override
				public void onAuthSuccess(AuthProviderResponse response) {
					finish(context);
					if(listener != null) {
						listener.onAuthSuccess(response);
					}
				}

				@Override
				public void onAuthFail(SocializeException error) {
					finish(context);
					if(listener != null) {
						listener.onAuthFail(error);
					}
				}
			});
		}
		else {
			authenticateLegacy(context, permissions, sso);
		}
	}

	@Deprecated
	private void authenticateLegacy(final Activity context, final String[] permissions, final boolean sso) {
		facebookSessionStore.restore(facebook, context);

		FacebookDialogListener facebookDialogListener = new FacebookDialogListener(context, facebook, facebookSessionStore, listener) {

			@Override
			public void onFinish() {
				finish(context);
			}

			@Override
			public void handleError(Throwable error) {
				if(listener != null) {
					listener.onError(new SocializeException(error));
				}
				else {
					doError(context, error, permissions, sso);
				}
			}
		};

		if(sso) {
			facebook.authorize(context, permissions, facebookDialogListener);
		}
		else {
			facebook.authorize(context, permissions, Facebook.FORCE_DIALOG_AUTH, facebookDialogListener);
		}
	}

	// Mockable
	public void finish(Activity context) {
		context.finish();
	}

	public void cancel(Activity context) {
		if(listener != null) {
			listener.onCancel();
		}
		else {
			Toast.makeText(context, "Request cancelled", Toast.LENGTH_SHORT).show();
		}
	}

	public void logout(Activity context) {
		try {
			if(facebookFacade != null) {
				facebookFacade.logout(context);
			}
			else if(facebook != null) { // Legacy
				facebook.logout(context);
			}
		}
		catch (Exception e) {
			if(listener != null) {
				listener.onError(new SocializeException(e));
			}
			else {
				if(logger != null) {
					logger.error(e.getMessage(), e);
				}
				else {
					e.printStackTrace();
				}
			}
		}
	}

	@Deprecated
	public void doError(final Activity context, final Throwable e, final String[] permissions, final boolean sso) {
		context.runOnUiThread(new Runnable() {
			public void run() {
				if(logger != null) {
					logger.error("Facebook error", e);
				}
				else {
					e.printStackTrace();
				}

				doErrorUI(context, e.getMessage(), permissions, sso);
			}
		});
	}

	@Deprecated
	public void doErrorUI(final Activity context, String error, String[] permissions, boolean sso) {
		try {
			makeErrorDialog(context, error, permissions, sso).show();
		}
		catch (Exception e) {
			if(logger != null) {
				logger.error("Facebook error", e);
			}
			else {
				e.printStackTrace();
			}

		}
	}

	@Deprecated
	public AlertDialog makeErrorDialog(final Activity context, String error, final String[] permissions, final boolean sso) {
		AlertDialog.Builder builder = dialogFactory.getAlertDialogBuilder(context);
		builder.setTitle("Oops!");
		builder.setMessage("Oops!\nSomething went wrong...\n[" + error + "]");
		builder.setCancelable(false);
		builder.setPositiveButton("Try again", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.dismiss();
				authenticate((Activity) context, permissions, sso, false);
			}
		});
		builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.dismiss();
				finish((Activity) context);
			}
		});

		return builder.create();
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.demo.implementations.like;

import com.socialize.LikeUtils;
import com.socialize.demo.SDKDemoActivity;
import com.socialize.entity.Like;
import com.socialize.error.SocializeException;
import com.socialize.listener.like.LikeListListener;

import java.util.List;

/**
 * @author Jason Polites
 *
 */
public class GetLikesByEntityActivity extends SDKDemoActivity {

	/* (non-Javadoc)
	 * @see com.socialize.demo.DemoActivity#executeDemo()
	 */
	@Override
	public void executeDemo(String text) {
		LikeUtils.getLikesByEntity(this, entity.getKey(), 0, PAGE_SIZE, new LikeListListener() {
			@Override
			public void onList(List<Like> items, int totalSize) {
				handleSocializeResult(items);
			}

			@Override
			public void onError(SocializeException error) {
				handleError(GetLikesByEntityActivity.this, error);
			}
		});
	}

	@Override
	public boolean isTextEntryRequired() {
		return false;
	}

	/* (non-Javadoc)
	 * @see com.socialize.demo.DemoActivity#getButtonText()
	 */
	@Override
	public String getButtonText() {
		return "List " + PAGE_SIZE + " Likes for Current Entity";
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import com.socialize.listener.SocializeInitListener;
import com.socialize.log.SocializeLogger.LogLevel;
import com.socialize.ui.SocializeActivityLifecycleListener;

/**
 * Singleton helper class to make accessing the socialize service easier.
 * @author Jason Polites
 */
public class Socialize {

	// This will be set during the build process
	public static final String VERSION = "3.1.5";

	public static final String ENTITY_OBJECT = "socialize.entity";
	public static final String ENTITY_ID = "socialize.entity.id";

	public static final String ACTION_ID = "socialize.action.id";
	public static final String ACTION_TYPE = "socialize.action.type";
	public static final String DIRECT_URL = "socialize.direct.url";

	public static final String LOG_KEY = "Socialize";
	public static final String USER_ID = "socialize.user.id";
	public static final String DEFAULT_USER_ICON = "default_user_icon.png";

	public static LogLevel DEFAULT_LOG_LEVEL = LogLevel.WARN;

	static final SocializeServiceImpl instance = new SocializeServiceImpl();

	static SocializeLifecycleListener socializeLifecycleListener;
	static SocializeActivityLifecycleListener socializeActivityLifecycleListener;

	private Socialize() {
		super();
	}

	/**
	 * Initialize Socialize synchronously.  Should not be called from the main UI thread.
	 */
	public static void init(Context context) {
		instance.init(context);
	}

	/**
	 * Initialize Socialize asynchronously.  Can be called from the main UI thread.
	 */
	public static void initAsync(Context context) {
		instance.initAsync(context, null);
	}

	/**
	 * Initialize Socialize asynchronously.  Can be called from the main UI thread.
	 * @param listener A listener which will be called after init.
	 */
	public static void initAsync(Context context, SocializeInitListener listener) {
		instance.initAsync(context, listener);
	}

	/**
	 * Expert only.  Does not normally need to be called.
	 */
	public static void destroy(Context context) {
        instance.destroy();
    }

	/**
	 * Returns the Socialize singleton instance.
	 * @return The Socialize singleton instance.
	 */
	public static SocializeService getSocialize() {
		return instance;
	}

	static Object getBean(String name) {
		return instance.getContainer().getBean(name);
	}

	/**
	 * Called by containing Activities in their onPause() method.
	 */
	public static void onPause(Activity context) {
		instance.onPause(context);

		if(socializeLifecycleListener != null) {
			socializeLifecycleListener.onPause(context);
		}
	}

	/**
	 * Called by containing Activities in their onResume() method.
	 */
	public static void onResume(Activity context) {
		instance.onResume(context);

		if(socializeLifecycleListener != null) {
			socializeLifecycleListener.onResume(context);
		}
	}

	/**
	 * Called by containing Activities in their onCreate() method.
	 */
	public static void onCreate(Activity context, Bundle savedInstanceState) {
		instance.onCreate(context, savedInstanceState);

		if(socializeLifecycleListener != null) {
			socializeLifecycleListener.onCreate(context, savedInstanceState);
		}
	}

	/**
	 * Called by containing Activities in their onDestroy() method.
	 */
	public static void onDestroy(Activity context) {
		instance.onDestroy(context);

		if(socializeLifecycleListener != null) {
			socializeLifecycleListener.onDestroy(context);
		}
	}

    /**
     * Called by containing Activities in their onStart() method.
     */
    public static void onStart(Activity context) {
        instance.onStart(context);

        if(socializeLifecycleListener != null) {
            socializeLifecycleListener.onStart(context);
        }
    }

    /**
     * Called by containing Activities in their onStop() method.
     */
    public static void onStop(Activity context) {
        instance.onStop(context);

        if(socializeLifecycleListener != null) {
            socializeLifecycleListener.onStop(context);
        }
    }

	public static void setSocializeLifecycleListener(SocializeLifecycleListener socializeLifecycleListener) {
		Socialize.socializeLifecycleListener = socializeLifecycleListener;
	}

	public static SocializeActivityLifecycleListener getSocializeActivityLifecycleListener() {
		return socializeActivityLifecycleListener;
	}

	public static void setSocializeActivityLifecycleListener(SocializeActivityLifecycleListener socializeActivityLifecycleListener) {
		Socialize.socializeActivityLifecycleListener = socializeActivityLifecycleListener;
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.util;

import java.lang.reflect.Field;

/**
 * Gets the value of a reflected field.
 * @author Jason
 */
public final class ReflectionUtils {

	/**
	 * Gets the value of the given static field from the given class.
	 * @param fieldName
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings("unchecked")
	public static final <E extends Object> E getStaticField(String fieldName, Class<?> clazz) throws Exception {

		try {
			Field field = clazz.getField(fieldName);

			if(field != null) {
				return (E) field.get(null);
			}

		} catch (Exception e) {
			throw e;
		}

		return null;
	}

	public static final boolean hasStaticField(String fieldName, Class<?> clazz) {
		Field[] fields = clazz.getFields();

		for (Field field : fields) {
			if(field.getName().equals(fieldName)) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Returns the name of the static field that corresponds to the given value
	 * @param value
	 * @param clazz
	 * @return
	 * @throws Exception
	 */
	public static final String getStaticFieldName(Object value, Class<?> clazz) throws Exception {
		Field[] fields = clazz.getFields();
		for (Field field : fields) {
			Object fVal = field.get(null);
			if(fVal != null && fVal.equals(value)) {
				return field.getName();
			}
		}
		return null;
	}

}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.demo.implementations.share;

import com.socialize.ShareUtils;
import com.socialize.demo.SDKDemoActivity;
import com.socialize.entity.ListResult;
import com.socialize.entity.Share;
import com.socialize.error.SocializeException;
import com.socialize.listener.share.ShareGetListener;
import com.socialize.listener.share.ShareListListener;

/**
 * @author Jason Polites
 *
 */
public class GetSharesByIDActivity extends SDKDemoActivity {

	/* (non-Javadoc)
	 * @see com.socialize.demo.DemoActivity#executeDemo()
	 */
	@Override
	public void executeDemo(String text) {

		// We are going to list shares just so we can get the ID for a single share
		// Usually you would NOT do this as you would usually already have an ID (e.g. from a click on a list view)
		ShareUtils.getSharesByEntity(this, entity.getKey(), 0, 1, new ShareListListener() {

			@Override
			public void onList(ListResult<Share> shares) {

				// Use the id from the first share
				if(shares.getTotalCount() > 0) {
					ShareUtils.getShare(GetSharesByIDActivity.this, new ShareGetListener() {
						@Override
						public void onGet(Share share) {
							handleSocializeResult(share);
						}

						@Override
						public void onError(SocializeException error) {
							handleError(GetSharesByIDActivity.this, error);
						}
					}, shares.getItems().get(0).getId());
				}
			}

			@Override
			public void onError(SocializeException error) {
				handleError(GetSharesByIDActivity.this, error);
			}
		});
	}

	@Override
	public boolean isTextEntryRequired() {
		return false;
	}

	/* (non-Javadoc)
	 * @see com.socialize.demo.DemoActivity#getButtonText()
	 */
	@Override
	public String getButtonText() {
		return "Get Last Share by ID";
	}
}


/* Copyright (c) 2008, 2009 Netflix, Matthias Kaeppler
 *
 * 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 com.socialize.oauth.signpost.http;

import com.socialize.oauth.signpost.OAuth;

import java.io.Serializable;
import java.util.*;

/**
 * A multi-map of HTTP request parameters. Each key references a
 * {@link SortedSet} of parameters collected from the request during message
 * signing. Parameter values are sorted as per {@linkplain http
 * ://oauth.net/core/1.0a/#anchor13}. Every key/value pair will be
 * percent-encoded upon insertion. This class has special semantics tailored to
 * being useful for message signing; it's not a general purpose collection class
 * to handle request parameters.
 *
 * @author Matthias Kaeppler
 */
@SuppressWarnings("serial")
public class HttpParameters implements Map<String, SortedSet<String>>, Serializable {

    private TreeMap<String, SortedSet<String>> wrappedMap = new TreeMap<String, SortedSet<String>>();

    public SortedSet<String> put(String key, SortedSet<String> value) {
        return wrappedMap.put(key, value);
    }

    public void merge(HttpParameters other) {
    	wrappedMap.putAll(other.wrappedMap);
    }

    public SortedSet<String> put(String key, SortedSet<String> values, boolean percentEncode) {
        if (percentEncode) {
            remove(key);
            for (String v : values) {
                put(key, v, true);
            }
            return get(key);
        } else {
            return wrappedMap.put(key, values);
        }
    }

    /**
     * Convenience method to add a single value for the parameter specified by
     * 'key'.
     *
     * @param key
     *        the parameter name
     * @param value
     *        the parameter value
     * @return the value
     */
    public String put(String key, String value) {
        return put(key, value, false);
    }

    /**
     * Convenience method to add a single value for the parameter specified by
     * 'key'.
     *
     * @param key
     *        the parameter name
     * @param value
     *        the parameter value
     * @param percentEncode
     *        whether key and value should be percent encoded before being
     *        inserted into the map
     * @return the value
     */
    public String put(String key, String value, boolean percentEncode) {
        SortedSet<String> values = wrappedMap.get(key);
        if (values == null) {
            values = new TreeSet<String>();
            wrappedMap.put(percentEncode ? OAuth.percentEncode(key) : key, values);
        }
        if (value != null) {
            value = percentEncode ? OAuth.percentEncode(value) : value;
            values.add(value);
        }

        return value;
    }

    /**
     * Convenience method to allow for storing null values. {@link #put} doesn't
     * allow null values, because that would be ambiguous.
     *
     * @param key
     *        the parameter name
     * @param nullString
     *        can be anything, but probably... null?
     * @return null
     */
    public String putNull(String key, String nullString) {
        return put(key, nullString);
    }

    public void putAll(Map<? extends String, ? extends SortedSet<String>> m) {
        wrappedMap.putAll(m);
    }

    public void putAll(Map<? extends String, ? extends SortedSet<String>> m, boolean percentEncode) {
        if (percentEncode) {
            for (String key : m.keySet()) {
                put(key, m.get(key), true);
            }
        } else {
            wrappedMap.putAll(m);
        }
    }

    public void putAll(String[] keyValuePairs, boolean percentEncode) {
        for (int i = 0; i < keyValuePairs.length - 1; i += 2) {
            this.put(keyValuePairs[i], keyValuePairs[i + 1], percentEncode);
        }
    }

    /**
     * Convenience method to merge a Map<String, List<String>>.
     *
     * @param m
     *        the map
     */
    public void putMap(Map<String, List<String>> m) {
        for (String key : m.keySet()) {
            SortedSet<String> vals = get(key);
            if (vals == null) {
                vals = new TreeSet<String>();
                put(key, vals);
            }
            vals.addAll(m.get(key));
        }
    }

    public SortedSet<String> get(Object key) {
        return wrappedMap.get(key);
    }

    /**
     * Convenience method for {@link #getFirst(key, false)}.
     *
     * @param key
     *        the parameter name (must be percent encoded if it contains unsafe
     *        characters!)
     * @return the first value found for this parameter
     */
    public String getFirst(Object key) {
        return getFirst(key, false);
    }

    /**
     * Returns the first value from the set of all values for the given
     * parameter name. If the key passed to this method contains special
     * characters, you MUST first percent encode it using
     * {@link OAuth#percentEncode(String)}, otherwise the lookup will fail
     * (that's because upon storing values in this map, keys get
     * percent-encoded).
     *
     * @param key
     *        the parameter name (must be percent encoded if it contains unsafe
     *        characters!)
     * @param percentDecode
     *        whether the value being retrieved should be percent decoded
     * @return the first value found for this parameter
     */
    public String getFirst(Object key, boolean percentDecode) {
        SortedSet<String> values = wrappedMap.get(key);
        if (values == null || values.isEmpty()) {
            return null;
        }
        String value = values.first();
        return percentDecode ? OAuth.percentDecode(value) : value;
    }

    /**
     * Concatenates all values for the given key to a list of key/value pairs
     * suitable for use in a URL query string.
     *
     * @param key
     *        the parameter name
     * @return the query string
     */
    public String getAsQueryString(Object key) {
        StringBuilder sb = new StringBuilder();
        key = OAuth.percentEncode((String) key);
        Set<String> values = wrappedMap.get(key);
        if (values == null) {
            return key + "=";
        }
        Iterator<String> iter = values.iterator();
        while (iter.hasNext()) {
            sb.append(key + "=" + iter.next());
            if (iter.hasNext()) {
                sb.append("&");
            }
        }
        return sb.toString();
    }

    public String getAsHeaderElement(String key) {
        String value = getFirst(key);
        if (value == null) {
            return null;
        }
        return key + "=\"" + value + "\"";
    }

    public boolean containsKey(Object key) {
        return wrappedMap.containsKey(key);
    }

    public boolean containsValue(Object value) {
        for (Set<String> values : wrappedMap.values()) {
            if (values.contains(value)) {
                return true;
            }
        }
        return false;
    }

    public int size() {
        int count = 0;
        for (String key : wrappedMap.keySet()) {
            count += wrappedMap.get(key).size();
        }
        return count;
    }

    public boolean isEmpty() {
        return wrappedMap.isEmpty();
    }

    public void clear() {
        wrappedMap.clear();
    }

    public SortedSet<String> remove(Object key) {
        return wrappedMap.remove(key);
    }

    public Set<String> keySet() {
        return wrappedMap.keySet();
    }

    public Collection<SortedSet<String>> values() {
        return wrappedMap.values();
    }

    public Set<java.util.Map.Entry<String, SortedSet<String>>> entrySet() {
        return wrappedMap.entrySet();
    }
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.config;

import android.content.Context;
import android.os.Bundle;
import com.socialize.error.SocializeException;
import com.socialize.launcher.LaunchTask;

/**
 * @author Jason Polites
 *
 */
public class NotificationsConfigLaunchTask implements LaunchTask {

	private SocializeConfig config;

	/* (non-Javadoc)
	 * @see com.socialize.launcher.SocializeLaunchTask#execute(android.content.Context)
	 */
	@Override
	public void execute(Context context, Bundle extras) throws SocializeException {
		config.setEntityLoaderCheckEnabled(false);
	}

	public void setConfig(SocializeConfig config) {
		this.config = config;
	}
}


/*
 * Copyright (c) 2012 Socialize Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.socialize.cache;

/**
 * @author Jason Polites
 *
 */
public class Key<K extends Comparable<K>> implements Comparable<Key<K>> {

	private long time;
	private K key;

	public Key(K key, long time) {
		this.time = time;
		this.key = key;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.lang.Comparable#compareTo(java.lang.Object)
	 */
	public int compareTo(Key<K> o) {
		if(o != null) {
			if (o.time > time) {
				return -1;
			}
			else if (o.time < time) {
				return 1;
			}
			else if(o.key != null) {
				return o.key.compareTo(key);
			}
			else {
				return 0;
			}
		}

		return 0;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((key == null) ? 0 : key.hashCode());
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Key<K> other = (Key<K>) obj;
		if (key == null) {
			if (other.key != null)
				return false;
		}
		else if (!key.equals(other.key))
			return false;
		return true;
	}

	public String toString() {
		return key.toString();
	}

	public long getTime() {
		return time;
	}

	public K getKey() {
		return key;
	}

	void setTime(long time) {
		this.time = time;
	}
}