#include "android.h"
#include "SH_server_base.h"
#include <QDebug>
#include <QMessageBox>
#include <QApplication>
#include <QFileInfo>
#include <QLocale>
#include <QTimer>
#include "piqt.h"
#ifdef ANDROID
#  include "pisysteminfo.h"
#  include <QAndroidJniObject>
#  include <QAndroidService>
#  include <QtAndroid>
#endif


AndroidLayer::AndroidLayer(): QObject(), settings("SHS", "Pult") {
#ifdef ANDROID
	nid = settings.value("android.notification_id", 0).toInt();
	ai_eth.setReadAddress("127.0.0.1", SHNetworkTypes::interfacePort);
	ai_eth.setSendAddress("127.0.0.1", SHNetworkTypes::interfacePort + 1);
	ai_eth.startThreadedRead();
	CONNECTU(&ai_eth, threadedReadEvent, this, interfaceReceived);
#endif
}


AndroidLayer::~AndroidLayer() {
#ifdef ANDROID
	ai_eth.stopThreadedRead();
#endif
}


void AndroidLayer::init() {
#ifdef ANDROID
	PISystemInfo::instance()->hostname = Q2PIString(QAndroidJniObject::getStaticObjectField<jstring>("android/os/Build", "MODEL").toString());
#endif
}


void AndroidLayer::sendLang() {
#ifdef ANDROID
	PIByteArray ba;
	qDebug() << "send lang" << QLocale::system().name().left(2);
	ba << int(2) << Q2PIString(QLocale::system().name().left(2));
	ai_eth.send(ba);
#endif
}


void AndroidLayer::queryIntent() {
#ifdef ANDROID
	QtAndroid::runOnAndroidThreadSync([](){
		QAndroidJniObject::callStaticMethod<void>("org/SHS/Pult/MainActivity", "queryIntent", "()V");
	});
#endif
}


AndroidLayer * AndroidLayer::instance() {
	static AndroidLayer * ret = new AndroidLayer();
	return ret;
}


void AndroidLayer::openAPK(QString path) {
#ifdef ANDROID
	QtAndroid::runOnAndroidThreadSync([path](){
		QAndroidJniObject::callStaticMethod<void>("org/SHS/Pult/MainActivity",
												  "execPackage",
												  "(Ljava/lang/String;)V",
												  QAndroidJniObject::fromString(path).object<jstring>());
	});
#endif
}


#ifdef ANDROID
void AndroidLayer::interfaceReceivedQ(QByteArray qba) {
	PIByteArray ba = Q2PIByteArray(qba);
	if (ba.size() < 4) return;
	int type = 0;
	ba >> type;
	qDebug() << "interface rec" << type;
	if (type == 3)
		sendLang();
}
#endif


void AndroidLayer::connectedToServer(PacketServerInfo si) {
#ifdef ANDROID
	PIByteArray ba;
	ba << int(1);
	ba.append(si.toByteArray());
	ai_eth.send(ba);
#endif
}


void AndroidLayer::startService() {
#ifdef ANDROID
	QAndroidJniObject::callStaticMethod<void>("org/SHS/Pult/MainService",
											  "start",
											  "(Landroid/content/Context;)V",
											  QtAndroid::androidActivity().object());
#endif
}


void AndroidLayer::notify(QString s) {
	//qDebug() << "notify" << s;
#ifdef ANDROID
	settings.setValue("android.notification_id", ++nid);
	QAndroidJniObject::callStaticMethod<void>("org/SHS/Pult/MainService",
											  "notify",
											  "(ILjava/lang/String;)V",
											  nid,
											  QAndroidJniObject::fromString(s).object<jstring>());
#endif
}


void AndroidLayer::status(QString s) {
	if (last_status == s) return;
	last_status = s;
#ifdef ANDROID
	QAndroidJniObject::callStaticMethod<void>("org/SHS/Pult/MainService",
											  "status",
											  "(Ljava/lang/String;)V",
											  QAndroidJniObject::fromString(s).object<jstring>());
#endif
}


void AndroidLayer::packageExists(QString path) {
	QMessageBox::information(0, "SHS Pult", "Please, install new package");
	openAPK(path);
	qApp->exit();
}


void AndroidLayer::packageReady(QString path, bool forced) {
	QString msg = tr("New package downloaded to\n\"%1\"").arg(path);
	if (!forced)
		msg += "\n" + tr("Please, install new package");
	QMessageBox::information(0, "SHS Pult", msg);
	if (forced) return;
	openAPK(QFileInfo(path).fileName());
	qApp->exit();
}


void AndroidLayer::showDialog(QString def) {
#ifdef ANDROID
	QtAndroid::runOnAndroidThreadSync([def](){
		QAndroidJniObject::callStaticMethod<void>("org/SHS/Pult/MainActivity", "execDialog", "(Ljava/lang/String;)V",
												  QAndroidJniObject::fromString(def).object<jstring>());
	});
#endif
}


#ifdef ANDROID
#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT void JNICALL Java_org_SHS_Pult_Bridge_returnDialogResult(JNIEnv , jobject , jstring results) {
	QString ret = QAndroidJniObject(results).toString();
	QMetaObject::invokeMethod(ANDROID_LAYER, "dialogDone", Qt::QueuedConnection, Q_ARG(QString, ret));
}

JNIEXPORT void JNICALL Java_org_SHS_Pult_Bridge_activityStarted(JNIEnv , jobject , jstring results) {
	QString ret = QAndroidJniObject(results).toString();
	//qDebug() << "activityStarted" << ret;
	QMetaObject::invokeMethod(ANDROID_LAYER, "activityStarted", Qt::QueuedConnection, Q_ARG(QString, ret));
}

#ifdef __cplusplus
}
#endif
#endif
