package indoor.java;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Debug;
import android.util.Log;
import java.util.List;
import java.io.ByteArrayOutputStream;

public class WiFi {

    private static Activity act;
    private static WifiManager manager;
    private static BroadcastReceiver receiver;

	private static Thread tHeartbeat = null;
	private static long lastScanStartTS = 0;

    /** called when a scan is completed successfully */
    public static native void onScanComplete(final byte[] result);

    /**
     * start WiFi scanning in the background.
     * will call onScanComplete() once a scan is available
     */
    public static int start() {

        Log.d("wifi", "start()");

        MyActivity act = MyActivity.act;
        manager = (WifiManager) act.getSystemService(Context.WIFI_SERVICE);

		// reset();

        WiFi.receiver = new BroadcastReceiver() {
            public final void onReceive(final Context context, final Intent intent) {
                final byte[] result = serialize(manager.getScanResults());
				triggerOneScan();
                WiFi.onScanComplete(result);
            }
        };

        // register scan callback
        act.registerReceiver(WiFi.receiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

        // start the first scan
		triggerOneScan();



		// if the scan result takes longer than X milliseconds,
		// trigger another-scan to ensure nothing is stuck
		final Runnable r = new Runnable() {
			public void run() {
				while(true) {
					final long ts = System.currentTimeMillis();
					final long diff = ts - lastScanStartTS;
					if (diff > 1000) { triggerOneScan(); }
					try {Thread.sleep(200);} catch (final Exception e) {;}
				}
			}
		};

	    // start the heartbeat once
		if (tHeartbeat == null) {
			tHeartbeat = new Thread(r);
			tHeartbeat.start();
		}

		return 1337;

    }

    /** convert the given scan-result to a binary byte[] representation */
    private static byte[] serialize(final List<ScanResult> lst) {
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        try {
            for (final ScanResult res : lst) {
                baos.write(res.BSSID.getBytes());
                baos.write((byte)res.level);
                baos.write((byte)0);
                baos.write((byte)0);
            }
        } catch (final Exception e) {;}
        return baos.toByteArray();
    }



    /** reset the WiFi subsystem (better scanning) */
    private static void reset() {
        WiFi.manager.disconnect();
        WiFi.manager.createWifiLock(manager.WIFI_MODE_SCAN_ONLY, "Indoor");
        //WiFi.manager.setWifiEnabled(false);
        //WiFi.manager.setWifiEnabled(true);
        WiFi.manager.disconnect();
        WiFi.manager.disconnect();
        WiFi.manager.disconnect();
        WiFi.manager.disconnect();
        WiFi.manager.disconnect();
        WiFi.manager.disconnect();
    }

    /** try to trigger one scan process */
    private static void triggerOneScan() {

        Log.d("wifi", "triggerOneScan()");

        try {
            if(!manager.startScan()) {throw new RuntimeException("Cant start WiFi!");}
			lastScanStartTS = System.currentTimeMillis();
        }catch (final Exception e) {
            throw new RuntimeException(e);
        }

    }


}
