/*
 * 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 android.app.Activity;
import com.socialize.api.SocializeSession;
import com.socialize.demo.SDKDemoActivity;
import com.socialize.error.SocializeException;
import com.socialize.listener.SocializeAuthListener;
import com.socialize.networks.SocialNetwork;
import com.socialize.networks.SocialNetworkPostListener;
import com.socialize.networks.facebook.FacebookFacade;
import com.socialize.networks.facebook.FacebookUtils;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

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

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

		if(!FacebookUtils.isLinkedForRead(this, FacebookFacade.READ_PERMISSIONS)) {
			FacebookUtils.linkForRead(this, new SocializeAuthListener() {

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

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

				@Override
				public void onAuthSuccess(SocializeSession session) {
					doPost(text);
				}

				@Override
				public void onAuthFail(SocializeException error) {
					handleError(PostToWallActivity.this, error);
				}
			}, FacebookFacade.READ_PERMISSIONS);
		}
		else {
			doPost(text);
		}
	}

	private void doPost(final String text) {
		FacebookUtils.linkForWrite(this, new SocializeAuthListener() {

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

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

			@Override
			public void onAuthSuccess(SocializeSession session) {

				// Params for a Post at: http://developers.facebook.com/docs/reference/api/post/
				Map<String, Object> postData = new HashMap<String, Object>();
				postData.put("name", "Socialize Test");
				postData.put("link", "http://getsocialize.com");
				postData.put("message", text);

				FacebookUtils.post(PostToWallActivity.this, "me/feed", postData, new SocialNetworkPostListener() {

					@Override
					public void onNetworkError(Activity context, SocialNetwork network, Exception error) {
						handleError(PostToWallActivity.this, error);
					}

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

					@Override
					public void onAfterPost(Activity parent, SocialNetwork socialNetwork, JSONObject responseObject) {
						handleResult(responseObject.toString());
					}
				});
			}

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

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

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


/*
 * 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.facebook;

import com.socialize.android.ioc.Container;
import com.socialize.android.ioc.IBeanMaker;

/**
 * Determines which version of the facebook SDK the user is using and returns the appropriate facade.
 * @author Jason Polites
 */
public class FacebookFacadeFactory implements IBeanMaker {

	private String v2BeanName;
	private String v3BeanName;

	private String beanName;

	/**
	 * Set to true to force FB SDK v2.x
	 */
	static boolean FORCE_V2 = false;

	/* (non-Javadoc)
	 * @see com.socialize.android.ioc.IBeanMaker#getBeanName(java.lang.Object, com.socialize.android.ioc.Container)
	 */
	@Override
	public String getBeanName(Object parent, Container container) {
		if(FORCE_V2) {
			return v2BeanName;
		}

		if(beanName == null) {
			try {
				Class.forName("com.facebook.Session");
				// We assume that if this class exists, we are v3+
				beanName = v3BeanName;
			}
			catch (ClassNotFoundException e) {
				beanName = v2BeanName;
			}
		}

		return beanName;
	}

	public void setV2BeanName(String v2BeanName) {
		this.v2BeanName = v2BeanName;
	}

	public void setV3BeanName(String v3BeanName) {
		this.v3BeanName = v3BeanName;
	}
}


/*
 * 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.oauth;

import com.socialize.oauth.signpost.OAuthConsumer;
import com.socialize.oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;

/**
 * @author Jason Polites
 *
 */
public class CommonsHttpOAuthConsumerFactory implements OAuthConsumerFactory {

	/* (non-Javadoc)
	 * @see com.socialize.oauth.OAuthConsumerFactory#createConsumer(java.lang.String, java.lang.String)
	 */
	@Override
	public OAuthConsumer createConsumer(String key, String secret) {
		return new CommonsHttpOAuthConsumer(key, secret);
	}

}


/*
 * 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 android.app.Activity;
import com.socialize.api.SocializeSession;
import com.socialize.api.action.share.SocialNetworkShareListener;
import com.socialize.demo.SDKDemoActivity;
import com.socialize.error.SocializeException;
import com.socialize.listener.SocializeAuthListener;
import com.socialize.networks.PostData;
import com.socialize.networks.SocialNetwork;
import com.socialize.networks.facebook.FacebookUtils;
import org.json.JSONException;
import org.json.JSONObject;

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

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

		// Link if we need to
		FacebookUtils.linkForWrite(this, new SocializeAuthListener() {

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

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

			@Override
			public void onAuthSuccess(SocializeSession session) {

				// This could be a custom Open Graph path in the form namespace:action
				final String graphPath = "me/og.likes";

				FacebookUtils.postEntity(OpenGraphActivity.this, entity, text, new SocialNetworkShareListener() {
					@Override
					public boolean onBeforePost(Activity parent, SocialNetwork socialNetwork, PostData postData) {

						// Add/Change the contents of the post to fit with open graph
						postData.setPath(graphPath);

						// Facebook like requires an "object" parameter
						postData.getPostValues().put("object", postData.getPropagationInfo().getEntityUrl());

						return false;
					}

					@Override
					public void onNetworkError(Activity context, SocialNetwork network, Exception error) {
						handleError(OpenGraphActivity.this, error);
					}

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

					@Override
					public void onAfterPost(Activity parent, SocialNetwork socialNetwork, JSONObject responseObject) {
						try {
							handleResult(responseObject.toString(4));
						}
						catch (JSONException e) {
							handleError(OpenGraphActivity.this, e);
						}
					}
				});

			}

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

	/* (non-Javadoc)
	 * @see com.socialize.demo.SDKDemoActivity#getButtonText()
	 */
	@Override
	public String getButtonText() {
		return "Facebook Like";
	}

	/* (non-Javadoc)
	 * @see com.socialize.demo.SDKDemoActivity#isTextEntryRequired()
	 */
	@Override
	public boolean isTextEntryRequired() {
		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.config;

import android.content.Context;
import com.socialize.log.ExternalLogger;
import com.socialize.log.SocializeLogger;
import com.socialize.util.ResourceLocator;
import com.socialize.util.StringUtils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;

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

	public static final String SOCIALIZE_PROPERTIES_PATH = "socialize.properties";
	public static final String DEFAULT_PROPERTIES_PATH = "default.socialize.properties";

	public static final String SOCIALIZE_CORE_BEANS_PATH = "socialize_core_beans.xml";
	public static final String SOCIALIZE_UI_BEANS_PATH = "socialize_ui_beans.xml";
	public static final String SOCIALIZE_NOTIFICATION_BEANS_PATH = "socialize_notification_beans.xml";
	public static final String SOCIALIZE_ERRORS_PATH = "socialize.errors.properties";

	public static final String SOCIALIZE_CONSUMER_KEY = "socialize.consumer.key";
	public static final String SOCIALIZE_CONSUMER_SECRET = "socialize.consumer.secret";
	public static final String SOCIALIZE_CHECK_NOTIFICATIONS = "socialize.check.notifications";
	public static final String SOCIALIZE_NOTIFICATION_APP_ICON = "socialize.notification.app.icon";

	/**
	 * Time between duplicate gcm registration requests
	 */
	public static final String GCM_REGISTRATION_INTERVAL = "gcm.registration.interval";
	public static final String GCM_REGISTRATION_ENABLED = "gcm.registration.enabled";

	public static final String SOCIALIZE_NOTIFICATIONS_INTERVAL = "socialize.notification.request.interval";
	public static final String SOCIALIZE_NOTIFICATIONS_ENABLED = "socialize.notification.enabled";

	@Deprecated
	public static final String SOCIALIZE_C2DM_SENDER_ID = "socialize.c2dm.sender.id";

	public static final String SOCIALIZE_GCM_SENDER_ID = "socialize.gcm.sender.id";

	public static final String SOCIALIZE_CUSTOM_GCM_SENDER_ID = "socialize.custom.gcm.sender.id";

	public static final String SOCIALIZE_ENTITY_LOADER = "socialize.entity.loader";

	public static final String SOCIALIZE_LOCATION_ENABLED = "socialize.location.enabled";

	public static final String SOCIALIZE_REQUIRE_AUTH = "socialize.require.auth";

	public static final String SOCIALIZE_EXTERNAL_LOGS_ENABLED = "socialize.external.logs.enabled";

	@Deprecated
	public static final String SOCIALIZE_REQUIRE_SHARE = "socialize.require.share";

	public static final String SOCIALIZE_ALLOW_ANON = "socialize.allow.anon";

	public static final String SOCIALIZE_ALLOW_ANON_COMMENT = "socialize.allow.anon.comments";

	public static final String SOCIALIZE_ALLOW_NEVER_AUTH = "socialize.allow.never.auth";

	public static final String SOCIALIZE_EVENTS_AUTH_ENABLED = "socialize.events.auth.enabled";

	public static final String SOCIALIZE_EVENTS_SHARE_ENABLED = "socialize.events.share.enabled";

	public static final String SOCIALIZE_SHOW_COMMENT_LIST_ON_NOTIFY = "socialize.comments.on.notify";

	public static final String SOCIALIZE_SHOW_COMMENT_HEADER = "socialize.show.comment.header";

	public static final String SOCIALIZE_PROMPT_SHARE = "socialize.prompt.share";

	public static final String SOCIALIZE_ALLOW_DELETE_COMMENT = "socialize.allow.delete.comment";

	public static final String GOOGLE_PLUS_ENABLED = "googleplus.enabled";

    public static final String LOOPY_ENABLED = "loopy.enabled";

	/**
	 * true if Single Sign On is enabled.  Default is true.
	 */
	public static final String FACEBOOK_SSO_ENABLED = "facebook.sso.enabled";

	public static final String FACEBOOK_OG_USE_INBUILT_LIKE = "facebook.og.like.enabled";

	@Deprecated
	public static final String FACEBOOK_PHOTOS_ENABLED = "facebook.photos.enabled";

	public static final String FACEBOOK_APP_ID = "facebook.app.id";

	@Deprecated
	public static final String FACEBOOK_USER_ID = "facebook.user.id";

	@Deprecated
	public static final String FACEBOOK_USER_TOKEN = "facebook.user.token";

	public static final String TWITTER_CONSUMER_KEY = "twitter.consumer.key";
	public static final String TWITTER_CONSUMER_SECRET = "twitter.consumer.secret";

	private Properties properties;
	private SocializeLogger logger;
	private ResourceLocator resourceLocator;

	private String propertiesFileName = SOCIALIZE_PROPERTIES_PATH;

	public static final String LOG_LEVEL = "log.level";
	public static final String LOG_TAG = "log.tag";
	public static final String LOG_THREAD = "log.thread";
	public static final String LOG_MSG = "log.msg.";
	public static final String API_HOST = "api.host";

	public static final String REDIRECT_APP_STORE = "redirect.app.store";

	public static final String HTTP_CONNECTION_TIMEOUT = "http.connection.timeout";
	public static final String HTTP_SOCKET_TIMEOUT = "http.socket.timeout";

	public static final int MAX_LIST_RESULTS = 100;

	public static final String SOCIALIZE_SHARE_COMMENT = "socialize.share.comment";
	public static final String SOCIALIZE_SHARE_IS_HTML = "socialize.share.html";
	public static final String SOCIALIZE_SHARE_MIME_TYPE = "socialize.share.mime";
	public static final String SOCIALIZE_SHARE_LISTENER_KEY = "socialize.share.listener.key";

	private static boolean ENTITY_LOADER_CHECK_ENABLED = true;

	public SocializeConfig() {
		super();
	}

	public SocializeConfig(String propertiesFileName) {
		super();
		this.propertiesFileName = propertiesFileName;
	}

	public void init(Context context) {
		init(context, true);
	}

	/**
	 *
	 * @param context
	 * @param override
	 */
	public void init(Context context, boolean override) {
		InputStream in = null;
		try {
			if(resourceLocator != null) {
				try {
					in = resourceLocator.locateInClassPath(context, DEFAULT_PROPERTIES_PATH);

					if(in != null) {
						Properties old = null;

						if(properties != null) {
							old = properties;
						}

						properties = createProperties();
						properties.load(in);

						trimValues(properties);

						if(old != null) {
							merge(old, null);
						}
					}
					else {
						if(logger != null) {
							logger.error("Could not locate config [" +
									DEFAULT_PROPERTIES_PATH +
									"] in classpath");
						}
					}
				}
				catch (IOException ignore) {
					// No config.. eek!
					ignore.printStackTrace();
				}
				finally {
					if(in != null) {
						in.close();
					}
				}

				if(override) {
					// Look for override
					try {
						in = resourceLocator.locate(context, propertiesFileName);

						if(in != null) {
							Properties overrideProps = createProperties();
							overrideProps.load(in);
							trimValues(overrideProps);
							merge(overrideProps, null);
						}
					}
					catch (IOException ignore) {
						// ignore
					}
					finally {
						if(in != null) {
							in.close();
						}
					}
				}
			}

			if(properties == null) {
				if(logger != null) {
					logger.error(SocializeLogger.NO_CONFIG);
				}
				properties = createProperties();
			}
		}
		catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	protected void trimValues(Properties properties) {
		if(properties != null) {
			Set<Object> keys = properties.keySet();
			if(keys != null) {
				String value = null;
				for (Object key : keys) {
					value = properties.getProperty(key.toString());
					if(value != null) {
						value = value.trim();
						properties.put(key, value);
					}
				}
			}
		}
	}

	/**
	 * Sets a custom property.  This will override settings in socialize.properties.
	 * @param key
	 * @param value
	 */
	public void setProperty(String key, String value) {
		if(properties == null) {
			properties = createProperties();
		}

		if(value != null) {
			value = value.trim();
			properties.put(key, value);
		}
		else {
			properties.remove(key);
		}
	}

	/**
	 * Returns a property from socialize.properties.
	 * @param key
	 * @return
	 */
	public String getProperty(String key) {
		return (properties == null) ? null : properties.getProperty(key);
	}

	public String getProperty(String key, String defaultValue) {
		if(properties == null) {
			return defaultValue;
		}

		String value = properties.getProperty(key);

		if(StringUtils.isEmpty(value)) {
			return defaultValue;
		}

		return value;
	}

	public void destroy() {
		if(properties != null) {
			properties.clear();
		}
	}

	public int getIntProperty(String key, int defaultValue) {
		String val = getProperty(key);
		if(!StringUtils.isEmpty(val)) {
			return Integer.parseInt(val);
		}
		return defaultValue;
	}

	public long getLongProperty(String key, long defaultValue) {
		String val = getProperty(key);
		if(!StringUtils.isEmpty(val)) {
			return Long.parseLong(val);
		}
		return defaultValue;
	}

	public boolean getBooleanProperty(String key, boolean defaultValue) {
		String val = getProperty(key);
		if(!StringUtils.isEmpty(val)) {
			return Boolean.parseBoolean(val);
		}
		return defaultValue;
	}

	/**
	 * Sets the Facebook App ID for Facebook authentication.
	 * @param appId Your Facebook App Id, obtained from https://developers.facebook.com/
	 * @see "https://developers.facebook.com/"
	 */
	public void setFacebookAppId(String appId) {
		setProperty(SocializeConfig.FACEBOOK_APP_ID, appId);
	}

	/**
	 * Sets the Twitter App consumer key/secret pair for Twitter authentication.
	 * @param consumerKey Your Twitter App consumer key, obtained from https://dev.twitter.com/
	 * @param consumerSecret Your Twitter App consumer secret, obtained from https://dev.twitter.com/
	 */
	public void setTwitterKeySecret(String consumerKey, String consumerSecret) {
		setProperty(SocializeConfig.TWITTER_CONSUMER_KEY, consumerKey);
		setProperty(SocializeConfig.TWITTER_CONSUMER_SECRET, consumerSecret);
	}

	/**
	 * Enables/disables Single Sign On for Facebook.
	 * @param enabled True if enabled.  Default is true.
	 */
	public void setFacebookSingleSignOnEnabled(boolean enabled) {
		setProperty(SocializeConfig.FACEBOOK_SSO_ENABLED, String.valueOf(enabled));
	}

	/**
	 * Sets the FB credentials for the current user if available.
	 * @param userId
	 * @param token
	 * @deprecated No longer used. Any values set here will be ignored.  Use FacebookUtils to link a known user.
	 */
	@Deprecated
	public void setFacebookUserCredentials(String userId, String token) {
		setProperty(SocializeConfig.FACEBOOK_USER_ID, userId);
		setProperty(SocializeConfig.FACEBOOK_USER_TOKEN, token);
	}

	@Deprecated
	public boolean isShareRequired() {
		return getBooleanProperty(SOCIALIZE_REQUIRE_SHARE, getBooleanProperty(SOCIALIZE_ALLOW_ANON, false));
	}

	public boolean isAllowSkipAuthOnComments() {
		return getBooleanProperty(SOCIALIZE_ALLOW_ANON_COMMENT, false);
	}

    public boolean isLoopyEnabled() {
        return getBooleanProperty(LOOPY_ENABLED, true);
    }

    public boolean isDiagnosticLoggingEnabled() {
		return getBooleanProperty(SOCIALIZE_EXTERNAL_LOGS_ENABLED, false);
	}

	public void setDiagnosticLoggingEnabled(Context context, boolean enabled) {
		setProperty(SOCIALIZE_EXTERNAL_LOGS_ENABLED, String.valueOf(enabled));
		if(logger != null) {
			if(enabled) {
				logger.destroy();
				logger.init(context, this);
			}
			else {
				ExternalLogger externalLogger = logger.getExternalLogger();
				if(externalLogger != null) {
					externalLogger.destroy();
				}
				logger.setExternalLogger(null);
			}
		}
	}

	public boolean isAllowSkipAuthOnAllActions() {
		return getBooleanProperty(SOCIALIZE_ALLOW_ANON, false);
	}

	public boolean isAllowNeverAuth() {
		return getBooleanProperty(SOCIALIZE_ALLOW_NEVER_AUTH, false);
	}

	public boolean isAllowDeleteComment() {
		return getBooleanProperty(SOCIALIZE_ALLOW_DELETE_COMMENT, false);
	}

	public boolean isShowCommentHeader() {
		return getBooleanProperty(SOCIALIZE_SHOW_COMMENT_HEADER, true);
	}

	public boolean isOGLike() {
		return getBooleanProperty(FACEBOOK_OG_USE_INBUILT_LIKE, false);
	}

	public boolean isGooglePlusEnabled() {
		return getBooleanProperty(GOOGLE_PLUS_ENABLED, true);
	}

	public boolean isNotificationsEnabled() {
		return getBooleanProperty(SOCIALIZE_NOTIFICATIONS_ENABLED, true);
	}

	public boolean isPromptForAuth() {
		return getBooleanProperty(SOCIALIZE_REQUIRE_AUTH, true);
	}

	public boolean isPromptForShare() {
		return getBooleanProperty(SOCIALIZE_PROMPT_SHARE, true);
	}

	/**
	 * Sets the Socialize credentials for your App.
	 * @param consumerKey Your consumer key, obtained via registration at http://getsocialize.com
	 * @param consumerSecret Your consumer secret, obtained via registration at http://getsocialize.com
	 */
	public void setSocializeCredentials(String consumerKey, String consumerSecret) {
		setProperty(SocializeConfig.SOCIALIZE_CONSUMER_KEY, consumerKey);
		setProperty(SocializeConfig.SOCIALIZE_CONSUMER_SECRET, consumerSecret);
	}

	protected String getLocalProperty(String key) {
		return getLocalProperty(key, null);
	}

	protected String getLocalProperty(String key, String defaultValue) {
		String val = properties.getProperty(key);
		if(!StringUtils.isEmpty(val)) {
			return val;
		}
		return defaultValue;
	}

	public void merge(SocializeConfig config) {
		merge(config.getProperties(), null);
	}

	/**
	 * Merge properties into the config.
	 * @param other
	 */
	public void merge(Properties other, Set<String> toBeRemoved) {
		if(properties == null) {
			properties = createProperties();
		}

		if(other != null && other.size() > 0) {
			Set<Entry<Object, Object>> entrySet = other.entrySet();
			for (Entry<Object, Object> entry : entrySet) {
				properties.put(entry.getKey(),  entry.getValue());
			}
		}

		if(toBeRemoved != null && toBeRemoved.size() > 0) {
			for (String key : toBeRemoved) {
				properties.remove(key);
			}
			toBeRemoved.clear();
		}
	}

	public String getDefaultPropertiesFileName() {
		return SOCIALIZE_PROPERTIES_PATH;
	}

	public Properties getProperties() {
		return properties;
	}

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

	public void setResourceLocator(ResourceLocator resourceLocator) {
		this.resourceLocator = resourceLocator;
	}

	protected Properties createProperties() {
		return new Properties();
	}

	public boolean isEntityLoaderCheckEnabled() {
		return ENTITY_LOADER_CHECK_ENABLED;
	}

	protected void setEntityLoaderCheckEnabled(boolean entityLoaderCheckEnabled) {
		ENTITY_LOADER_CHECK_ENABLED = entityLoaderCheckEnabled;
	}
}


/*
 * 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.share;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import com.socialize.Socialize;
import com.socialize.SocializeService;
import com.socialize.api.SocializeApi;
import com.socialize.api.SocializeSession;
import com.socialize.api.action.ShareType;
import com.socialize.auth.AuthProviderType;
import com.socialize.config.SocializeConfig;
import com.socialize.entity.Entity;
import com.socialize.entity.Share;
import com.socialize.entity.SocializeAction;
import com.socialize.error.SocializeException;
import com.socialize.listener.SocializeAuthListener;
import com.socialize.listener.share.ShareListener;
import com.socialize.log.SocializeLogger;
import com.socialize.networks.SocialNetwork;
import com.socialize.networks.SocialNetworkListener;
import com.socialize.provider.SocializeProvider;
import com.socialize.share.ShareHandler;
import com.socialize.share.ShareHandlers;

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

/**
 * @author Jason Polites
 */
public class SocializeShareSystem extends SocializeApi<Share, SocializeProvider<Share>> implements ShareSystem {

	private ShareHandlers shareHandlers;

	private SocializeLogger logger;

    public SocializeShareSystem(SocializeProvider<Share> provider) {
		super(provider);
	}

	@Override
	public boolean canShare(Context context, ShareType shareType) {
		ShareHandler shareHandler = shareHandlers.getShareHandler(shareType);
        return shareHandler != null && shareHandler.isAvailableOnDevice(context);
    }

	@Override
	public void addShare(Context context, SocializeSession session, Entity entity, String text, SocialNetwork network, Location location, ShareListener listener) {
		addShare(context, session, entity, text, null, network, location, listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.ShareSystem#addShare(android.content.Context, com.socialize.api.SocializeSession, com.socialize.entityKey.Entity, java.lang.String, com.socialize.api.action.ShareType, android.location.Location, com.socialize.listener.share.ShareListener)
	 */
	@Override
	public void addShare(Context context, SocializeSession session, Entity entity, String text, ShareType shareType, Location location, ShareListener listener) {
		addShare(context, session, entity, text, shareType, null, location, listener);
	}

	protected void addShare(
			final Context context,
			final SocializeSession session,
			final Entity entity,
			final String text,
			ShareType shareType,
			SocialNetwork network,
			final Location location,
			final ShareListener listener) {

		if(shareType == null) {
			if(network != null) {
				shareType = ShareType.valueOf(network.name().toUpperCase());
			}
			else {
				shareType = ShareType.OTHER;
			}
		}
		else if(network == null) {
			network = SocialNetwork.valueOf(shareType);
		}

		final SocialNetwork fnetwork = network;
		final ShareType fshareType = shareType;

		if(network != null) {
			AuthProviderType authType = AuthProviderType.valueOf(network);
			if(getSocialize().isAuthenticatedForWrite(authType)) {
				addShare(session, entity, text, shareType, location, listener, network);
			}
			else {
				getSocialize().authenticateForWrite(context, authType, new SocializeAuthListener() {
					@Override
					public void onError(SocializeException error) {
						if(listener != null) {
							listener.onError(error);
						}
					}

					@Override
					public void onCancel() {
						// no network
						addShare(session, entity, text, fshareType, location, listener);
					}

					@Override
					public void onAuthSuccess(SocializeSession session) {
						addShare(session, entity, text, fshareType, location, listener, fnetwork);
					}

					@Override
					public void onAuthFail(SocializeException error) {
						if(listener != null) {
							listener.onError(error);
						}
					}
				});
			}
		}
		else {
			// no network
			addShare(session, entity, text, fshareType, location, listener);
		}
	}

	@Override
	public void addShare(Context context, SocializeSession session, Entity entity, String text, ShareType shareType, ShareListener listener, SocialNetwork... network) {
		addShare(session, entity, text, shareType, null, listener, network);
	}

	public void addShare(Context context, SocializeSession session, Entity entity, ShareType shareType, ShareListener listener, SocialNetwork...network) {
		addShare(session, entity, "", shareType, null, listener, network);
	}

	public void addShare(SocializeSession session, Entity entity, String text, ShareType shareType, Location location, ShareListener listener, SocialNetwork...network) {

		if(text == null) {
			text = "";
		}

		Share c = new Share();
		c.setEntitySafe(entity);
		c.setText(text);
		c.setShareType(shareType);

		if(network != null && network.length > 0) {
			ShareOptions shareOptions = new ShareOptions();

			// TODO: Is this needed?
			shareOptions.setShowAuthDialog(true);

			setPropagationData(c, shareOptions, network);
		}
		else if(shareType != null) {
			// Set propagation data for non-network share types
			setPropagationData(c, shareType);
		}

		setLocation(c);

		List<Share> list = new ArrayList<Share>(1);
		list.add(c);

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

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

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareSystem#getSharesByApplication(com.socialize.api.SocializeSession, int, int, com.socialize.listener.share.ShareListener)
	 */
	@Override
	public void getSharesByApplication(SocializeSession session, int startIndex, int endIndex, ShareListener listener) {
		listAsync(session, ENDPOINT, null, null, null, startIndex, endIndex, listener);
	}

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

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

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareSystem#getShare(com.socialize.api.SocializeSession, long, com.socialize.listener.share.ShareListener)
	 */
	@Override
	public void getShare(SocializeSession session, long id, ShareListener listener) {
		getAsync(session, ENDPOINT, String.valueOf(id), listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareSystem#getSharesById(com.socialize.api.SocializeSession, com.socialize.listener.share.ShareListener, long[])
	 */
	@Override
	public void getSharesById(SocializeSession session, ShareListener listener, long... ids) {
		if(ids != null) {
			String[] strIds = new String[ids.length];

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

			listAsync(session, ENDPOINT, null, 0, SocializeConfig.MAX_LIST_RESULTS, listener, strIds);
		}
		else {
			if(listener != null) {
				listener.onError(new SocializeException("No ids supplied"));
			}
		}
	}

	@Override
	public void share(Activity context, SocializeSession session, SocializeAction action, String comment, Location location, ShareType destination, SocialNetworkListener listener) {
		ShareHandler sharer = getSharer(destination);
		if(sharer != null) {
            sharer.handle(context, action, location, comment, listener);
		}
		else {
			if(listener != null) {
				listener.onNetworkError(context, SocialNetwork.valueOf(destination), new SocializeException("Unable to share to [" +
						destination.getDisplayName() +
						"] No sharer defined for type"));

			}

			if(logger != null) {
				logger.warn("Unable to share to [" +
						destination.getDisplayName() +
						"].  No sharer defined for this type.");
			}
		}
	}

	protected ShareHandler getSharer(ShareType destination) {
		ShareHandler sharer = null;

		if(shareHandlers != null) {
			sharer = shareHandlers.getShareHandler(destination);
		}

		if(sharer == null) {
			if(logger != null) {
				logger.warn("No sharer found for network type [" +
						destination.name() +
						"]");
			}
		}
		return sharer;
	}

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

	public void setShareHandlers(ShareHandlers shareHandlers) {
		this.shareHandlers = shareHandlers;
	}

	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.api.action.share;

import android.app.Activity;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.location.Location;
import com.socialize.api.SocializeSession;
import com.socialize.api.action.ShareType;
import com.socialize.api.action.SocializeActionUtilsBase;
import com.socialize.entity.Entity;
import com.socialize.entity.Share;
import com.socialize.entity.User;
import com.socialize.error.SocializeException;
import com.socialize.listener.share.ShareAddListener;
import com.socialize.listener.share.ShareGetListener;
import com.socialize.listener.share.ShareListListener;
import com.socialize.networks.PostData;
import com.socialize.networks.SocialNetwork;
import com.socialize.networks.SocialNetworkListener;
import com.socialize.ui.auth.AuthDialogListener;
import com.socialize.ui.auth.AuthPanelView;
import com.socialize.ui.auth.IAuthDialogFactory;
import com.socialize.ui.dialog.SafeProgressDialog;
import com.socialize.ui.share.DialogFlowController;
import com.socialize.ui.share.IShareDialogFactory;
import com.socialize.ui.share.ShareDialogListener;
import com.socialize.ui.share.SharePanelView;
import org.json.JSONObject;

/**
 * @author Jason Polites
 */
public class SocializeShareUtils extends SocializeActionUtilsBase implements ShareUtilsProxy {

	private ShareSystem shareSystem;
	private IShareDialogFactory shareDialogFactory;
	private IAuthDialogFactory authDialogFactory;

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#getUserShareOptions(android.content.Context)
	 */
	@Override
	public ShareOptions getUserShareOptions(Context context) {
		ShareOptions options = new ShareOptions();
		populateActionOptions(context, options);
		return options;
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#showLinkDialog(android.app.Activity, com.socialize.ui.auth.AuthDialogListener)
	 */
	@Override
	public void showLinkDialog(Activity context, AuthDialogListener listener) {
		authDialogFactory.show(context, listener, !config.isAllowSkipAuthOnAllActions());
	}

	@Override
	public void preloadShareDialog(Activity context) {
		shareDialogFactory.preload(context);
	}

	@Override
	public void preloadLinkDialog(Activity context) {
		authDialogFactory.preload(context);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#showShareDialog(android.app.Activity, com.socialize.entity.Entity, int, com.socialize.api.action.share.SocialNetworkShareListener, com.socialize.ui.share.ShareDialogListener)
	 */
	@Override
	public void showShareDialog(final Activity context, final Entity entity, int options, final SocialNetworkShareListener socialNetworkListener, final ShareDialogListener dialogListener) {
		shareDialogFactory.show(context, entity, socialNetworkListener, new ShareDialogListener() {

			SharePanelView dialogView;

			@Override
			public void onCancel(Dialog dialog) {
				if(dialogListener != null) {
					dialogListener.onCancel(dialog);
				}
			}

			@Override
			public void onShow(Dialog dialog, SharePanelView dialogView) {
				if(dialogListener != null) {
					dialogListener.onShow(dialog, dialogView);
				}
				this.dialogView = dialogView;
			}

			@Override
			public void onSimpleShare(ShareType type) {
				if(dialogListener != null) {
					dialogListener.onSimpleShare(type);
				}
			}

			@Override
			public void onFlowInterrupted(DialogFlowController controller) {
				// Will not be called.
			}

			@Override
			public boolean onContinue(final Dialog dialog, boolean remember, final SocialNetwork... networks) {
				boolean consumed = false;

				if(dialogListener != null) {
					consumed = dialogListener.onContinue(dialog, remember, networks);
				}

				if(!consumed) {
					doShare(dialog, context, entity, socialNetworkListener, networks);
				}
				else {
                    dialogListener.onFlowInterrupted(new DialogFlowController() {

                        @Override
                        public void onContinue(String text) {

                            ShareOptions options = new ShareOptions();
                            options.setText(text);

                            doShare(dialog, context, entity, socialNetworkListener, options, networks);
                        }

                        @Override
                        public void onCancel() {

                            if(dialogView != null) {
                                dialogView.getContinueButton().setEnabled(true);
                            }

                            dialogListener.onCancel(dialog);
                        }
                    });
				}

				return false;
			}
		}, options);
	}

	protected void doShare(final Activity context, final Entity entity, final SocialNetworkShareListener socialNetworkListener, final ShareOptions shareOptions, final SocialNetwork... networks) {
		doShare(null, context, entity, socialNetworkListener, shareOptions, networks);
	}

	protected void doShare(final Dialog dialog, final Activity context, final Entity entity, final SocialNetworkShareListener socialNetworkListener, final SocialNetwork... networks) {
		doShare(dialog, context, entity, socialNetworkListener, null, networks);
	}

	protected void doShare(final Dialog dialog, final Activity context, final Entity entity, final SocialNetworkShareListener socialNetworkListener, final ShareOptions shareOptions, final SocialNetwork... networks) {
		final ProgressDialog progress = SafeProgressDialog.show(context);

		ShareType shareType = ShareType.OTHER;

		if(networks != null && networks.length == 1) {
			shareType = ShareType.valueOf(networks[0]);
		}

		String text = null;

		if(shareOptions != null) {
			text = shareOptions.getText();
		}

		if(text == null) {
			text = "";
		}

		final String fText = text;

		shareSystem.addShare(context, getSocialize().getSession(), entity, text, shareType, new ShareAddListener() {
			@Override
			public void onError(SocializeException error) {
				if(socialNetworkListener != null) {
					socialNetworkListener.onError(error);
				}

				progress.dismiss();

				if(dialog != null) {
					dialog.dismiss();
				}

			}

			@Override
			public void onCreate(Share share) {
				if(socialNetworkListener != null) {
					socialNetworkListener.onCreate(share);
				}

				if(share != null && shareSystem != null && networks != null && networks.length > 0) {
					for (final SocialNetwork network : networks) {
						shareSystem.share(context, getSocialize().getSession(), share, fText, null, ShareType.valueOf(network), socialNetworkListener);
					}
				}

				progress.dismiss();

				if(dialog != null) {
					dialog.dismiss();
				}
			}
		}, networks);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#registerShare(android.app.Activity, com.socialize.entity.Entity, com.socialize.api.action.share.ShareOptions, com.socialize.listener.share.ShareAddListener, com.socialize.networks.SocialNetwork[])
	 */
	@Override
	public void registerShare(Activity context, Entity entity, ShareOptions shareOptions, ShareAddListener listener, SocialNetwork...networks) {

		String text = null;
		if(shareOptions != null)  text = shareOptions.getText();
		if(text == null) text = "";

		ShareType shareType = ShareType.OTHER;

		if(networks != null && networks.length > 0) {
			if(networks.length == 1) {
				shareType = ShareType.valueOf(networks[0]);
			}
		}

		shareSystem.addShare(context, getSocialize().getSession(), entity, text, shareType, listener, networks);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#shareViaEmail(android.app.Activity, com.socialize.entity.Entity, com.socialize.listener.share.ShareAddListener)
	 */
	@Override
	public void shareViaEmail(Activity context, Entity entity, ShareAddListener listener) {
		doShare(context, entity, ShareType.EMAIL, listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#shareViaGooglePlus(android.app.Activity, com.socialize.entity.Entity, com.socialize.listener.share.ShareAddListener)
	 */
	@Override
	public void shareViaGooglePlus(Activity context, Entity entity, ShareAddListener listener) {
		doShare(context, entity, ShareType.GOOGLE_PLUS, listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#shareViaOther(android.app.Activity, com.socialize.entity.Entity, com.socialize.listener.share.ShareAddListener)
	 */
	@Override
	public void shareViaOther(Activity context, Entity entity, ShareAddListener listener) {
		doShare(context, entity, ShareType.OTHER, listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#shareViaSMS(android.app.Activity, com.socialize.entity.Entity, com.socialize.listener.share.ShareAddListener)
	 */
	@Override
	public void shareViaSMS(Activity context, Entity entity, ShareAddListener listener) {
		doShare(context, entity, ShareType.SMS, listener);
	}

	// Creates the socialize share object.
	protected void doShare(final Activity context, final Entity entity, final ShareType shareType, final ShareAddListener shareAddListener) {
		final SocializeSession session = getSocialize().getSession();
		shareSystem.addShare(context, session, entity, "", shareType, null, new ShareAddListener() {
			@Override
			public void onError(SocializeException error) {
				if(shareAddListener != null) {
					shareAddListener.onError(error);
				}
			}

			@Override
			public void onCreate(Share share) {
				if(share != null && shareSystem != null) {
					handleNonNetworkShare(context, session, shareType, share, "", null, shareAddListener);
				}
			}
		});
	}

	// Handles a non-network share like email or SMS.
	protected void handleNonNetworkShare(Activity activity, final SocializeSession session, final ShareType shareType, final Share share, String shareText, Location location, final ShareAddListener shareAddListener) {

		SocialNetworkListener snListener = new SocialNetworkListener() {

			@Override
			public void onNetworkError(Activity context, SocialNetwork network, Exception error) {
				if(shareAddListener != null) {
					shareAddListener.onError(SocializeException.wrap(error));
				}
			}

			@Override
			public void onCancel() {
				if(shareAddListener != null) {
					shareAddListener.onCancel();
				}
			}

			@Override
			public boolean onBeforePost(Activity parent, SocialNetwork socialNetwork, PostData postData) {
				return shareAddListener instanceof SocialNetworkListener && ((SimpleShareListener) shareAddListener).onBeforePost(parent, socialNetwork, postData);
			}

			@Override
			public void onAfterPost(Activity parent, SocialNetwork socialNetwork, JSONObject responseObject) {
				if(shareAddListener != null) {
					shareAddListener.onCreate(share);
				}
			}
		};

		shareSystem.share(activity, session, share, shareText, location, shareType, snListener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#shareViaSocialNetworks(android.app.Activity, com.socialize.entity.Entity, com.socialize.api.action.share.ShareOptions, com.socialize.api.action.share.SocialNetworkShareListener, com.socialize.networks.SocialNetwork[])
	 */
	@Override
	public void shareViaSocialNetworks(Activity context, final Entity entity, final ShareOptions shareOptions, final SocialNetworkShareListener listener, final SocialNetwork...networks) {

		final SocializeSession session = getSocialize().getSession();

		if(isDisplayAuthDialog(context, session, shareOptions, networks)) {

			authDialogFactory.show(context, new AuthDialogListener() {

				@Override
				public void onShow(Dialog dialog, AuthPanelView dialogView) {}

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

				@Override
				public void onSkipAuth(Activity context, Dialog dialog) {
					dialog.dismiss();
					doShare(context, entity, listener, shareOptions, networks);
				}

				@Override
				public void onError(Activity context, Dialog dialog, Exception error) {
					dialog.dismiss();
					if(listener != null) {
						listener.onError(SocializeException.wrap(error));
					}
				}

				@Override
				public void onAuthenticate(Activity context, Dialog dialog, SocialNetwork network) {
					dialog.dismiss();
					doShare(context, entity, listener, shareOptions, network);
				}
			}, !config.isAllowSkipAuthOnAllActions());
		}
		else {
			doShare(context, entity, listener, shareOptions, networks);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#getShare(android.app.Activity, com.socialize.listener.share.ShareGetListener, long)
	 */
	@Override
	public void getShare(Activity context, ShareGetListener listener, long id) {
		shareSystem.getShare(getSocialize().getSession(), id, listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#getShares(android.app.Activity, com.socialize.listener.share.ShareListListener, long[])
	 */
	@Override
	public void getShares(Activity context, ShareListListener listener, long... ids) {
		shareSystem.getSharesById(getSocialize().getSession(), listener, ids);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#getSharesByUser(android.app.Activity, long, int, int, com.socialize.listener.share.ShareListListener)
	 */
	@Override
	public void getSharesByUser(Activity context, User user, int start, int end, ShareListListener listener) {
		shareSystem.getSharesByUser(getSocialize().getSession(), user.getId(), start, end, listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#getSharesByEntity(android.app.Activity, java.lang.String, int, int, com.socialize.listener.share.ShareListListener)
	 */
	@Override
	public void getSharesByEntity(Activity context, String entityKey, int start, int end, ShareListListener listener) {
		shareSystem.getSharesByEntity(getSocialize().getSession(), entityKey, start, end, listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#getSharesByApplication(android.app.Activity, int, int, com.socialize.listener.share.ShareListListener)
	 */
	@Override
	public void getSharesByApplication(Activity context, int start, int end, ShareListListener listener) {
		shareSystem.getSharesByApplication(getSocialize().getSession(), start, end, listener);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#canShareViaEmail(android.app.Activity)
	 */
	@Override
	public boolean canShareViaEmail(Activity context) {
		return getSocialize().canShare(context, ShareType.EMAIL);
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.api.action.share.ShareUtilsProxy#canShareViaSMS(android.app.Activity)
	 */
	@Override
	public boolean canShareViaSMS(Activity context) {
		return getSocialize().canShare(context, ShareType.SMS);
	}

	public void setShareSystem(ShareSystem shareSystem) {
		this.shareSystem = shareSystem;
	}

	public void setShareDialogFactory(IShareDialogFactory shareDialogFactory) {
		this.shareDialogFactory = shareDialogFactory;
	}

	public void setAuthDialogFactory(IAuthDialogFactory authDialogFactory) {
		this.authDialogFactory = authDialogFactory;
	}
}


/*
 * 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.comment.CommentOptions;
import com.socialize.api.action.comment.CommentUtilsProxy;
import com.socialize.entity.Entity;
import com.socialize.entity.User;
import com.socialize.listener.comment.CommentAddListener;
import com.socialize.listener.comment.CommentDeleteListener;
import com.socialize.listener.comment.CommentGetListener;
import com.socialize.listener.comment.CommentListListener;
import com.socialize.networks.SocialNetwork;
import com.socialize.ui.comment.OnCommentViewActionListener;

import java.lang.reflect.Proxy;

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

	static CommentUtilsProxy proxy;

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

	/**
	 * Returns the default sharing options for the user.
	 * @param context The current context.
	 * @return The default sharing options for the user.
	 */
	public static CommentOptions getUserCommentOptions(Context context) {
		return proxy.getUserCommentOptions(context);
	}

	/**
	 * Adds a comment to the given entity.  This method will also prompt the user to share their comment.
	 * @param context The current context.
	 * @param entity The entity on which the comment will be associated.
	 * @param text The text of the comment.
	 * @param listener A listener to handle the result.
	 */
	public static void addComment (Activity context, Entity entity, String text, CommentAddListener listener) {
		proxy.addComment(context, entity, text, listener);
	}

	/**
	 * Deletes a comment.  Only the person that created the comment can delete it.
	 * @param context The current context.
	 * @param id The ID of the comment to be deleted.
	 * @param listener A listener to handle the result.
	 */
	public static void deleteComment (Activity context, long id, CommentDeleteListener listener) {
		proxy.deleteComment(context, id, listener);
	}

	/**
	 * Adds a comment to the given entity.  This method will NOT prompt the user to share their comment as the desired networks are passed as a parameter.
	 * @param context The current context.
	 * @param entity The entity on which the comment will be associated.
	 * @param text The text of the comment.
	 * @param commentOptions Optional parameters for the comment.
	 * @param listener A listener to handle the result.
	 * @param networks 0 or more networks on which to share the comment.  It is assumed that the user is already linked to the given networks.  If not an error will be reported in the listener for each propagation failure.
	 */
	public static void addComment (Activity context, Entity entity, String text, CommentOptions commentOptions, CommentAddListener listener, SocialNetwork...networks) {
		proxy.addComment(context, entity, text, commentOptions, listener, networks);
	}

	/**
	 * Retrieves a single comment based on ID.
	 * @param context The current context.
	 * @param id
	 * @param listener A listener to handle the result.
	 */
	public static void getComment (Activity context, CommentGetListener listener, long id) {
		proxy.getComment(context, id, listener);
	}

	/**
	 * Retrieves comments based on a set of IDs.
	 * @param context The current context.
	 * @param listener A listener to handle the result.
	 * @param ids An array of comment IDs
	 */
	public static void getComments (Activity context, CommentListListener listener, long...ids) {
		proxy.getComments(context, listener, ids);
	}

	/**
	 * Retrieves all comments made by the given user.
	 * @param context The current context.
	 * @param user The user.
	 * @param start The start index for pagination (from 0).
	 * @param end The end index for pagination.
	 * @param listener A listener to handle the result.
	 */
	public static void getCommentsByUser (Activity context, User user, int start, int end, CommentListListener listener) {
		proxy.getCommentsByUser(context, user, start, end, listener);
	}

	/**
	 * Retrieves all comments associated with the given entity.
	 * @param context The current context.
	 * @param entityKey The entity on which the comment were associated.
	 * @param start The start index for pagination (from 0).
	 * @param end The end index for pagination.
	 * @param listener A listener to handle the result.
	 */
	public static void getCommentsByEntity (Activity context, String entityKey, int start, int end, CommentListListener listener) {
		proxy.getCommentsByEntity(context, entityKey, start, end, listener);
	}

	/**
	 * Retrieves all comments across all entities.
	 * @param context The current context.
	 * @param start The start index for pagination (from 0).
	 * @param end The end index for pagination.
	 * @param listener A listener to handle the result.
	 */
	public static void getCommentsByApplication (Activity context, int start, int end, CommentListListener listener) {
		proxy.getCommentsByApplication(context, start, end, listener);
	}

	/**
	 * Shows the comments for an entity.
	 * @param listener A listener to handle the result.
	 */
	public static void showCommentView(Activity context, Entity entity, OnCommentViewActionListener listener) {
		proxy.showCommentView(context, entity, listener);
	}

	/**
	 * Shows the comments for an entity.
	 */
	public static void showCommentView(Activity context, Entity entity) {
		proxy.showCommentView(context, 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.launcher;

import android.app.Activity;
import android.os.Bundle;
import com.socialize.CommentUtils;
import com.socialize.Socialize;
import com.socialize.api.SocializeSession;
import com.socialize.api.action.ActionType;
import com.socialize.api.action.activity.ActivitySystem;
import com.socialize.entity.SocializeAction;
import com.socialize.error.SocializeException;
import com.socialize.log.SocializeLogger;
import com.socialize.notifications.NotificationAuthenticator;
import com.socialize.util.EntityLoaderUtils;
import com.socialize.util.StringUtils;

/**
 * Loads the comment list.
 * @author Jason Polites
 */
public class CommentListLauncher extends BaseLauncher {

	private EntityLoaderUtils entityLoaderUtils;
	private SocializeLogger logger;
	private ActivitySystem activitySystem;
	private NotificationAuthenticator notificationAuthenticator;

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

		if(entityLoaderUtils != null) {
			entityLoaderUtils.initEntityLoader();
		}

		// Expect an action id
		Object idObj = data.get(Socialize.ACTION_ID);
		String actionType = data.getString(Socialize.ACTION_TYPE);

		if(idObj != null && !StringUtils.isEmpty(actionType)) {

			long id = Long.parseLong(idObj.toString());

			try {
				ActionType type = ActionType.valueOf(actionType);

				SocializeSession session = notificationAuthenticator.authenticate(context);
				SocializeAction action = activitySystem.getAction(session, id, type);

				if(action != null) {
					CommentUtils.showCommentView(context, action.getEntity());
					return true;
				}
				else {
					handleWarn("No action found for id [" +
							id +
							"].");
				}
			}
			catch (SocializeException e) {
				handleError("Failed to load entity", e);
			}
		}
		else {
			handleWarn("No action id found.  Action based notification cannot be handled");
		}

		return false;
	}

	protected void handleError(String msg, Exception e) {
		if(logger != null) {
			logger.error(msg, e);
		}
		else {
			SocializeLogger.e(e.getMessage(), e);
		}
	}

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

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

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

	public void setActivitySystem(ActivitySystem activitySystem) {
		this.activitySystem = activitySystem;
	}

	public void setNotificationAuthenticator(NotificationAuthenticator notificationAuthenticator) {
		this.notificationAuthenticator = notificationAuthenticator;
	}
}


/*
 * 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 org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;

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

	private IOUtils ioUtils;

	public JSONObject parseObject(InputStream in) throws IOException, JSONException {
		String json = ioUtils.read(in);
		return parseObject(json);
	}

	/**
	 * Detects whether the inbound string is a JSONArray and if so wraps the array in an object with a single field called "data"
	 * @param json
	 * @return
	 */
	public JSONObject parseObject(String json) throws JSONException {
		json = json.trim();
		if(json.startsWith("[")) {
			JSONArray array = new JSONArray(json);
			JSONObject obj = new JSONObject();
			obj.put("data", array);
			return obj;
		}
		else {
			return new JSONObject(json);
		}
	}

	public JSONArray parseArray(InputStream in) throws IOException, JSONException {
		String json = ioUtils.read(in);
		return parseArray(json);
	}

	public JSONArray parseArray(String json) throws JSONException {
		return new JSONArray(json);
	}

	public IOUtils getIoUtils() {
		return ioUtils;
	}

	public void setIoUtils(IOUtils ioUtils) {
		this.ioUtils = ioUtils;
	}
}


/*
 * Copyright 2010 Facebook, Inc.
 *
 * 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.facebook;

import android.app.AlertDialog.Builder;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.*;
import java.net.*;

/**
 * Utility class supporting the Facebook Object.
 *
 * @author ssoneff@facebook.com
 *
 */
@Deprecated
public final class Util {

    /**
     * Set this to true to enable log output.  Remember to turn this back off
     * before releasing.  Sending sensitive data to log is a security risk.
     */
    private static boolean ENABLE_LOG = false;

    /**
     * Generate the multi-part post body providing the parameters and boundary
     * string
     *
     * @param parameters the parameters need to be posted
     * @param boundary the random string as boundary
     * @return a string of the post body
     */
    public static String encodePostBody(Bundle parameters, String boundary) {
        if (parameters == null) return "";
        StringBuilder sb = new StringBuilder();

        for (String key : parameters.keySet()) {
            Object parameter = parameters.get(key);
            if (!(parameter instanceof String)) {
                continue;
            }

            sb.append("Content-Disposition: form-data; name=\"" + key +
                    "\"\r\n\r\n" + (String)parameter);
            sb.append("\r\n" + "--" + boundary + "\r\n");
        }

        return sb.toString();
    }

    public static String encodeUrl(Bundle parameters) {
        if (parameters == null) {
            return "";
        }

        StringBuilder sb = new StringBuilder();
        boolean first = true;
        for (String key : parameters.keySet()) {
            Object parameter = parameters.get(key);
            if (!(parameter instanceof String)) {
                continue;
            }

            if (first) first = false; else sb.append("&");
            sb.append(URLEncoder.encode(key) + "=" +
                      URLEncoder.encode(parameters.getString(key)));
        }
        return sb.toString();
    }

    public static Bundle decodeUrl(String s) {
        Bundle params = new Bundle();
        if (s != null) {
            String array[] = s.split("&");
            for (String parameter : array) {
                String v[] = parameter.split("=");
                if (v.length == 2) {
                    params.putString(URLDecoder.decode(v[0]),
                                     URLDecoder.decode(v[1]));
                }
            }
        }
        return params;
    }

    /**
     * Parse a URL query and fragment parameters into a key-value bundle.
     *
     * @param url the URL to parse
     * @return a dictionary bundle of keys and values
     */
    public static Bundle parseUrl(String url) {
        // hack to prevent MalformedURLException
        url = url.replace("fbconnect", "http");
        try {
            URL u = new URL(url);
            Bundle b = decodeUrl(u.getQuery());
            b.putAll(decodeUrl(u.getRef()));
            return b;
        } catch (MalformedURLException e) {
            return new Bundle();
        }
    }

    /**
     * Connect to an HTTP URL and return the response as a string.
     *
     * Note that the HTTP method override is used on non-GET requests. (i.e.
     * requests are made as "POST" with method specified in the body).
     *
     * @param url - the resource to open: must be a welformed URL
     * @param method - the HTTP method to use ("GET", "POST", etc.)
     * @param params - the query parameter for the URL (e.g. access_token=foo)
     * @return the URL contents as a String
     * @throws MalformedURLException - if the URL format is invalid
     * @throws IOException - if a network problem occurs
     */
    public static String openUrl(String url, String method, Bundle params)
          throws MalformedURLException, IOException {
        // random string as boundary for multi-part http post
        String strBoundary = "3i2ndDfv2rTHiSisAbouNdArYfORhtTPEefj3q2f";
        String endLine = "\r\n";

        OutputStream os;

        if (method.equals("GET")) {
            url = url + "?" + encodeUrl(params);
        }
        Util.logd("Facebook-Util", method + " URL: " + url);
        HttpURLConnection conn =
            (HttpURLConnection) new URL(url).openConnection();
        conn.setRequestProperty("User-Agent", System.getProperties().
                getProperty("http.agent") + " FacebookAndroidSDK");
        if (!method.equals("GET")) {
            Bundle dataparams = new Bundle();
            for (String key : params.keySet()) {
                Object parameter = params.get(key);
                if (parameter instanceof byte[]) {
                    dataparams.putByteArray(key, (byte[])parameter);
                }
            }

            // use method override
            if (!params.containsKey("method")) {
                params.putString("method", method);
            }

            if (params.containsKey("access_token")) {
                String decoded_token =
                    URLDecoder.decode(params.getString("access_token"));
                params.putString("access_token", decoded_token);
            }

            conn.setRequestMethod("POST");
            conn.setRequestProperty(
                    "Content-Type",
                    "multipart/form-data;boundary="+strBoundary);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.connect();
            os = new BufferedOutputStream(conn.getOutputStream());

            os.write(("--" + strBoundary +endLine).getBytes());
            os.write((encodePostBody(params, strBoundary)).getBytes());
            os.write((endLine + "--" + strBoundary + endLine).getBytes());

            if (!dataparams.isEmpty()) {

                for (String key: dataparams.keySet()){
                    os.write(("Content-Disposition: form-data; filename=\"" + key + "\"" + endLine).getBytes());
                    os.write(("Content-Type: content/unknown" + endLine + endLine).getBytes());
                    os.write(dataparams.getByteArray(key));
                    os.write((endLine + "--" + strBoundary + endLine).getBytes());

                }
            }
            os.flush();
        }

        String response = "";
        try {
            response = read(conn.getInputStream());
        } catch (FileNotFoundException e) {
            // Error Stream contains JSON that we can parse to a FB error
            response = read(conn.getErrorStream());
        }
        return response;
    }

    private static String read(InputStream in) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader r = new BufferedReader(new InputStreamReader(in), 1000);
        for (String line = r.readLine(); line != null; line = r.readLine()) {
            sb.append(line);
        }
        in.close();
        return sb.toString();
    }

    public static void clearCookies(Context context) {
        // Edge case: an illegal state exception is thrown if an instance of
        // CookieSyncManager has not be created.  CookieSyncManager is normally
        // created by a WebKit view, but this might happen if you start the
        // app, restore saved state, and click logout before running a UI
        // dialog in a WebView -- in which case the app crashes
        @SuppressWarnings("unused")
        CookieSyncManager cookieSyncMngr =
            CookieSyncManager.createInstance(context);
        CookieManager cookieManager = CookieManager.getInstance();
        cookieManager.removeAllCookie();
    }

    /**
     * Parse a server response into a JSON Object. This is a basic
     * implementation using org.json.JSONObject representation. More
     * sophisticated applications may wish to do their own parsing.
     *
     * The parsed JSON is checked for a variety of error fields and
     * a FacebookException is thrown if an error condition is set,
     * populated with the error message and error type or code if
     * available.
     *
     * @param response - string representation of the response
     * @return the response as a JSON Object
     * @throws JSONException - if the response is not valid JSON
     * @throws FacebookError - if an error condition is set
     */
    public static JSONObject parseJson(String response)
          throws JSONException, FacebookError {
        // Edge case: when sending a POST request to /[post_id]/likes
        // the return value is 'true' or 'false'. Unfortunately
        // these values cause the JSONObject constructor to throw
        // an exception.
        if (response.equals("false")) {
            throw new FacebookError("request failed");
        }
        if (response.equals("true")) {
            response = "{value : true}";
        }
        JSONObject json = new JSONObject(response);

        // errors set by the server are not consistent
        // they depend on the method and endpoint
        if (json.has("error")) {
            JSONObject error = json.getJSONObject("error");
            throw new FacebookError(
                    error.getString("message"), error.getString("type"), 0);
        }
        if (json.has("error_code") && json.has("error_msg")) {
            throw new FacebookError(json.getString("error_msg"), "",
                    Integer.parseInt(json.getString("error_code")));
        }
        if (json.has("error_code")) {
            throw new FacebookError("request failed", "",
                    Integer.parseInt(json.getString("error_code")));
        }
        if (json.has("error_msg")) {
            throw new FacebookError(json.getString("error_msg"));
        }
        if (json.has("error_reason")) {
            throw new FacebookError(json.getString("error_reason"));
        }
        return json;
    }

    /**
     * Display a simple alert dialog with the given text and title.
     *
     * @param context
     *          Android context in which the dialog should be displayed
     * @param title
     *          Alert dialog title
     * @param text
     *          Alert dialog message
     */
    public static void showAlert(Context context, String title, String text) {
        Builder alertBuilder = new Builder(context);
        alertBuilder.setTitle(title);
        alertBuilder.setMessage(text);
        alertBuilder.create().show();
    }

    /**
     * A proxy for Log.d api that kills log messages in release build. It
     * not recommended to send sensitive information to log output in
     * shipping apps.
     *
     * @param tag
     * @param msg
     */
    public static void logd(String tag, String msg) {
        if (ENABLE_LOG) {
            Log.d(tag, msg);
        }
    }
}


/*
 * 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.app.Activity;
import android.content.Context;
import android.os.Bundle;
import com.socialize.Socialize;
import com.socialize.android.ioc.IOCContainer;
import com.socialize.error.SocializeException;
import com.socialize.listener.SocializeInitListener;

/**
 * @author Jason Polites
 */
public class SocializeInitSnippetA extends Activity {
// begin-snippet-0
@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);

	// Initialize socialize
	Socialize.initAsync(this, new SocializeInitListener() {

		@Override
		public void onError(SocializeException error) {
			// Handle error
		}

		@Override
		public void onInit(Context context, IOCContainer container) {
			// If you want to access Socialize directly, do it here
		}
	});
}

@Override
protected void onPause() {
	super.onPause();
	Socialize.onPause(this);
}

@Override
protected void onResume() {
	super.onResume();
	Socialize.onResume(this);
}
//end-snippet-0
}


/*
 * Copyright (C) 2011 Google Inc.
 *
 * 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.google.gson.internal.bind;

import com.socialize.google.gson.Gson;
import com.socialize.google.gson.TypeAdapter;
import com.socialize.google.gson.reflect.TypeToken;
import com.socialize.google.gson.stream.JsonReader;
import com.socialize.google.gson.stream.JsonWriter;

import java.io.IOException;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;

final class TypeAdapterRuntimeTypeWrapper<T> extends TypeAdapter<T> {
  private final Gson context;
  private final TypeAdapter<T> delegate;
  private final Type type;

  TypeAdapterRuntimeTypeWrapper(Gson context, TypeAdapter<T> delegate, Type type) {
    this.context = context;
    this.delegate = delegate;
    this.type = type;
  }

  @Override
  public T read(JsonReader in) throws IOException {
    return delegate.read(in);
  }

  @SuppressWarnings({"rawtypes", "unchecked"})
  @Override
  public void write(JsonWriter out, T value) throws IOException {
    // Order of preference for choosing type adapters
    // First preference: a type adapter registered for the runtime type
    // Second preference: a type adapter registered for the declared type
    // Third preference: reflective type adapter for the runtime type (if it is a sub class of the declared type)
    // Fourth preference: reflective type adapter for the declared type

    TypeAdapter chosen = delegate;
    Type runtimeType = getRuntimeTypeIfMoreSpecific(type, value);
    if (runtimeType != type) {
      TypeAdapter runtimeTypeAdapter = context.getAdapter(TypeToken.get(runtimeType));
      if (!(runtimeTypeAdapter instanceof ReflectiveTypeAdapterFactory.Adapter)) {
        // The user registered a type adapter for the runtime type, so we will use that
        chosen = runtimeTypeAdapter;
      } else if (!(delegate instanceof ReflectiveTypeAdapterFactory.Adapter)) {
        // The user registered a type adapter for Base class, so we prefer it over the
        // reflective type adapter for the runtime type
        chosen = delegate;
      } else {
        // Use the type adapter for runtime type
        chosen = runtimeTypeAdapter;
      }
    }
    chosen.write(out, value);
  }

  /**
   * Finds a compatible runtime type if it is more specific
   */
  private Type getRuntimeTypeIfMoreSpecific(Type type, Object value) {
    if (value != null
        && (type == Object.class || type instanceof TypeVariable<?> || type instanceof Class<?>)) {
      type = value.getClass();
    }
    return type;
  }
}


/*
 * 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.twitter;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.net.Uri;
import com.socialize.ConfigUtils;
import com.socialize.ShareUtils;
import com.socialize.Socialize;
import com.socialize.SocializeService;
import com.socialize.apache.http.entity.mime.HttpMultipartMode;
import com.socialize.apache.http.entity.mime.MultipartEntity;
import com.socialize.apache.http.entity.mime.content.ByteArrayBody;
import com.socialize.apache.http.entity.mime.content.StringBody;
import com.socialize.api.SocializeSession;
import com.socialize.api.action.share.ShareOptions;
import com.socialize.api.action.share.SocialNetworkShareListener;
import com.socialize.api.action.user.UserSystem;
import com.socialize.auth.AuthProviderInfoBuilder;
import com.socialize.auth.AuthProviderType;
import com.socialize.auth.DefaultUserProviderCredentials;
import com.socialize.auth.UserProviderCredentials;
import com.socialize.auth.twitter.TwitterAuthProviderInfo;
import com.socialize.config.SocializeConfig;
import com.socialize.entity.Entity;
import com.socialize.listener.SocializeAuthListener;
import com.socialize.net.HttpRequestListener;
import com.socialize.net.HttpRequestProvider;
import com.socialize.networks.DefaultPostData;
import com.socialize.networks.SocialNetwork;
import com.socialize.networks.SocialNetworkListener;
import com.socialize.networks.SocialNetworkPostListener;
import com.socialize.oauth.OAuthRequestSigner;
import com.socialize.util.ImageUtils;
import com.socialize.util.JSONParser;
import com.socialize.util.StringUtils;
import com.socialize.util.UrlBuilder;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.util.*;
import java.util.Map.Entry;

/**
 * @author Jason Polites
 *
 */
public class TwitterUtilsImpl implements TwitterUtilsProxy {

	private UserSystem userSystem;
	private SocializeConfig config;
	private OAuthRequestSigner requestSigner;
	private HttpRequestProvider httpRequestProvider;
	private ImageUtils imageUtils;
	private AuthProviderInfoBuilder authProviderInfoBuilder;
	private JSONParser jsonParser;
	private SocializeConfig socializeConfig;

	/* (non-Javadoc)
	 * @see com.socialize.networks.twitter.TwitterUtilsProxy#link(android.app.Activity, com.socialize.listener.SocializeAuthListener)
	 */
	@Override
	public void link(Activity context, SocializeAuthListener listener) {
		getSocialize().authenticateForWrite(context, AuthProviderType.TWITTER, listener);
	}

	/* (non-Javadoc)
	 * @see com.socialize.networks.twitter.TwitterUtilsProxy#link(android.app.Activity, java.lang.String, java.lang.String, com.socialize.listener.SocializeAuthListener)
	 */
	@Override
	public void link(Activity context, String token, String secret, SocializeAuthListener listener) {

		TwitterAuthProviderInfo twInfo = new TwitterAuthProviderInfo();
		twInfo.setConsumerKey(config.getProperty(SocializeConfig.TWITTER_CONSUMER_KEY));
		twInfo.setConsumerSecret(config.getProperty(SocializeConfig.TWITTER_CONSUMER_SECRET));

		DefaultUserProviderCredentials credentials = new DefaultUserProviderCredentials();
		credentials.setAuthProviderInfo(twInfo);
		credentials.setAccessToken(token);
		credentials.setTokenSecret(secret);

		getSocialize().authenticateKnownUser(
				context,
				credentials,
				listener);

	}

	/* (non-Javadoc)
	 * @see com.socialize.networks.twitter.TwitterUtilsProxy#unlink(android.app.Activity)
	 */
	@Override
	public void unlink(Context context) {
		SocializeSession session = getSocialize().getSession();
		session.clear(AuthProviderType.TWITTER);
		session.getUserSettings().setAutoPostTwitter(false);
		userSystem.saveSession(context, session);
	}

	/* (non-Javadoc)
	 * @see com.socialize.networks.twitter.TwitterUtilsProxy#isLinked(android.content.Context)
	 */
	@Override
	public boolean isLinked(Context context) {
		return getSocialize().isAuthenticatedForWrite(AuthProviderType.TWITTER);
	}

	/* (non-Javadoc)
	 * @see com.socialize.networks.twitter.TwitterUtilsProxy#isAvailable(android.content.Context)
	 */
	@Override
	public boolean isAvailable(Context context) {
		return authProviderInfoBuilder.isSupported(AuthProviderType.TWITTER);
	}

	/* (non-Javadoc)
	 * @see com.socialize.networks.twitter.TwitterUtilsProxy#setCredentials(android.content.Context, java.lang.String, java.lang.String)
	 */
	@Override
	public void setCredentials(Context context, String consumerKey, String consumerSecret) {
		config.setTwitterKeySecret(consumerKey, consumerSecret);
	}

	/* (non-Javadoc)
	 * @see com.socialize.networks.twitter.TwitterUtilsProxy#getAccessToken()
	 */
	@Override
	public String getAccessToken(Context context) {
		UserProviderCredentials creds = getSocialize().getSession().getUserProviderCredentials(AuthProviderType.TWITTER);
		if(creds != null) {
			return creds.getAccessToken();
		}
		return null;

	}

	/* (non-Javadoc)
	 * @see com.socialize.networks.twitter.TwitterUtilsProxy#getTokenSecret()
	 */
	@Override
	public String getTokenSecret(Context context) {
		UserProviderCredentials creds = getSocialize().getSession().getUserProviderCredentials(AuthProviderType.TWITTER);
		if(creds != null) {
			return creds.getTokenSecret();
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * @see com.socialize.networks.twitter.TwitterUtilsProxy#tweet(android.app.Activity, com.socialize.entity.Entity, java.lang.String, com.socialize.networks.SocialNetworkListener)
	 */
	@Override
	public void tweetEntity(final Activity context, final Entity entity, final String text, final SocialNetworkShareListener listener) {
		ShareOptions options = ShareUtils.getUserShareOptions(context);
		options.setText(text);
		options.setShowAuthDialog(false);
		ShareUtils.shareViaSocialNetworks(context, entity, options, listener, SocialNetwork.TWITTER);
	}

	@Override
	public void tweetPhoto(Activity context, PhotoTweet tweet, SocialNetworkPostListener listener) {
		try {
			MultipartEntity multipart = newMultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

			ByteArrayBody body = new ByteArrayBody(tweet.getImageData(), "media");
			StringBody status = new StringBody(tweet.getText());
			StringBody possiblySensitive = new StringBody(String.valueOf(tweet.isPossiblySensitive()));

			multipart.addPart("media", body);
			multipart.addPart("status", status);
			multipart.addPart("possibly_sensitive", possiblySensitive);

			String photoEndpoint = config.getProperty("twitter.upload.endpoint");
			post(context, photoEndpoint + "statuses/update_with_media.json", multipart, listener);
		}
		catch (Exception e) {
			if(listener != null) {
				listener.onNetworkError(context, SocialNetwork.TWITTER, e);
			}
		}
	}

	// Mockable
	protected MultipartEntity newMultipartEntity(HttpMultipartMode mode) {
		return new MultipartEntity(mode);
	}

	@Override
	public void tweet(final Activity context, Tweet tweet, final SocialNetworkListener listener) {
		tweet(context, null, tweet, listener);
	}

	@Override
	public void tweet(final Activity context, Entity entity, Tweet tweet, final SocialNetworkListener listener) {

		DefaultPostData postData = new DefaultPostData();

		Map<String, Object> map = new HashMap<String, Object>();

		map.put("status", tweet.getText());

		// Was failing: https://dev.twitter.com/discussions/8685
		if(tweet.isShareLocation() && tweet.getLocation() != null) {
			map.put("lat", String.valueOf(tweet.getLocation().getLatitude()));
			map.put("long", String.valueOf(tweet.getLocation().getLongitude()));
			map.put("display_coordinates", "true");
		}

		postData.setPostValues(map);
		postData.setEntity(entity);

		boolean okToGo = true;

		if(listener != null) {
			okToGo = !listener.onBeforePost(context, SocialNetwork.TWITTER, postData);
		}

		if(okToGo) {
			String path = postData.getPath();

			if(StringUtils.isEmpty(path)) {
				path = "statuses/update.json";
			}

			post(context, path, postData.getPostValues(), listener);
		}
	}

	@Override
	public void post(final Activity context, String resource, Map<String, Object> postData, final SocialNetworkPostListener listener) {

		try {
			Set<Entry<String, Object>> entries = postData.entrySet();

			List<NameValuePair> data = new ArrayList<NameValuePair>();

			for (Entry<String, Object> entry : entries) {
				String key = entry.getKey();
				Object value = entry.getValue();
				if(key != null && value != null) {
					data.add(new BasicNameValuePair(key, value.toString()));
				}
			}

			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(data, "UTF-8");
			String apiEndpoint = config.getProperty("twitter.api.endpoint");
			post(context, apiEndpoint + resource, entity, listener);
		}
		catch (Exception e) {
			if(listener != null) {
				listener.onNetworkError(context, SocialNetwork.TWITTER, e);
			}
		}
	}

	protected void post(final Activity context, String resource, HttpEntity entity, final SocialNetworkPostListener listener) {
		try {
			resource = resource.trim();

			if(!resource.endsWith(".json")) {
				resource += ".json";
			}

			HttpPost post = new HttpPost(resource);
			post.setEntity(entity);

			SocializeSession session = getSocialize().getSession();

			UserProviderCredentials creds = session.getUserProviderCredentials(AuthProviderType.TWITTER);

			String consumerKey = ConfigUtils.getConfig(context).getProperty(SocializeConfig.TWITTER_CONSUMER_KEY);
			String consumerSecret = ConfigUtils.getConfig(context).getProperty(SocializeConfig.TWITTER_CONSUMER_SECRET);

			HttpPost signedRequest = requestSigner.sign(consumerKey, consumerSecret, creds.getAccessToken(), creds.getTokenSecret(), post, null);

			httpRequestProvider.post(signedRequest, new HttpRequestListener() {

				@Override
				public void onSuccess(HttpResponse response, String responseData) {

					try {
						JSONObject responseObject = jsonParser.parseObject(responseData);
						if(listener != null) {
							listener.onAfterPost(context, SocialNetwork.TWITTER, responseObject);
						}
					}
					catch (JSONException e) {
						if(listener != null) {
							listener.onNetworkError(context, SocialNetwork.TWITTER, e);
						}
					}
				}

				@Override
				public void onError(Exception error, HttpResponse response, int errorCode, String responseData) {
					if(listener != null) {
						listener.onNetworkError(context, SocialNetwork.TWITTER, error);
					}
				}
			});
		}
		catch (Exception e) {
			if(listener != null) {
				listener.onNetworkError(context, SocialNetwork.TWITTER, e);
			}
		}
	}

	@Override
	public void get(final Activity context, String resource, Map<String, Object> params, final SocialNetworkPostListener listener) {

		try {
			resource = resource.trim();

			if(!resource.contains(".json")) {
				if(resource.contains("?")) {
					String[] split = resource.split("\\?");
					split[0] += ".json";
					resource = split[0] + split[1];
				}
				else {
					resource += ".json";
				}
			}

			String apiEndpoint = config.getProperty("twitter.api.endpoint");

			UrlBuilder builder = new UrlBuilder();
			builder.start(apiEndpoint + resource);

			if(params != null) {

				Set<Entry<String, Object>> entries = params.entrySet();

				for (Entry<String, Object> entry : entries) {
					String key = entry.getKey();
					Object value = entry.getValue();
					if(key != null && entry != null) {
						builder.addParam(key, value.toString());
					}
				}
			}

			HttpGet get = new HttpGet(builder.toString());

			SocializeSession session = getSocialize().getSession();

			UserProviderCredentials creds = session.getUserProviderCredentials(AuthProviderType.TWITTER);

			String consumerKey = ConfigUtils.getConfig(context).getProperty(SocializeConfig.TWITTER_CONSUMER_KEY);
			String consumerSecret = ConfigUtils.getConfig(context).getProperty(SocializeConfig.TWITTER_CONSUMER_SECRET);

			HttpGet signedRequest = requestSigner.sign(consumerKey, consumerSecret, creds.getAccessToken(), creds.getTokenSecret(), get, null);

			httpRequestProvider.get(signedRequest, new HttpRequestListener() {

				@Override
				public void onSuccess(HttpResponse response, String responseData) {

					try {
						JSONObject responseObject = jsonParser.parseObject(responseData);
						if(listener != null) {
							listener.onAfterPost(context, SocialNetwork.TWITTER, responseObject);
						}
					}
					catch (JSONException e) {
						if(listener != null) {
							listener.onNetworkError(context, SocialNetwork.TWITTER, e);
						}
					}
				}

				@Override
				public void onError(Exception error, HttpResponse response, int errorCode, String responseData) {
					if(listener != null) {
						listener.onNetworkError(context, SocialNetwork.TWITTER, error);
					}
				}
			});
		}
		catch (Exception e) {
			if(listener != null) {
				listener.onNetworkError(context, SocialNetwork.TWITTER, e);
			}
		}
	}

	@Override
	public byte[] getImageForPost(Activity context, Uri imagePath) throws IOException {
		return imageUtils.scaleImage(context, imagePath);
	}

	@Override
	public byte[] getImageForPost(Activity context, Bitmap image, CompressFormat format) throws IOException {
		return imageUtils.scaleImage(context, image, format);
	}

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

	public void setUserSystem(UserSystem userSystem) {
		this.userSystem = userSystem;
	}

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

	public void setRequestSigner(OAuthRequestSigner requestSigner) {
		this.requestSigner = requestSigner;
	}

	public void setHttpRequestProvider(HttpRequestProvider httpRequestProvider) {
		this.httpRequestProvider = httpRequestProvider;
	}

	public void setImageUtils(ImageUtils imageUtils) {
		this.imageUtils = imageUtils;
	}

	public void setAuthProviderInfoBuilder(AuthProviderInfoBuilder authProviderInfoBuilder) {
		this.authProviderInfoBuilder = authProviderInfoBuilder;
	}

	public void setJsonParser(JSONParser jsonParser) {
		this.jsonParser = jsonParser;
	}
}