package live.greiner.autophono;

import java.awt.AWTException;
import java.awt.Image;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Level;
import java.util.logging.Logger;
import se.vidstige.jadb.JadbConnection;
import se.vidstige.jadb.JadbDevice;
import se.vidstige.jadb.JadbException;

public class AutoPhono {
    
    public Status state = Status.INITIAL;
    public Image images[] = {
        Toolkit.getDefaultToolkit().createImage("img/apgrey.png"),
        Toolkit.getDefaultToolkit().createImage("img/apnorm.png"),
        Toolkit.getDefaultToolkit().createImage("img/apgreen.png")
    };
    public PopupMenu[] popMenues = new PopupMenu[2];
    
    
    public AutoPhono(){
        System.out.println("CONSTRUCTOR START");
        final PopupMenu popup1 = new PopupMenu();
        MenuItem exitItem1 = new MenuItem("Stop");
        popup1.add(exitItem1);
        
        final PopupMenu popup2 = new PopupMenu();
        MenuItem openItem = new MenuItem("Open");
        MenuItem exitItem2 = new MenuItem("Stop");
        popup2.add(openItem);
        popup2.addSeparator();
        popup2.add(exitItem2);
        
        ActionListener alExit = (ActionEvent e) -> {
            SystemTray tray = SystemTray.getSystemTray();
            for(TrayIcon icon:tray.getTrayIcons()){
                tray.remove(icon);
            }
            System.exit(0);
        };
        ActionListener alOpen = (ActionEvent e) -> {
            startScreenMirror();
        };
        
        exitItem1.addActionListener(alExit);
        exitItem2.addActionListener(alExit);
        openItem.addActionListener(alOpen);
        
        popMenues[0] = popup1;
        popMenues[1] = popup2;
        System.out.println("CONSTRUCTOR END");
    }
    
    public static void main(String[] args) {
        
        AutoPhono ap = new AutoPhono();
        System.out.println("CREATED AP");
        ap.startAdbServer();
        System.out.println("STARTED SERVER");
        TrayIcon icon = ap.startTrayIcon();
        
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                System.out.println("Checking");
                Status pre = ap.state;
                ap.checkDeviceConnected();
                
                if(ap.state == Status.CONNECTED){
                    if(pre == Status.TRAY_ICON_STARTED || pre == Status.UNCONNECTED){
                        System.out.println("Device Connected");
                        icon.setToolTip("AutoPhoner - Connected");
                        icon.setImage(ap.images[1]);
                        icon.setPopupMenu(ap.popMenues[1]);
                        ap.startScreenMirror();
                        System.out.println("Screen Mirror started");
                    }
                }
                if(ap.state == Status.UNCONNECTED && pre == Status.CONNECTED){
                    System.out.println("Device Disconnected");
                    icon.setImage(ap.images[0]);
                    icon.setPopupMenu(ap.popMenues[0]);
                }
            }
        };
        
        Timer timer = new Timer("Timer");
        long delay = 300L;
        timer.scheduleAtFixedRate(task, delay,10000);
    }
    
    private boolean startAdbServer(){
        try {
            String command = "cmd start cmd.exe /K \"cd tools/adb && adb devices\"";
            Process child = Runtime.getRuntime().exec(command);
            OutputStream out = child.getOutputStream();
            InputStream in = child.getInputStream();
            String validResult = "List of devices attached";
            String input = "";
            long start = System.currentTimeMillis();
            while(start + 10000 > System.currentTimeMillis()){
                if(in.available()>0){
                    input += (char)in.read();
                }
                if(input.equals(validResult)){
                    state = Status.ADB_STARTED;
                    return true;
                }
            }
        } catch (IOException ex) {
            return false;
        }
        return false;
    }
    
    private boolean startScreenMirror(){
        try {
            String command2 = "cmd -c start cmd.exe /K \"cd tools/scrcpy && dir && scrcpy.exe -S\"";
            Process child = Runtime.getRuntime().exec(command2);
            OutputStream out = child.getOutputStream();
            InputStream in = child.getInputStream();
            long start = System.currentTimeMillis();
            while(start + 10000 > System.currentTimeMillis()){
                if(in.available()>0){
                    System.out.print((char)in.read());
                }
            }
        } catch (IOException ex) {
            System.out.println(ex);
            return false;
        }
        return false;
    }
    
    private TrayIcon startTrayIcon(){
        
        try {
            if (!SystemTray.isSupported()) {
                return null;
            }
            
            TrayIcon trayIcon = new TrayIcon(images[0]);
            SystemTray tray = SystemTray.getSystemTray();
            trayIcon.setImageAutoSize(true);
            trayIcon.setToolTip("AutoPhoner - Searching");
            trayIcon.setPopupMenu(popMenues[0]);
            
            
            tray.add(trayIcon);
            state = Status.TRAY_ICON_STARTED;
            return trayIcon;
        } catch (AWTException ex) {
            Logger.getLogger(AutoPhono.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }

    private boolean checkDeviceConnected(){
        
        JadbConnection jadb = new JadbConnection();
        System.out.println("CREATED CONNECTION");    
        List<JadbDevice> devices;
        try {
            System.out.println("GETTING DEVICES");
            devices = jadb.getDevices();
            System.out.println("GOT DEVICES");
            if(devices.size() > 0){
                state = Status.CONNECTED;
                return true;
            }
            state = Status.UNCONNECTED;
            return false;
        } catch (IOException ex) {
            Logger.getLogger(AutoPhono.class.getName()).log(Level.SEVERE, null, ex);
        } catch (JadbException ex) {
            Logger.getLogger(AutoPhono.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("GOT JADB EXCEPTION");
        }
        state = Status.UNCONNECTED;
        return false;
    }
}
