/*
* Copyright (C) 2005-2009 Team XBMC
* http://xbmc.org
*
* 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 2, 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 XBMC Remote; see the file license. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
* http://www.gnu.org/copyleft/gpl.html
*
*/
package org.xbmc.android.remote.presentation.controller;
import java.io.IOException;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import org.apache.http.HttpException;
import org.xbmc.android.remote.business.Command;
import org.xbmc.android.remote.presentation.activity.HostSettingsActivity;
import org.xbmc.android.remote.presentation.activity.SettingsActivity;
import org.xbmc.android.util.HostFactory;
import org.xbmc.android.util.WifiHelper;
import org.xbmc.api.business.INotifiableManager;
import org.xbmc.api.object.Host;
import org.xbmc.httpapi.NoNetworkException;
import org.xbmc.httpapi.NoSettingsException;
import org.xbmc.httpapi.WrongDataFormatException;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
/**
* Every controller should extend this class. Takes care of the messages.
*
* @author Team XBMC
*/
public abstract class AbstractController {
public static final int MAX_WAIT_FOR_WIFI = 20;
public static final String TAG = "AbstractController";
protected Activity mActivity;
protected Handler mHandler;
private boolean mDialogShowing = false;
protected boolean mPaused = true;
private Thread mWaitForWifi;
public void onCreate(Activity activity, Handler handler) {
mActivity = activity;
mHandler = handler;
HostFactory.readHost(activity.getApplicationContext());
//ClientFactory.resetClient(HostFactory.host);
}
public void onWrongConnectionState(int state, final INotifiableManager manager, final Command<?> source) {
final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
switch (state) {
case WifiHelper.WIFI_STATE_DISABLED:
builder.setTitle("Wifi disabled");
builder.setMessage("This host is Wifi only. Should I activate Wifi?");
builder.setNeutralButton("Activate Wifi", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final ProgressDialog pd = new ProgressDialog(mActivity);
pd.setCancelable(true);
pd.setTitle("Activating Wifi");
pd.setMessage("Please wait while Wifi is activated.");
pd.show();
(new Thread() {
public void run() {
final WifiHelper helper = WifiHelper.getInstance(mActivity);
helper.enableWifi(true);
int wait = 0;
while(wait <= MAX_WAIT_FOR_WIFI * 1000 && helper.getWifiState() != WifiHelper.WIFI_STATE_ENABLED) {
try {
sleep(500);
wait += 500;
} catch (InterruptedException e) {}
}
manager.retryAll();
pd.cancel();
mDialogShowing = false;
}
}).start();
}
});
showDialog(builder);
break;
case WifiHelper.WIFI_STATE_ENABLED:
final Host host = HostFactory.host;
final WifiHelper helper = WifiHelper.getInstance(mActivity);
final String msg;
if(host != null && host.access_point != null && !host.access_point.equals("")) {
helper.connect(host);
msg = "Connecting to " + host.access_point + ". Please wait";
} else {
msg = "Waiting for Wifi to connect to your LAN.";
}
final ProgressDialog pd = new ProgressDialog(mActivity);
pd.setCancelable(true);
pd.setTitle("Connecting");
pd.setMessage(msg);
mWaitForWifi = new Thread() {
public void run() {
mDialogShowing = true;
pd.show();
(new Thread( ) {
public void run() {
int wait = 0;
while(wait <= MAX_WAIT_FOR_WIFI * 1000 && helper.getWifiState() != WifiHelper.WIFI_STATE_CONNECTED) {
try {
sleep(500);
wait += 500;
} catch (InterruptedException e) {}
}
pd.cancel();
mDialogShowing = false;
}
}).start();
pd.setOnDismissListener(new OnDismissListener() {
public void onDismiss(DialogInterface dialog) {
if(helper.getWifiState() != WifiHelper.WIFI_STATE_CONNECTED) {
builder.setTitle("Wifi doesn't seem to connect");
builder.setMessage("You can open the Wifi settings or wait "+ MAX_WAIT_FOR_WIFI +" seconds");
builder.setNeutralButton("Wifi Settings", new OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
mDialogShowing = false;
mActivity.startActivity(new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK));
}
});
builder.setCancelable(true);
builder.setNegativeButton("Wait", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mDialogShowing = false;
mActivity.runOnUiThread(mWaitForWifi); //had to make the Thread a field because of this line
}
});
mActivity.runOnUiThread(new Runnable() {
public void run() {
final AlertDialog alert = builder.create();
try {
if (!mDialogShowing) {
alert.show();
mDialogShowing = true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
});
}
};
mActivity.runOnUiThread(mWaitForWifi);
}
}
public void onError(Exception exception) {
if (mActivity == null) {
return;
}
final AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
try {
throw exception;
} catch (NoSettingsException e) {
builder.setTitle("No hosts detected");
builder.setMessage(e.getMessage());
builder.setNeutralButton("Settings", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final Intent intent = new Intent(mActivity, HostSettingsActivity.class);
// intent.putExtra(SettingsActivity.JUMP_TO, SettingsActivity.JUMP_TO_INSTANCES);
mActivity.startActivity(intent);
mDialogShowing = false;
}
});
} catch (NoNetworkException e) {
builder.setTitle("No Network");
builder.setMessage(e.getMessage());
builder.setCancelable(true);
builder.setNeutralButton("Settings", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mActivity.startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
mDialogShowing = false;
}
});
} catch (WrongDataFormatException e) {
builder.setTitle("Internal Error");
builder.setMessage("Wrong data from HTTP API; expected '" + e.getExpected() + "', got '" + e.getReceived() + "'.");
} catch (SocketTimeoutException e) {
builder.setTitle("Socket Timeout");
builder.setMessage("Make sure XBMC webserver is enabled and XBMC is running.");
builder.setNeutralButton("Settings", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mActivity.startActivity(new Intent(mActivity, SettingsActivity.class));
mDialogShowing = false;
}
});
} catch (ConnectException e) {
builder.setTitle("Connection Refused");
builder.setMessage("Make sure XBMC webserver is enabled and XBMC is running.");
builder.setNeutralButton("Settings", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mActivity.startActivity(new Intent(mActivity, SettingsActivity.class));
mDialogShowing = false;
}
});
} catch (IOException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Network unreachable")) {
builder.setTitle("No network");
builder.setMessage("XBMC Remote needs local network access. Please make sure that your wireless network is activated. You can click on the Settings button below to directly access your network settings.");
builder.setNeutralButton("Settings", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mActivity.startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
mDialogShowing = false;
}
});
} else {
builder.setTitle("I/O Exception (" + e.getClass().getCanonicalName() + ")");
if (e.getMessage() != null) {
builder.setMessage(e.getMessage().toString());
}
Log.e(TAG, e.getStackTrace().toString());
}
} catch (HttpException e) {
if (e.getMessage().startsWith("401")) {
builder.setTitle("HTTP 401: Unauthorized");
builder.setMessage("The supplied username and/or password is incorrect. Please check your settings.");
builder.setNeutralButton("Settings", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mActivity.startActivity(new Intent(mActivity, SettingsActivity.class));
mDialogShowing = false;
}
});
}
} catch (Exception e) {
final String name = e.getClass().getName();
builder.setTitle(name.substring(name.lastIndexOf(".") + 1));
builder.setMessage(e.getMessage());
} finally {
exception.printStackTrace();
}
showDialog(builder);
}
protected void showDialog(final AlertDialog.Builder builder) {
builder.setCancelable(true);
builder.setNegativeButton("Close", new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
mDialogShowing = false;
// ConnectionManager.resetClient();
}
});
mActivity.runOnUiThread(new Runnable() {
public void run() {
final AlertDialog alert = builder.create();
try {
if (!mDialogShowing) {
alert.show();
mDialogShowing = true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
protected void showDialog(int id){
mActivity.showDialog(id);
}
protected void dismissDialog(int id){
mActivity.dismissDialog(id);
}
public void onMessage(final String message) {
mActivity.runOnUiThread(new Runnable() {
public void run() {
Toast toast = Toast.makeText(mActivity, message, Toast.LENGTH_LONG);
toast.show();
}
});
}
public void runOnUI(Runnable action) {
if (mHandler != null) {
//Log.i(TAG, "### running on UI at " + mActivity.getClass().getSimpleName());
mHandler.post(action);
//mActivity.runOnUiThread(action);
}
}
public void onActivityPause() {
// mActivity = null;
mPaused = true;
}
public void onActivityResume(Activity activity) {
mActivity = activity;
mPaused = false;
}
}