com.piusvelte.sonet.core.SonetComments.java Source code

Java tutorial

Introduction

Here is the source code for com.piusvelte.sonet.core.SonetComments.java

Source

/*
 * Sonet - Android Social Networking Widget
 * Copyright (C) 2009 Bryan Emmanuel
 * 
 * This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *  
 *  Bryan Emmanuel piusvelte@gmail.com
 */
package com.piusvelte.sonet.core;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;

import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.google.ads.*;

import static com.piusvelte.sonet.core.Sonet.*;
import static com.piusvelte.sonet.core.SonetTokens.*;

import com.piusvelte.sonet.core.R;
import com.piusvelte.sonet.core.Sonet.Accounts;
import com.piusvelte.sonet.core.Sonet.Entities;
import com.piusvelte.sonet.core.Sonet.Notifications;
import com.piusvelte.sonet.core.Sonet.Statuses;
import com.piusvelte.sonet.core.Sonet.Statuses_styles;
import com.piusvelte.sonet.core.Sonet.Widgets;
import com.piusvelte.sonet.core.Sonet.Widgets_settings;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.appwidget.AppWidgetManager;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class SonetComments extends ListActivity
        implements OnKeyListener, OnClickListener, TextWatcher, DialogInterface.OnClickListener, OnCancelListener {
    private static final String TAG = "SonetComments";
    private int mService;
    private long mAccount;
    private String mSid = null;
    private String mEsid = null;
    private EditText mMessage;
    private ImageButton mSend;
    private TextView mCount;
    private List<HashMap<String, String>> mComments = new ArrayList<HashMap<String, String>>();
    private boolean mTime24hr = false;
    private String mChatterInstance = null;
    private String mChatterToken = null;
    private String mChatterLikeId = null;
    private String mToken = null;
    private String mSecret = null;
    private String mAccountSid = null;
    private String mServiceName = null;
    private Uri mData = null;
    private SimpleDateFormat mSimpleDateFormat = null;
    private HttpClient mHttpClient;
    private String[] items = null;
    private AlertDialog mDialog;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // allow posting to multiple services if an account is defined
        // allow selecting which accounts to use
        // get existing comments, allow liking|unliking those comments
        setContentView(R.layout.comments);
        if (!getPackageName().toLowerCase().contains(PRO)) {
            AdView adView = new AdView(this, AdSize.BANNER, SonetTokens.GOOGLE_AD_ID);
            ((LinearLayout) findViewById(R.id.ad)).addView(adView);
            adView.loadAd(new AdRequest());
        }
        mMessage = (EditText) findViewById(R.id.message);
        mSend = (ImageButton) findViewById(R.id.send);
        mCount = (TextView) findViewById(R.id.count);
        mMessage.addTextChangedListener(this);
        mMessage.setOnKeyListener(this);
        mSend.setOnClickListener(this);
        mHttpClient = SonetHttpClient.getThreadSafeClient(getApplicationContext());
        setResult(RESULT_OK);
    }

    @Override
    public void onNewIntent(Intent intent) {
        setIntent(intent);
    }

    @Override
    protected void onResume() {
        super.onResume();
        Intent intent = getIntent();
        if (intent != null)
            mData = intent.getData();
        if (mData == null) {
            (Toast.makeText(this, getString(R.string.failure), Toast.LENGTH_LONG)).show();
            finish();
        } else {
            loadComments();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if ((mDialog != null) && mDialog.isShowing()) {
            mDialog.dismiss();
        }
    }

    @Override
    public void onClick(View v) {
        if (v == mSend) {
            if ((mMessage.getText().toString() != null) && (mMessage.getText().toString().length() > 0)
                    && (mSid != null) && (mEsid != null)) {
                mMessage.setEnabled(false);
                mSend.setEnabled(false);
                // post or comment!
                final ProgressDialog loadingDialog = new ProgressDialog(this);
                final AsyncTask<Void, String, String> asyncTask = new AsyncTask<Void, String, String>() {
                    @Override
                    protected String doInBackground(Void... arg0) {
                        List<NameValuePair> params;
                        String message;
                        String response = null;
                        HttpPost httpPost;
                        SonetOAuth sonetOAuth;
                        String serviceName = Sonet.getServiceName(getResources(), mService);
                        publishProgress(serviceName);
                        switch (mService) {
                        case TWITTER:
                            // limit tweets to 140, breaking up the message if necessary
                            sonetOAuth = new SonetOAuth(TWITTER_KEY, TWITTER_SECRET, mToken, mSecret);
                            message = mMessage.getText().toString();
                            while (message.length() > 0) {
                                final String send;
                                if (message.length() > 140) {
                                    // need to break on a word
                                    int end = 0;
                                    int nextSpace = 0;
                                    for (int i = 0, i2 = message.length(); i < i2; i++) {
                                        end = nextSpace;
                                        if (message.substring(i, i + 1).equals(" ")) {
                                            nextSpace = i;
                                        }
                                    }
                                    // in case there are no spaces, just break on 140
                                    if (end == 0) {
                                        end = 140;
                                    }
                                    send = message.substring(0, end);
                                    message = message.substring(end + 1);
                                } else {
                                    send = message;
                                    message = "";
                                }
                                httpPost = new HttpPost(String.format(TWITTER_UPDATE, TWITTER_BASE_URL));
                                // resolve Error 417 Expectation by Twitter
                                httpPost.getParams().setBooleanParameter("http.protocol.expect-continue", false);
                                params = new ArrayList<NameValuePair>();
                                params.add(new BasicNameValuePair(Sstatus, send));
                                params.add(new BasicNameValuePair(Sin_reply_to_status_id, mSid));
                                try {
                                    httpPost.setEntity(new UrlEncodedFormEntity(params));
                                    response = SonetHttpClient.httpResponse(mHttpClient,
                                            sonetOAuth.getSignedRequest(httpPost));
                                } catch (UnsupportedEncodingException e) {
                                    Log.e(TAG, e.toString());
                                }
                            }
                            break;
                        case FACEBOOK:
                            httpPost = new HttpPost(String.format(FACEBOOK_COMMENTS, FACEBOOK_BASE_URL, mSid,
                                    Saccess_token, mToken));
                            params = new ArrayList<NameValuePair>();
                            params.add(new BasicNameValuePair(Smessage, mMessage.getText().toString()));
                            try {
                                httpPost.setEntity(new UrlEncodedFormEntity(params));
                                response = SonetHttpClient.httpResponse(mHttpClient, httpPost);
                            } catch (UnsupportedEncodingException e) {
                                Log.e(TAG, e.toString());
                            }
                            break;
                        case MYSPACE:
                            sonetOAuth = new SonetOAuth(MYSPACE_KEY, MYSPACE_SECRET, mToken, mSecret);
                            try {
                                httpPost = new HttpPost(String.format(MYSPACE_URL_STATUSMOODCOMMENTS,
                                        MYSPACE_BASE_URL, mEsid, mSid));
                                httpPost.setEntity(new StringEntity(String.format(MYSPACE_STATUSMOODCOMMENTS_BODY,
                                        mMessage.getText().toString())));
                                response = SonetHttpClient.httpResponse(mHttpClient,
                                        sonetOAuth.getSignedRequest(httpPost));
                            } catch (IOException e) {
                                Log.e(TAG, e.toString());
                            }
                            break;
                        case FOURSQUARE:
                            try {
                                message = URLEncoder.encode(mMessage.getText().toString(), "UTF-8");
                                httpPost = new HttpPost(String.format(FOURSQUARE_ADDCOMMENT, FOURSQUARE_BASE_URL,
                                        mSid, message, mToken));
                                response = SonetHttpClient.httpResponse(mHttpClient, httpPost);
                            } catch (UnsupportedEncodingException e) {
                                Log.e(TAG, e.toString());
                            }
                            break;
                        case LINKEDIN:
                            sonetOAuth = new SonetOAuth(LINKEDIN_KEY, LINKEDIN_SECRET, mToken, mSecret);
                            try {
                                httpPost = new HttpPost(
                                        String.format(LINKEDIN_UPDATE_COMMENTS, LINKEDIN_BASE_URL, mSid));
                                httpPost.setEntity(new StringEntity(
                                        String.format(LINKEDIN_COMMENT_BODY, mMessage.getText().toString())));
                                httpPost.addHeader(new BasicHeader("Content-Type", "application/xml"));
                                response = SonetHttpClient.httpResponse(mHttpClient,
                                        sonetOAuth.getSignedRequest(httpPost));
                            } catch (IOException e) {
                                Log.e(TAG, e.toString());
                            }
                            break;
                        case IDENTICA:
                            // limit tweets to 140, breaking up the message if necessary
                            sonetOAuth = new SonetOAuth(IDENTICA_KEY, IDENTICA_SECRET, mToken, mSecret);
                            message = mMessage.getText().toString();
                            while (message.length() > 0) {
                                final String send;
                                if (message.length() > 140) {
                                    // need to break on a word
                                    int end = 0;
                                    int nextSpace = 0;
                                    for (int i = 0, i2 = message.length(); i < i2; i++) {
                                        end = nextSpace;
                                        if (message.substring(i, i + 1).equals(" ")) {
                                            nextSpace = i;
                                        }
                                    }
                                    // in case there are no spaces, just break on 140
                                    if (end == 0) {
                                        end = 140;
                                    }
                                    send = message.substring(0, end);
                                    message = message.substring(end + 1);
                                } else {
                                    send = message;
                                    message = "";
                                }
                                httpPost = new HttpPost(String.format(IDENTICA_UPDATE, IDENTICA_BASE_URL));
                                // resolve Error 417 Expectation by Twitter
                                httpPost.getParams().setBooleanParameter("http.protocol.expect-continue", false);
                                params = new ArrayList<NameValuePair>();
                                params.add(new BasicNameValuePair(Sstatus, send));
                                params.add(new BasicNameValuePair(Sin_reply_to_status_id, mSid));
                                try {
                                    httpPost.setEntity(new UrlEncodedFormEntity(params));
                                    response = SonetHttpClient.httpResponse(mHttpClient,
                                            sonetOAuth.getSignedRequest(httpPost));
                                } catch (UnsupportedEncodingException e) {
                                    Log.e(TAG, e.toString());
                                }
                            }
                            break;
                        case GOOGLEPLUS:
                            break;
                        case CHATTER:
                            httpPost = new HttpPost(String.format(CHATTER_URL_COMMENT, mChatterInstance, mSid,
                                    Uri.encode(mMessage.getText().toString())));
                            httpPost.setHeader("Authorization", "OAuth " + mChatterToken);
                            response = SonetHttpClient.httpResponse(mHttpClient, httpPost);
                            break;
                        }
                        return ((response == null) && (mService == MYSPACE)) ? null
                                : serviceName + " "
                                        + getString(response != null ? R.string.success : R.string.failure);
                    }

                    @Override
                    protected void onProgressUpdate(String... params) {
                        loadingDialog.setMessage(String.format(getString(R.string.sending), params[0]));
                    }

                    @Override
                    protected void onPostExecute(String result) {
                        if (result != null) {
                            (Toast.makeText(SonetComments.this, result, Toast.LENGTH_LONG)).show();
                        } else if (mService == MYSPACE) {
                            // myspace permissions
                            (Toast.makeText(SonetComments.this,
                                    SonetComments.this.getResources()
                                            .getStringArray(R.array.service_entries)[MYSPACE]
                                            + getString(R.string.failure) + " "
                                            + getString(R.string.myspace_permissions_message),
                                    Toast.LENGTH_LONG)).show();
                        }
                        if (loadingDialog.isShowing())
                            loadingDialog.dismiss();
                        finish();
                    }

                };
                loadingDialog.setMessage(getString(R.string.loading));
                loadingDialog.setCancelable(true);
                loadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        if (!asyncTask.isCancelled())
                            asyncTask.cancel(true);
                    }
                });
                loadingDialog.setButton(ProgressDialog.BUTTON_NEGATIVE, getString(android.R.string.cancel),
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.cancel();
                            }
                        });
                loadingDialog.show();
                asyncTask.execute();
            } else {
                (Toast.makeText(SonetComments.this, "error parsing message body", Toast.LENGTH_LONG)).show();
                mMessage.setEnabled(true);
                mSend.setEnabled(true);
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_comments, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int itemId = item.getItemId();
        if (itemId == R.id.menu_comments_refresh)
            loadComments();
        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onListItemClick(ListView list, View view, final int position, long id) {
        super.onListItemClick(list, view, position, id);
        final String sid = mComments.get(position).get(Statuses.SID);
        final String liked = mComments.get(position).get(getString(R.string.like));
        // wait for previous attempts to finish
        if ((liked.length() > 0) && !liked.equals(getString(R.string.loading))) {
            // parse comment body, as in StatusDialog.java
            Matcher m = Sonet.getLinksMatcher(mComments.get(position).get(Statuses.MESSAGE));
            int count = 0;
            while (m.find()) {
                count++;
            }
            // like comments, the first comment is the post itself
            switch (mService) {
            case TWITTER:
                // retweet
                items = new String[count + 1];
                items[0] = getString(R.string.retweet);
                count = 1;
                m.reset();
                while (m.find()) {
                    items[count++] = m.group();
                }
                mDialog = (new AlertDialog.Builder(this)).setItems(items, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if (which == 0) {
                            AsyncTask<String, Void, String> asyncTask = new AsyncTask<String, Void, String>() {
                                @Override
                                protected String doInBackground(String... arg0) {
                                    SonetOAuth sonetOAuth = new SonetOAuth(TWITTER_KEY, TWITTER_SECRET, mToken,
                                            mSecret);
                                    HttpPost httpPost = new HttpPost(
                                            String.format(TWITTER_RETWEET, TWITTER_BASE_URL, sid));
                                    // resolve Error 417 Expectation by Twitter
                                    httpPost.getParams().setBooleanParameter("http.protocol.expect-continue",
                                            false);
                                    return SonetHttpClient.httpResponse(mHttpClient,
                                            sonetOAuth.getSignedRequest(httpPost));
                                }

                                @Override
                                protected void onPostExecute(String response) {
                                    setCommentStatus(0, getString(R.string.retweet));
                                    (Toast.makeText(SonetComments.this,
                                            mServiceName + " "
                                                    + getString(
                                                            response != null ? R.string.success : R.string.failure),
                                            Toast.LENGTH_LONG)).show();
                                }
                            };
                            setCommentStatus(0, getString(R.string.loading));
                            asyncTask.execute();
                        } else {
                            if ((which < items.length) && (items[which] != null))
                                // open link
                                startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(items[which])));
                            else
                                (Toast.makeText(SonetComments.this, getString(R.string.error_status),
                                        Toast.LENGTH_LONG)).show();
                        }
                    }
                }).setCancelable(true).setOnCancelListener(this).create();
                mDialog.show();
                break;
            case FACEBOOK:
                items = new String[count + 1];
                items[0] = getString(
                        mComments.get(position).get(getString(R.string.like)) == getString(R.string.like)
                                ? R.string.like
                                : R.string.unlike);
                count = 1;
                m.reset();
                while (m.find()) {
                    items[count++] = m.group();
                }
                mDialog = (new AlertDialog.Builder(this)).setItems(items, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if (which == 0) {
                            AsyncTask<String, Void, String> asyncTask = new AsyncTask<String, Void, String>() {
                                @Override
                                protected String doInBackground(String... arg0) {
                                    if (liked.equals(getString(R.string.like))) {
                                        return SonetHttpClient.httpResponse(mHttpClient,
                                                new HttpPost(String.format(FACEBOOK_LIKES, FACEBOOK_BASE_URL, sid,
                                                        Saccess_token, mToken)));
                                    } else {
                                        HttpDelete httpDelete = new HttpDelete(String.format(FACEBOOK_LIKES,
                                                FACEBOOK_BASE_URL, sid, Saccess_token, mToken));
                                        httpDelete.setHeader("Content-Length", "0");
                                        return SonetHttpClient.httpResponse(mHttpClient, httpDelete);
                                    }
                                }

                                @Override
                                protected void onPostExecute(String response) {
                                    if (response != null) {
                                        setCommentStatus(position,
                                                getString(liked.equals(getString(R.string.like)) ? R.string.unlike
                                                        : R.string.like));
                                        (Toast.makeText(SonetComments.this,
                                                mServiceName + " " + getString(R.string.success),
                                                Toast.LENGTH_LONG)).show();
                                    } else {
                                        setCommentStatus(position,
                                                getString(liked.equals(getString(R.string.like)) ? R.string.like
                                                        : R.string.unlike));
                                        (Toast.makeText(SonetComments.this,
                                                mServiceName + " " + getString(R.string.failure),
                                                Toast.LENGTH_LONG)).show();
                                    }
                                }
                            };
                            setCommentStatus(position, getString(R.string.loading));
                            asyncTask.execute();
                        } else {
                            if ((which < items.length) && (items[which] != null))
                                // open link
                                startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(items[which])));
                            else
                                (Toast.makeText(SonetComments.this, getString(R.string.error_status),
                                        Toast.LENGTH_LONG)).show();
                        }
                    }
                }).setCancelable(true).setOnCancelListener(this).create();
                mDialog.show();
                break;
            case LINKEDIN:
                if (position == 0) {
                    items = new String[count + 1];
                    items[0] = getString(
                            mComments.get(position).get(getString(R.string.like)) == getString(R.string.like)
                                    ? R.string.like
                                    : R.string.unlike);
                    count = 1;
                    m.reset();
                    while (m.find()) {
                        items[count++] = m.group();
                    }
                    mDialog = (new AlertDialog.Builder(this))
                            .setItems(items, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    if (which == 0) {
                                        AsyncTask<String, Void, String> asyncTask = new AsyncTask<String, Void, String>() {
                                            @Override
                                            protected String doInBackground(String... arg0) {
                                                SonetOAuth sonetOAuth = new SonetOAuth(LINKEDIN_KEY,
                                                        LINKEDIN_SECRET, mToken, mSecret);
                                                HttpPut httpPut = new HttpPut(
                                                        String.format(LINKEDIN_IS_LIKED, LINKEDIN_BASE_URL, mSid));
                                                httpPut.addHeader(
                                                        new BasicHeader("Content-Type", "application/xml"));
                                                try {
                                                    httpPut.setEntity(new StringEntity(
                                                            String.format(LINKEDIN_LIKE_BODY, Boolean.toString(
                                                                    liked.equals(getString(R.string.like))))));
                                                    return SonetHttpClient.httpResponse(mHttpClient,
                                                            sonetOAuth.getSignedRequest(httpPut));
                                                } catch (UnsupportedEncodingException e) {
                                                    Log.e(TAG, e.toString());
                                                }
                                                return null;
                                            }

                                            @Override
                                            protected void onPostExecute(String response) {
                                                if (response != null) {
                                                    setCommentStatus(position,
                                                            getString(liked.equals(getString(R.string.like))
                                                                    ? R.string.unlike
                                                                    : R.string.like));
                                                    (Toast.makeText(SonetComments.this,
                                                            mServiceName + " " + getString(R.string.success),
                                                            Toast.LENGTH_LONG)).show();
                                                } else {
                                                    setCommentStatus(position,
                                                            getString(liked.equals(getString(R.string.like))
                                                                    ? R.string.like
                                                                    : R.string.unlike));
                                                    (Toast.makeText(SonetComments.this,
                                                            mServiceName + " " + getString(R.string.failure),
                                                            Toast.LENGTH_LONG)).show();
                                                }
                                            }
                                        };
                                        setCommentStatus(position, getString(R.string.loading));
                                        asyncTask.execute();
                                    } else {
                                        if ((which < items.length) && (items[which] != null))
                                            // open link
                                            startActivity(new Intent(Intent.ACTION_VIEW)
                                                    .setData(Uri.parse(items[which])));
                                        else
                                            (Toast.makeText(SonetComments.this, getString(R.string.error_status),
                                                    Toast.LENGTH_LONG)).show();
                                    }
                                }
                            }).setCancelable(true).setOnCancelListener(this).create();
                    mDialog.show();
                } else {
                    // no like option here
                    items = new String[count];
                    count = 1;
                    m.reset();
                    while (m.find()) {
                        items[count++] = m.group();
                    }
                    mDialog = (new AlertDialog.Builder(this))
                            .setItems(items, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    if ((which < items.length) && (items[which] != null))
                                        // open link
                                        startActivity(
                                                new Intent(Intent.ACTION_VIEW).setData(Uri.parse(items[which])));
                                    else
                                        (Toast.makeText(SonetComments.this, getString(R.string.error_status),
                                                Toast.LENGTH_LONG)).show();
                                }
                            }).setCancelable(true).setOnCancelListener(this).create();
                    mDialog.show();
                }
                break;
            case IDENTICA:
                // retweet
                items = new String[count + 1];
                items[0] = getString(R.string.repeat);
                count = 1;
                m.reset();
                while (m.find()) {
                    items[count++] = m.group();
                }
                mDialog = (new AlertDialog.Builder(this)).setItems(items, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if (which == 0) {
                            AsyncTask<String, Void, String> asyncTask = new AsyncTask<String, Void, String>() {
                                @Override
                                protected String doInBackground(String... arg0) {
                                    SonetOAuth sonetOAuth = new SonetOAuth(IDENTICA_KEY, IDENTICA_SECRET, mToken,
                                            mSecret);
                                    HttpPost httpPost = new HttpPost(
                                            String.format(IDENTICA_RETWEET, IDENTICA_BASE_URL, sid));
                                    // resolve Error 417 Expectation by Twitter
                                    httpPost.getParams().setBooleanParameter("http.protocol.expect-continue",
                                            false);
                                    return SonetHttpClient.httpResponse(mHttpClient,
                                            sonetOAuth.getSignedRequest(httpPost));
                                }

                                @Override
                                protected void onPostExecute(String response) {
                                    setCommentStatus(0, getString(R.string.repeat));
                                    (Toast.makeText(SonetComments.this,
                                            mServiceName + " "
                                                    + getString(
                                                            response != null ? R.string.success : R.string.failure),
                                            Toast.LENGTH_LONG)).show();
                                }
                            };
                            setCommentStatus(0, getString(R.string.loading));
                            asyncTask.execute();
                        } else {
                            if ((which < items.length) && (items[which] != null))
                                // open link
                                startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(items[which])));
                            else
                                (Toast.makeText(SonetComments.this, getString(R.string.error_status),
                                        Toast.LENGTH_LONG)).show();
                        }
                    }
                }).setCancelable(true).setOnCancelListener(this).create();
                mDialog.show();
                break;
            case GOOGLEPLUS:
                //TODO:
                // plus1
                items = new String[count];
                count = 1;
                m.reset();
                while (m.find()) {
                    items[count++] = m.group();
                }
                mDialog = (new AlertDialog.Builder(this)).setItems(items, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        if ((which < items.length) && (items[which] != null))
                            // open link
                            startActivity(new Intent(Intent.ACTION_VIEW).setData(Uri.parse(items[which])));
                        else
                            (Toast.makeText(SonetComments.this, getString(R.string.error_status),
                                    Toast.LENGTH_LONG)).show();
                    }
                }).setCancelable(true).setOnCancelListener(this).create();
                mDialog.show();
                break;
            case CHATTER:
                if (position == 0) {
                    items = new String[count + 1];
                    items[0] = getString(
                            mComments.get(position).get(getString(R.string.like)) == getString(R.string.like)
                                    ? R.string.like
                                    : R.string.unlike);
                    count = 1;
                    m.reset();
                    while (m.find()) {
                        items[count++] = m.group();
                    }
                    mDialog = (new AlertDialog.Builder(this))
                            .setItems(items, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    if (which == 0) {
                                        AsyncTask<String, Void, String> asyncTask = new AsyncTask<String, Void, String>() {
                                            @Override
                                            protected String doInBackground(String... arg0) {
                                                HttpUriRequest httpRequest;
                                                if (liked.equals(getString(R.string.like))) {
                                                    httpRequest = new HttpPost(String.format(CHATTER_URL_LIKES,
                                                            mChatterInstance, mSid));
                                                } else {
                                                    httpRequest = new HttpDelete(String.format(CHATTER_URL_LIKE,
                                                            mChatterInstance, mChatterLikeId));
                                                }
                                                httpRequest.setHeader("Authorization", "OAuth " + mChatterToken);
                                                return SonetHttpClient.httpResponse(mHttpClient, httpRequest);
                                            }

                                            @Override
                                            protected void onPostExecute(String response) {
                                                if (response != null) {
                                                    setCommentStatus(position,
                                                            getString(liked.equals(getString(R.string.like))
                                                                    ? R.string.unlike
                                                                    : R.string.like));
                                                    (Toast.makeText(SonetComments.this,
                                                            mServiceName + " " + getString(R.string.success),
                                                            Toast.LENGTH_LONG)).show();
                                                } else {
                                                    setCommentStatus(position,
                                                            getString(liked.equals(getString(R.string.like))
                                                                    ? R.string.like
                                                                    : R.string.unlike));
                                                    (Toast.makeText(SonetComments.this,
                                                            mServiceName + " " + getString(R.string.failure),
                                                            Toast.LENGTH_LONG)).show();
                                                }
                                            }
                                        };
                                        setCommentStatus(position, getString(R.string.loading));
                                        asyncTask.execute();
                                    } else {
                                        if ((which < items.length) && (items[which] != null))
                                            // open link
                                            startActivity(new Intent(Intent.ACTION_VIEW)
                                                    .setData(Uri.parse(items[which])));
                                        else
                                            (Toast.makeText(SonetComments.this, getString(R.string.error_status),
                                                    Toast.LENGTH_LONG)).show();
                                    }
                                }
                            }).setCancelable(true).setOnCancelListener(this).create();
                    mDialog.show();
                } else {
                    // no like option here
                    items = new String[count];
                    count = 1;
                    m.reset();
                    while (m.find()) {
                        items[count++] = m.group();
                    }
                    mDialog = (new AlertDialog.Builder(this))
                            .setItems(items, new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    if ((which < items.length) && (items[which] != null))
                                        // open link
                                        startActivity(
                                                new Intent(Intent.ACTION_VIEW).setData(Uri.parse(items[which])));
                                    else
                                        (Toast.makeText(SonetComments.this, getString(R.string.error_status),
                                                Toast.LENGTH_LONG)).show();
                                }
                            }).setCancelable(true).setOnCancelListener(this).create();
                    mDialog.show();
                }
                break;
            }
        }
    }

    @Override
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        mCount.setText(Integer.toString(mMessage.getText().toString().length()));
        return false;
    }

    @Override
    public void afterTextChanged(Editable arg0) {
        mCount.setText(Integer.toString(arg0.toString().length()));
    }

    @Override
    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }

    private void setCommentStatus(int position, String status) {
        if (mComments.size() > position) {
            HashMap<String, String> comment = mComments.get(position);
            comment.put(getString(R.string.like), status);
            mComments.set(position, comment);
            setListAdapter(new SimpleAdapter(SonetComments.this, mComments, R.layout.comment,
                    new String[] { Entities.FRIEND, Statuses.MESSAGE, Statuses.CREATEDTEXT,
                            getString(R.string.like) },
                    new int[] { R.id.friend, R.id.message, R.id.created, R.id.like }));
        }
    }

    private void loadComments() {
        mComments.clear();
        setListAdapter(new SimpleAdapter(SonetComments.this, mComments, R.layout.comment,
                new String[] { Entities.FRIEND, Statuses.MESSAGE, Statuses.CREATEDTEXT, getString(R.string.like) },
                new int[] { R.id.friend, R.id.message, R.id.created, R.id.like }));
        mMessage.setEnabled(false);
        mMessage.setText(R.string.loading);
        final ProgressDialog loadingDialog = new ProgressDialog(this);
        final AsyncTask<Void, String, String> asyncTask = new AsyncTask<Void, String, String>() {
            @Override
            protected String doInBackground(Void... none) {
                // load the status itself
                if (mData != null) {
                    SonetCrypto sonetCrypto = SonetCrypto.getInstance(getApplicationContext());
                    UriMatcher um = new UriMatcher(UriMatcher.NO_MATCH);
                    String authority = Sonet.getAuthority(SonetComments.this);
                    um.addURI(authority, SonetProvider.VIEW_STATUSES_STYLES + "/*", SonetProvider.STATUSES_STYLES);
                    um.addURI(authority, SonetProvider.TABLE_NOTIFICATIONS + "/*", SonetProvider.NOTIFICATIONS);
                    Cursor status;
                    switch (um.match(mData)) {
                    case SonetProvider.STATUSES_STYLES:
                        status = getContentResolver().query(Statuses_styles.getContentUri(SonetComments.this),
                                new String[] { Statuses_styles.ACCOUNT, Statuses_styles.SID, Statuses_styles.ESID,
                                        Statuses_styles.WIDGET, Statuses_styles.SERVICE, Statuses_styles.FRIEND,
                                        Statuses_styles.MESSAGE, Statuses_styles.CREATED },
                                Statuses_styles._ID + "=?", new String[] { mData.getLastPathSegment() }, null);
                        if (status.moveToFirst()) {
                            mService = status.getInt(4);
                            mServiceName = getResources().getStringArray(R.array.service_entries)[mService];
                            mAccount = status.getLong(0);
                            mSid = sonetCrypto.Decrypt(status.getString(1));
                            mEsid = sonetCrypto.Decrypt(status.getString(2));
                            Cursor widget = getContentResolver().query(
                                    Widgets_settings.getContentUri(SonetComments.this),
                                    new String[] { Widgets.TIME24HR },
                                    Widgets.WIDGET + "=? and " + Widgets.ACCOUNT + "=?",
                                    new String[] { Integer.toString(status.getInt(3)), Long.toString(mAccount) },
                                    null);
                            if (widget.moveToFirst()) {
                                mTime24hr = widget.getInt(0) == 1;
                            } else {
                                Cursor b = getContentResolver().query(
                                        Widgets_settings.getContentUri(SonetComments.this),
                                        new String[] { Widgets.TIME24HR },
                                        Widgets.WIDGET + "=? and " + Widgets.ACCOUNT + "=?",
                                        new String[] { Integer.toString(status.getInt(3)),
                                                Long.toString(Sonet.INVALID_ACCOUNT_ID) },
                                        null);
                                if (b.moveToFirst()) {
                                    mTime24hr = b.getInt(0) == 1;
                                } else {
                                    Cursor c = getContentResolver()
                                            .query(Widgets_settings.getContentUri(SonetComments.this),
                                                    new String[] { Widgets.TIME24HR },
                                                    Widgets.WIDGET + "=? and " + Widgets.ACCOUNT + "=?",
                                                    new String[] {
                                                            Integer.toString(AppWidgetManager.INVALID_APPWIDGET_ID),
                                                            Long.toString(Sonet.INVALID_ACCOUNT_ID) },
                                                    null);
                                    if (c.moveToFirst()) {
                                        mTime24hr = c.getInt(0) == 1;
                                    } else {
                                        mTime24hr = false;
                                    }
                                    c.close();
                                }
                                b.close();
                            }
                            widget.close();
                            HashMap<String, String> commentMap = new HashMap<String, String>();
                            commentMap.put(Statuses.SID, mSid);
                            commentMap.put(Entities.FRIEND, status.getString(5));
                            commentMap.put(Statuses.MESSAGE, status.getString(6));
                            commentMap.put(Statuses.CREATEDTEXT,
                                    Sonet.getCreatedText(status.getLong(7), mTime24hr));
                            commentMap.put(getString(R.string.like),
                                    mService == TWITTER ? getString(R.string.retweet)
                                            : mService == IDENTICA ? getString(R.string.repeat) : "");
                            mComments.add(commentMap);
                            // load the session
                            Cursor account = getContentResolver().query(Accounts.getContentUri(SonetComments.this),
                                    new String[] { Accounts.TOKEN, Accounts.SECRET, Accounts.SID },
                                    Accounts._ID + "=?", new String[] { Long.toString(mAccount) }, null);
                            if (account.moveToFirst()) {
                                mToken = sonetCrypto.Decrypt(account.getString(0));
                                mSecret = sonetCrypto.Decrypt(account.getString(1));
                                mAccountSid = sonetCrypto.Decrypt(account.getString(2));
                            }
                            account.close();
                        }
                        status.close();
                        break;
                    case SonetProvider.NOTIFICATIONS:
                        Cursor notification = getContentResolver().query(
                                Notifications.getContentUri(SonetComments.this),
                                new String[] { Notifications.ACCOUNT, Notifications.SID, Notifications.ESID,
                                        Notifications.FRIEND, Notifications.MESSAGE, Notifications.CREATED },
                                Notifications._ID + "=?", new String[] { mData.getLastPathSegment() }, null);
                        if (notification.moveToFirst()) {
                            // clear notification
                            ContentValues values = new ContentValues();
                            values.put(Notifications.CLEARED, 1);
                            getContentResolver().update(Notifications.getContentUri(SonetComments.this), values,
                                    Notifications._ID + "=?", new String[] { mData.getLastPathSegment() });
                            mAccount = notification.getLong(0);
                            mSid = sonetCrypto.Decrypt(notification.getString(1));
                            mEsid = sonetCrypto.Decrypt(notification.getString(2));
                            mTime24hr = false;
                            // load the session
                            Cursor account = getContentResolver().query(Accounts.getContentUri(SonetComments.this),
                                    new String[] { Accounts.TOKEN, Accounts.SECRET, Accounts.SID,
                                            Accounts.SERVICE },
                                    Accounts._ID + "=?", new String[] { Long.toString(mAccount) }, null);
                            if (account.moveToFirst()) {
                                mToken = sonetCrypto.Decrypt(account.getString(0));
                                mSecret = sonetCrypto.Decrypt(account.getString(1));
                                mAccountSid = sonetCrypto.Decrypt(account.getString(2));
                                mService = account.getInt(3);
                            }
                            account.close();
                            HashMap<String, String> commentMap = new HashMap<String, String>();
                            commentMap.put(Statuses.SID, mSid);
                            commentMap.put(Entities.FRIEND, notification.getString(3));
                            commentMap.put(Statuses.MESSAGE, notification.getString(4));
                            commentMap.put(Statuses.CREATEDTEXT,
                                    Sonet.getCreatedText(notification.getLong(5), mTime24hr));
                            commentMap.put(getString(R.string.like),
                                    mService == TWITTER ? getString(R.string.retweet) : getString(R.string.repeat));
                            mComments.add(commentMap);
                            mServiceName = getResources().getStringArray(R.array.service_entries)[mService];
                        }
                        notification.close();
                        break;
                    default:
                        mComments.clear();
                        HashMap<String, String> commentMap = new HashMap<String, String>();
                        commentMap.put(Statuses.SID, "");
                        commentMap.put(Entities.FRIEND, "");
                        commentMap.put(Statuses.MESSAGE, "error, status not found");
                        commentMap.put(Statuses.CREATEDTEXT, "");
                        commentMap.put(getString(R.string.like), "");
                        mComments.add(commentMap);
                    }
                    String response = null;
                    HttpGet httpGet;
                    SonetOAuth sonetOAuth;
                    boolean liked = false;
                    String screen_name = "";
                    switch (mService) {
                    case TWITTER:
                        sonetOAuth = new SonetOAuth(TWITTER_KEY, TWITTER_SECRET, mToken, mSecret);
                        if ((response = SonetHttpClient.httpResponse(mHttpClient, sonetOAuth.getSignedRequest(
                                new HttpGet(String.format(TWITTER_USER, TWITTER_BASE_URL, mEsid))))) != null) {
                            try {
                                JSONObject user = new JSONObject(response);
                                screen_name = "@" + user.getString(Sscreen_name) + " ";
                            } catch (JSONException e) {
                                Log.e(TAG, e.toString());
                            }
                        }
                        publishProgress(screen_name);
                        response = SonetHttpClient.httpResponse(mHttpClient,
                                sonetOAuth.getSignedRequest(new HttpGet(String.format(TWITTER_MENTIONS,
                                        TWITTER_BASE_URL, String.format(TWITTER_SINCE_ID, mSid)))));
                        break;
                    case FACEBOOK:
                        if ((response = SonetHttpClient.httpResponse(mHttpClient,
                                new HttpGet(String.format(FACEBOOK_LIKES, FACEBOOK_BASE_URL, mSid, Saccess_token,
                                        mToken)))) != null) {
                            try {
                                JSONArray likes = new JSONObject(response).getJSONArray(Sdata);
                                for (int i = 0, i2 = likes.length(); i < i2; i++) {
                                    JSONObject like = likes.getJSONObject(i);
                                    if (like.getString(Sid).equals(mAccountSid)) {
                                        liked = true;
                                        break;
                                    }
                                }
                            } catch (JSONException e) {
                                Log.e(TAG, e.toString());
                            }
                        }
                        publishProgress(getString(liked ? R.string.unlike : R.string.like));
                        response = SonetHttpClient.httpResponse(mHttpClient, new HttpGet(
                                String.format(FACEBOOK_COMMENTS, FACEBOOK_BASE_URL, mSid, Saccess_token, mToken)));
                        break;
                    case MYSPACE:
                        sonetOAuth = new SonetOAuth(MYSPACE_KEY, MYSPACE_SECRET, mToken, mSecret);
                        response = SonetHttpClient.httpResponse(mHttpClient,
                                sonetOAuth.getSignedRequest(new HttpGet(String
                                        .format(MYSPACE_URL_STATUSMOODCOMMENTS, MYSPACE_BASE_URL, mEsid, mSid))));
                        break;
                    case LINKEDIN:
                        sonetOAuth = new SonetOAuth(LINKEDIN_KEY, LINKEDIN_SECRET, mToken, mSecret);
                        httpGet = new HttpGet(String.format(LINKEDIN_UPDATE, LINKEDIN_BASE_URL, mSid));
                        for (String[] header : LINKEDIN_HEADERS)
                            httpGet.setHeader(header[0], header[1]);
                        if ((response = SonetHttpClient.httpResponse(mHttpClient,
                                sonetOAuth.getSignedRequest(httpGet))) != null) {
                            try {
                                JSONObject data = new JSONObject(response);
                                if (data.has("isCommentable") && !data.getBoolean("isCommentable")) {
                                    publishProgress(getString(R.string.uncommentable));
                                }
                                if (data.has("isLikable")) {
                                    publishProgress(getString(
                                            data.has("isLiked") && data.getBoolean("isLiked") ? R.string.unlike
                                                    : R.string.like));
                                } else {
                                    publishProgress(getString(R.string.unlikable));
                                }
                            } catch (JSONException e) {
                                Log.e(TAG, e.toString());
                            }
                        } else {
                            publishProgress(getString(R.string.unlikable));
                        }
                        httpGet = new HttpGet(String.format(LINKEDIN_UPDATE_COMMENTS, LINKEDIN_BASE_URL, mSid));
                        for (String[] header : LINKEDIN_HEADERS)
                            httpGet.setHeader(header[0], header[1]);
                        response = SonetHttpClient.httpResponse(mHttpClient, sonetOAuth.getSignedRequest(httpGet));
                        break;
                    case FOURSQUARE:
                        response = SonetHttpClient.httpResponse(mHttpClient, new HttpGet(
                                String.format(FOURSQUARE_GET_CHECKIN, FOURSQUARE_BASE_URL, mSid, mToken)));
                        break;
                    case IDENTICA:
                        sonetOAuth = new SonetOAuth(IDENTICA_KEY, IDENTICA_SECRET, mToken, mSecret);
                        if ((response = SonetHttpClient.httpResponse(mHttpClient, sonetOAuth.getSignedRequest(
                                new HttpGet(String.format(IDENTICA_USER, IDENTICA_BASE_URL, mEsid))))) != null) {
                            try {
                                JSONObject user = new JSONObject(response);
                                screen_name = "@" + user.getString(Sscreen_name) + " ";
                            } catch (JSONException e) {
                                Log.e(TAG, e.toString());
                            }
                        }
                        publishProgress(screen_name);
                        response = SonetHttpClient.httpResponse(mHttpClient,
                                sonetOAuth.getSignedRequest(new HttpGet(String.format(IDENTICA_MENTIONS,
                                        IDENTICA_BASE_URL, String.format(IDENTICA_SINCE_ID, mSid)))));
                        break;
                    case GOOGLEPLUS:
                        //TODO:
                        // get plussed status
                        break;
                    case CHATTER:
                        // Chatter requires loading an instance
                        if ((mChatterInstance == null) || (mChatterToken == null)) {
                            if ((response = SonetHttpClient.httpResponse(mHttpClient, new HttpPost(
                                    String.format(CHATTER_URL_ACCESS, CHATTER_KEY, mToken)))) != null) {
                                try {
                                    JSONObject jobj = new JSONObject(response);
                                    if (jobj.has("instance_url") && jobj.has(Saccess_token)) {
                                        mChatterInstance = jobj.getString("instance_url");
                                        mChatterToken = jobj.getString(Saccess_token);
                                    }
                                } catch (JSONException e) {
                                    Log.e(TAG, e.toString());
                                }
                            }
                        }
                        if ((mChatterInstance != null) && (mChatterToken != null)) {
                            httpGet = new HttpGet(String.format(CHATTER_URL_LIKES, mChatterInstance, mSid));
                            httpGet.setHeader("Authorization", "OAuth " + mChatterToken);
                            if ((response = SonetHttpClient.httpResponse(mHttpClient, httpGet)) != null) {
                                try {
                                    JSONObject jobj = new JSONObject(response);
                                    if (jobj.getInt(Stotal) > 0) {
                                        JSONArray likes = jobj.getJSONArray("likes");
                                        for (int i = 0, i2 = likes.length(); i < i2; i++) {
                                            JSONObject like = likes.getJSONObject(i);
                                            if (like.getJSONObject(Suser).getString(Sid).equals(mAccountSid)) {
                                                mChatterLikeId = like.getString(Sid);
                                                liked = true;
                                                break;
                                            }
                                        }
                                    }
                                } catch (JSONException e) {
                                    Log.e(TAG, e.toString());
                                }
                            }
                            publishProgress(getString(liked ? R.string.unlike : R.string.like));
                            httpGet = new HttpGet(String.format(CHATTER_URL_COMMENTS, mChatterInstance, mSid));
                            httpGet.setHeader("Authorization", "OAuth " + mChatterToken);
                            response = SonetHttpClient.httpResponse(mHttpClient, httpGet);
                        } else {
                            response = null;
                        }
                        break;
                    }
                    return response;
                }
                return null;
            }

            @Override
            protected void onProgressUpdate(String... params) {
                mMessage.setText("");
                if (params != null) {
                    if ((mService == TWITTER) || (mService == IDENTICA)) {
                        mMessage.append(params[0]);
                    } else {
                        if (mService == LINKEDIN) {
                            if (params[0].equals(getString(R.string.uncommentable))) {
                                mSend.setEnabled(false);
                                mMessage.setEnabled(false);
                                mMessage.setText(R.string.uncommentable);
                            } else {
                                setCommentStatus(0, params[0]);
                            }
                        } else {
                            setCommentStatus(0, params[0]);
                        }
                    }
                }
                mMessage.setEnabled(true);
            }

            @Override
            protected void onPostExecute(String response) {
                if (response != null) {
                    int i2;
                    try {
                        JSONArray comments;
                        mSimpleDateFormat = null;
                        switch (mService) {
                        case TWITTER:
                            comments = new JSONArray(response);
                            if ((i2 = comments.length()) > 0) {
                                for (int i = 0; i < i2; i++) {
                                    JSONObject comment = comments.getJSONObject(i);
                                    if (comment.getString(Sin_reply_to_status_id) == mSid) {
                                        HashMap<String, String> commentMap = new HashMap<String, String>();
                                        commentMap.put(Statuses.SID, comment.getString(Sid));
                                        commentMap.put(Entities.FRIEND,
                                                comment.getJSONObject(Suser).getString(Sname));
                                        commentMap.put(Statuses.MESSAGE, comment.getString(Stext));
                                        commentMap.put(Statuses.CREATEDTEXT, Sonet.getCreatedText(
                                                parseDate(comment.getString(Screated_at), TWITTER_DATE_FORMAT),
                                                mTime24hr));
                                        commentMap.put(getString(R.string.like), getString(R.string.retweet));
                                        mComments.add(commentMap);
                                    }
                                }
                            } else {
                                noComments();
                            }
                            break;
                        case FACEBOOK:
                            comments = new JSONObject(response).getJSONArray(Sdata);
                            if ((i2 = comments.length()) > 0) {
                                for (int i = 0; i < i2; i++) {
                                    JSONObject comment = comments.getJSONObject(i);
                                    HashMap<String, String> commentMap = new HashMap<String, String>();
                                    commentMap.put(Statuses.SID, comment.getString(Sid));
                                    commentMap.put(Entities.FRIEND, comment.getJSONObject(Sfrom).getString(Sname));
                                    commentMap.put(Statuses.MESSAGE, comment.getString(Smessage));
                                    commentMap.put(Statuses.CREATEDTEXT,
                                            Sonet.getCreatedText(comment.getLong(Screated_time) * 1000, mTime24hr));
                                    commentMap.put(getString(R.string.like),
                                            getString(comment.has(Suser_likes) && comment.getBoolean(Suser_likes)
                                                    ? R.string.unlike
                                                    : R.string.like));
                                    mComments.add(commentMap);
                                }
                            } else {
                                noComments();
                            }
                            break;
                        case MYSPACE:
                            comments = new JSONObject(response).getJSONArray(Sentry);
                            if ((i2 = comments.length()) > 0) {
                                for (int i = 0; i < i2; i++) {
                                    JSONObject entry = comments.getJSONObject(i);
                                    HashMap<String, String> commentMap = new HashMap<String, String>();
                                    commentMap.put(Statuses.SID, entry.getString(ScommentId));
                                    commentMap.put(Entities.FRIEND,
                                            entry.getJSONObject(Sauthor).getString(SdisplayName));
                                    commentMap.put(Statuses.MESSAGE, entry.getString(Sbody));
                                    commentMap.put(Statuses.CREATEDTEXT,
                                            Sonet.getCreatedText(
                                                    parseDate(entry.getString(SpostedDate), MYSPACE_DATE_FORMAT),
                                                    mTime24hr));
                                    commentMap.put(getString(R.string.like), "");
                                    mComments.add(commentMap);
                                }
                            } else {
                                noComments();
                            }
                            break;
                        case LINKEDIN:
                            JSONObject jsonResponse = new JSONObject(response);
                            if (jsonResponse.has(S_total) && (jsonResponse.getInt(S_total) != 0)) {
                                comments = jsonResponse.getJSONArray(Svalues);
                                if ((i2 = comments.length()) > 0) {
                                    for (int i = 0; i < i2; i++) {
                                        JSONObject comment = comments.getJSONObject(i);
                                        JSONObject person = comment.getJSONObject(Sperson);
                                        HashMap<String, String> commentMap = new HashMap<String, String>();
                                        commentMap.put(Statuses.SID, comment.getString(Sid));
                                        commentMap.put(Entities.FRIEND,
                                                person.getString(SfirstName) + " " + person.getString(SlastName));
                                        commentMap.put(Statuses.MESSAGE, comment.getString(Scomment));
                                        commentMap.put(Statuses.CREATEDTEXT,
                                                Sonet.getCreatedText(comment.getLong(Stimestamp), mTime24hr));
                                        commentMap.put(getString(R.string.like), "");
                                        mComments.add(commentMap);
                                    }
                                } else {
                                    noComments();
                                }
                            }
                            break;
                        case FOURSQUARE:
                            comments = new JSONObject(response).getJSONObject(Sresponse).getJSONObject(Scheckin)
                                    .getJSONObject(Scomments).getJSONArray(Sitems);
                            if ((i2 = comments.length()) > 0) {
                                for (int i = 0; i < i2; i++) {
                                    JSONObject comment = comments.getJSONObject(i);
                                    JSONObject user = comment.getJSONObject(Suser);
                                    HashMap<String, String> commentMap = new HashMap<String, String>();
                                    commentMap.put(Statuses.SID, comment.getString(Sid));
                                    commentMap.put(Entities.FRIEND,
                                            user.getString(SfirstName) + " " + user.getString(SlastName));
                                    commentMap.put(Statuses.MESSAGE, comment.getString(Stext));
                                    commentMap.put(Statuses.CREATEDTEXT,
                                            Sonet.getCreatedText(comment.getLong(ScreatedAt) * 1000, mTime24hr));
                                    commentMap.put(getString(R.string.like), "");
                                    mComments.add(commentMap);
                                }
                            } else {
                                noComments();
                            }
                            break;
                        case IDENTICA:
                            comments = new JSONArray(response);
                            if ((i2 = comments.length()) > 0) {
                                for (int i = 0; i < i2; i++) {
                                    JSONObject comment = comments.getJSONObject(i);
                                    if (comment.getString(Sin_reply_to_status_id) == mSid) {
                                        HashMap<String, String> commentMap = new HashMap<String, String>();
                                        commentMap.put(Statuses.SID, comment.getString(Sid));
                                        commentMap.put(Entities.FRIEND,
                                                comment.getJSONObject(Suser).getString(Sname));
                                        commentMap.put(Statuses.MESSAGE, comment.getString(Stext));
                                        commentMap.put(Statuses.CREATEDTEXT, Sonet.getCreatedText(
                                                parseDate(comment.getString(Screated_at), TWITTER_DATE_FORMAT),
                                                mTime24hr));
                                        commentMap.put(getString(R.string.like), getString(R.string.repeat));
                                        mComments.add(commentMap);
                                    }
                                }
                            } else {
                                noComments();
                            }
                            break;
                        case GOOGLEPLUS:
                            //TODO: load comments
                            HttpPost httpPost = new HttpPost(GOOGLE_ACCESS);
                            List<NameValuePair> httpParams = new ArrayList<NameValuePair>();
                            httpParams.add(new BasicNameValuePair("client_id", GOOGLE_CLIENTID));
                            httpParams.add(new BasicNameValuePair("client_secret", GOOGLE_CLIENTSECRET));
                            httpParams.add(new BasicNameValuePair("refresh_token", mToken));
                            httpParams.add(new BasicNameValuePair("grant_type", "refresh_token"));
                            try {
                                httpPost.setEntity(new UrlEncodedFormEntity(httpParams));
                                if ((response = SonetHttpClient.httpResponse(mHttpClient, httpPost)) != null) {
                                    JSONObject j = new JSONObject(response);
                                    if (j.has(Saccess_token)) {
                                        String access_token = j.getString(Saccess_token);
                                        if ((response = SonetHttpClient.httpResponse(mHttpClient,
                                                new HttpGet(String.format(GOOGLEPLUS_ACTIVITY, GOOGLEPLUS_BASE_URL,
                                                        mSid, access_token)))) != null) {
                                            // check for a newer post, if it's the user's own, then set CLEARED=0
                                            try {
                                                JSONObject item = new JSONObject(response);
                                                if (item.has(Sobject)) {
                                                    JSONObject object = item.getJSONObject(Sobject);
                                                    if (object.has(Sreplies)) {
                                                        int commentCount = 0;
                                                        JSONObject replies = object.getJSONObject(Sreplies);
                                                        if (replies.has(StotalItems)) {
                                                            //TODO: load comments
                                                            commentCount = replies.getInt(StotalItems);
                                                        }
                                                    }
                                                }
                                            } catch (JSONException e) {
                                                Log.e(TAG, e.toString());
                                            }
                                        }
                                    }
                                }
                            } catch (UnsupportedEncodingException e) {
                                Log.e(TAG, e.toString());
                            } catch (JSONException e) {
                                Log.e(TAG, e.toString());
                            }
                            break;
                        case CHATTER:
                            JSONObject chats = new JSONObject(response);
                            if (chats.getInt(Stotal) > 0) {
                                comments = chats.getJSONArray(Scomments);
                                if ((i2 = comments.length()) > 0) {
                                    for (int i = 0; i < i2; i++) {
                                        JSONObject comment = comments.getJSONObject(i);
                                        HashMap<String, String> commentMap = new HashMap<String, String>();
                                        commentMap.put(Statuses.SID, comment.getString(Sid));
                                        commentMap.put(Entities.FRIEND,
                                                comment.getJSONObject(Suser).getString(Sname));
                                        commentMap.put(Statuses.MESSAGE,
                                                comment.getJSONObject(Sbody).getString(Stext));
                                        commentMap.put(Statuses.CREATEDTEXT, Sonet.getCreatedText(
                                                parseDate(comment.getString(ScreatedDate), CHATTER_DATE_FORMAT),
                                                mTime24hr));
                                        commentMap.put(getString(R.string.like), "");
                                        mComments.add(commentMap);
                                    }
                                } else {
                                    noComments();
                                }
                            } else {
                                noComments();
                            }
                            break;
                        }
                    } catch (JSONException e) {
                        Log.e(TAG, e.toString());
                    }
                } else {
                    noComments();
                }
                setListAdapter(new SimpleAdapter(SonetComments.this, mComments, R.layout.comment,
                        new String[] { Entities.FRIEND, Statuses.MESSAGE, Statuses.CREATEDTEXT,
                                getString(R.string.like) },
                        new int[] { R.id.friend, R.id.message, R.id.created, R.id.like }));
                if (loadingDialog.isShowing())
                    loadingDialog.dismiss();
            }

            private void noComments() {
                HashMap<String, String> commentMap = new HashMap<String, String>();
                commentMap.put(Statuses.SID, "");
                commentMap.put(Entities.FRIEND, "");
                commentMap.put(Statuses.MESSAGE, getString(R.string.no_comments));
                commentMap.put(Statuses.CREATEDTEXT, "");
                commentMap.put(getString(R.string.like), "");
                mComments.add(commentMap);
            }

            private long parseDate(String date, String format) {
                if (date != null) {
                    // hack for the literal 'Z'
                    if (date.substring(date.length() - 1).equals("Z")) {
                        date = date.substring(0, date.length() - 2) + "+0000";
                    }
                    Date created = null;
                    if (format != null) {
                        if (mSimpleDateFormat == null) {
                            mSimpleDateFormat = new SimpleDateFormat(format, Locale.ENGLISH);
                            // all dates should be GMT/UTC
                            mSimpleDateFormat.setTimeZone(sTimeZone);
                        }
                        try {
                            created = mSimpleDateFormat.parse(date);
                            return created.getTime();
                        } catch (ParseException e) {
                            Log.e(TAG, e.toString());
                        }
                    } else {
                        // attempt to parse RSS date
                        if (mSimpleDateFormat != null) {
                            try {
                                created = mSimpleDateFormat.parse(date);
                                return created.getTime();
                            } catch (ParseException e) {
                                Log.e(TAG, e.toString());
                            }
                        }
                        for (String rfc822 : sRFC822) {
                            mSimpleDateFormat = new SimpleDateFormat(rfc822, Locale.ENGLISH);
                            mSimpleDateFormat.setTimeZone(sTimeZone);
                            try {
                                if ((created = mSimpleDateFormat.parse(date)) != null) {
                                    return created.getTime();
                                }
                            } catch (ParseException e) {
                                Log.e(TAG, e.toString());
                            }
                        }
                    }
                }
                return System.currentTimeMillis();
            }
        };
        loadingDialog.setMessage(getString(R.string.loading));
        loadingDialog.setCancelable(true);
        loadingDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                if (!asyncTask.isCancelled())
                    asyncTask.cancel(true);
            }
        });
        loadingDialog.setButton(ProgressDialog.BUTTON_NEGATIVE, getString(android.R.string.cancel),
                new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });
        loadingDialog.show();
        asyncTask.execute();
    }

    @Override
    public void onCancel(DialogInterface dialog) {
    }
}