package com.stardust.scriptdroid.ui.console;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.view.WindowManager;
import com.stardust.autojs.runtime.ScriptInterface;
import com.stardust.autojs.runtime.ScriptInterruptedException;
import com.stardust.autojs.runtime.api.AbstractConsole;
import com.stardust.autojs.runtime.api.Console;
import com.stardust.enhancedfloaty.FloatyService;
import com.stardust.enhancedfloaty.ResizableExpandableFloatyWindow;
import com.stardust.scriptdroid.R;
import com.stardust.scriptdroid.autojs.AutoJs;
import com.stardust.scriptdroid.external.floatingwindow.FloatingWindowManger;
import com.stardust.util.UiHandler;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
/**
* Created by Stardust on 2017/5/2.
*/
public class StardustConsole extends AbstractConsole {
public static class Log {
public int level;
public CharSequence content;
public Log(int level, CharSequence content) {
this.level = level;
this.content = content;
}
}
public interface LogListener {
void onNewLog(Log log);
void onLogClear();
}
private final Console GLOBAL_CONSOLE = AutoJs.getInstance().getScriptEngineService().getGlobalConsole();
private List<Log> mLogs = new ArrayList<>();
private ResizableExpandableFloatyWindow mFloatyWindow;
private ConsoleFloaty mConsoleFloaty;
private LogListener mLogListener;
private UiHandler mUiHandler;
private BlockingQueue<String> mInput = new ArrayBlockingQueue<>(1);
private ConsoleView mConsoleView;
private volatile boolean mShown = false;
public StardustConsole(UiHandler uiHandler) {
mUiHandler = uiHandler;
mConsoleFloaty = new ConsoleFloaty(this);
mFloatyWindow = new ResizableExpandableFloatyWindow(mConsoleFloaty);
}
public void setConsoleView(ConsoleView consoleView) {
mConsoleView = consoleView;
setLogListener(consoleView);
synchronized (this) {
this.notify();
}
}
public void setLogListener(LogListener logListener) {
mLogListener = logListener;
}
public List<Log> getLogs() {
return mLogs;
}
@Override
public void println(int level, CharSequence charSequence) {
Log log = new Log(level, charSequence + "\n");
mLogs.add(log);
GLOBAL_CONSOLE.println(level, charSequence);
if (mLogListener != null) {
mLogListener.onNewLog(log);
}
}
@Override
public void write(int level, CharSequence charSequence) {
Log log = new Log(level, charSequence);
mLogs.add(log);
GLOBAL_CONSOLE.print(level, charSequence);
if (mLogListener != null) {
mLogListener.onNewLog(log);
}
}
@Override
public void clear() {
mLogs.clear();
if (mLogListener != null) {
mLogListener.onLogClear();
}
}
@Override
public void show() {
if (!FloatingWindowManger.hasFloatingWindowPermission(mUiHandler.getContext())) {
FloatingWindowManger.goToFloatingWindowPermissionSetting();
mUiHandler.toast(R.string.text_no_floating_window_permission);
}
startFloatyService();
mUiHandler.post(new Runnable() {
@Override
public void run() {
try {
FloatyService.addWindow(mFloatyWindow);
} catch (WindowManager.BadTokenException e) {
e.printStackTrace();
mUiHandler.toast(R.string.text_no_floating_window_permission);
}
}
});
mShown = true;
}
private void startFloatyService() {
Context context = mUiHandler.getContext();
context.startService(new Intent(context, FloatyService.class));
}
@Override
public void hide() {
try {
mFloatyWindow.close();
} catch (IllegalArgumentException ignored) {
}
mShown = false;
}
@ScriptInterface
public String rawInput() {
if (mConsoleView == null) {
if (!mShown) {
show();
}
waitConsoleView();
}
mConsoleView.showEditText();
try {
return mInput.take();
} catch (InterruptedException e) {
throw new ScriptInterruptedException();
}
}
private void waitConsoleView() {
synchronized (this) {
try {
this.wait();
} catch (InterruptedException e) {
throw new ScriptInterruptedException();
}
}
}
@ScriptInterface
public String rawInput(Object data, Object... param) {
log(data, param);
return rawInput();
}
boolean submitInput(@NonNull CharSequence input) {
return mInput.offer(input.toString());
}
@Override
public void setTitle(CharSequence title) {
mConsoleFloaty.setTitle(title);
}
}