package fundamental.games.metropolis.fragments;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import java.io.Serializable;

import fundamental.games.metropolis.R;
import fundamental.games.metropolis.activities.GameOverviewActivity;
import fundamental.games.metropolis.activities.SetUpGameActivity;
import fundamental.games.metropolis.adapters.BluetoothConnectedDevicesAdapter;
import fundamental.games.metropolis.adapters.NotificationsAdapter;
import fundamental.games.metropolis.adapters.SetUpGamePagerAdapter;
import fundamental.games.metropolis.connection.bluetooth.BluetoothConnection;
import fundamental.games.metropolis.connection.bluetooth.BluetoothListener;
import fundamental.games.metropolis.connection.bluetooth.BluetoothServer;
import fundamental.games.metropolis.connection.global.GUIConnector;
import fundamental.games.metropolis.connection.global.LogicConnector;
import fundamental.games.metropolis.connection.global.MessagesQueue;
import fundamental.games.metropolis.connection.serializable.PlayerInitData;
import fundamental.games.metropolis.connection.serializable.StartGame;
import fundamental.games.metropolis.widgets.BasicButton;

public class SetUpBluetoothServerFragment extends SetUpGamePageFragment
{
    private ListView list;
    private BluetoothConnectedDevicesAdapter adapter;

    private BasicButton button1;
    private BasicButton button2;
    private BasicButton button3;

    //*****************************

    @Override
    public void onStart()
    {
        super.onStart();
    }

    //*****************************

    @Override
    public void onResume()
    {
        super.onResume();
    }

    //*****************************

    @Override
    public void onPause()
    {
        super.onPause();
    }

    //*****************************

    @Override
    public void onStop()
    {
        super.onStop();
    }

    //*****************************

    @Override
    public void onDestroy()
    {
        super.onDestroy();
    }

    //*****************************

    @Override
    public void onAttach(Activity activity) { super.onAttach(activity); }

    //*****************************

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle bundle)
    {
        return inflater.inflate(R.layout.set_up_bluetooth_server, group, false);
    }

    //*****************************

    @Override
    public void onActivityCreated(Bundle bundle)
    {
        super.onActivityCreated(bundle);

        button1 = (BasicButton)getActivity().findViewById(R.id.start_server_button);
        button2 = (BasicButton)getActivity().findViewById(R.id.start_game_button);
        button3 = (BasicButton)getActivity().findViewById(R.id.stop_server_button);

        button1.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                startServer();
            }
        });

        button2.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                startGame();
            }
        });

        button3.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                stopServer();
            }
        });

        button2.lockButton();
        button3.lockButton();

        adapter = new BluetoothConnectedDevicesAdapter(getActivity().getApplicationContext(), getActivity());
        list = (ListView)getActivity().findViewById(R.id.connected_list);
        list.setAdapter(adapter);
    }

    //*****************************

    @Override
    public void onDestroyView()
    {
        super.onDestroyView();
    }

    //*****************************

    @Override
    public void onDetach()
    {
        super.onDetach();
    }

    //*****************************

    @Override
    public ViewGroup getFragmentView()
    {
        return (ViewGroup)getActivity().findViewById(R.id.bluetooth_frag);
    }

    //**********************************

    @Override
    public boolean returnKeyClicked()
    {
        ((SetUpGameActivity)getActivity()).changePage(SetUpGamePagerAdapter.BLUETOOTH, SetUpGamePagerAdapter.CHOOSE);
        return true;
    }

    //**********************************

    public void restartFragment()
    {
        button1.unlockButton();
        button2.lockButton();
        button3.lockButton();
        hideInfoLabel();

        adapter.clear();
    }

    //**********************************

    public void restartFragment(String errorMessage)
    {
        restartFragment();
        setErrorOn(errorMessage);
    }

    //***********************************

    public void startServer()
    {
        adapter.clear();
        BluetoothServer.getInstance().removeAllListeners();
        BluetoothServer.getInstance().stopAllConnections();

        BluetoothListener listener = new BluetoothListener()
        {
            boolean bluetoothOn = false;
            boolean visibilityOn = false;

            @Override
            public void actionCanceled()
            {

                Log.d("ERROR", "Canceling: " + bluetoothOn + " " + visibilityOn);
                button2.lockButton();
                button3.lockButton();
                button1.unlockButton();

                if(!bluetoothOn)
                {
                    setErrorOn("Bluetooth turning on canceled.");
                    BluetoothServer.getInstance().removeBluetoothListener(this);
                    return;
                }

                if(!visibilityOn)
                {
                    setErrorOn("Visibility turning on canceled.");
                    BluetoothServer.getInstance().removeBluetoothListener(this);
                    return;
                }
            }

            @Override
            public void bluetoothStateChanged(int bluetoothState)
            {
                if(bluetoothState == BluetoothAdapter.STATE_ON)
                {
                    bluetoothOn = true;
                    if(BluetoothServer.getInstance().turnVisibilityOn(getActivity()))
                    {
                        //visibilityOn = true;
                        visibilityChanged(BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE);
                    }
                    else
                        setProgressOn("Visibility turning on...");
                }
                else if(bluetoothState == BluetoothAdapter.STATE_TURNING_ON)
                {
                    setProgressOn("Bluetooth turning on...");
                }
                else if(bluetoothState == BluetoothAdapter.STATE_TURNING_OFF)
                {
                    button2.lockButton();
                    button3.lockButton();
                    button1.unlockButton();
                    setErrorOn("Bluetooth turned off.");
                    BluetoothServer.getInstance().removeBluetoothListener(this);
                }
            }

            @Override
            public void visibilityChanged(int state)
            {
                if(state == BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE)
                {
                    if(visibilityOn)
                        return;
                    visibilityOn = true;
                    setProgressOn("Waiting for players...");
                    BluetoothServer.getInstance().startNewServerConnection();
                }
                else
                {
                    visibilityOn = false;
                    setErrorOn("Server Invisible.");
                    button2.lockButton();
                    button3.lockButton();
                    button1.unlockButton();
                    BluetoothServer.getInstance().removeBluetoothListener(this);
                    adapter.clear();
                }
            }

            @Override
            public void connectionAdded(BluetoothConnection connection)
            {
                adapter.addItem(connection);
                Log.d("FLUSH", BluetoothServer.getInstance().getConnectionsNumber() + " ");
                if(BluetoothServer.getInstance().getConnectionsNumber() < 4)
                {
                    BluetoothServer.getInstance().startNewServerConnection();
                    button2.unlockButton();
                }
                else
                {
                    button2.unlockButton();
                    hideInfoLabel();
                }
            }

            @Override
            public void connectionRemoved(BluetoothConnection connection)
            {
                adapter.removeItem(connection);
            }
        };

        adapter.addItem(BluetoothServer.getInstance().addServerConnection());
        BluetoothServer.getInstance().addBluetoothListener(listener);


        BluetoothAdapter.getDefaultAdapter().cancelDiscovery();

        if(BluetoothServer.getInstance().turnBluetoothOn(getActivity()))
            listener.bluetoothStateChanged(BluetoothAdapter.STATE_ON);
        button1.lockButton();
        button2.lockButton();
        button3.unlockButton();
    }

    //************************************

    public void stopServer()
    {
        BluetoothServer.getInstance().removeAllListeners();
        BluetoothServer.getInstance().stopAllConnections();
        BluetoothServer.getInstance().stopServerConnection();

        adapter.clear();

        button1.unlockButton();
        button2.lockButton();
        button3.lockButton();
        hideInfoLabel();
    }

    //***********************************

    public void startGame()
    {
        setProgressOn("Starting Game...");
        GUIConnector.reset();
        LogicConnector.reset();

        //TODO
        //- Logic init
        //- GUI pass control
        //- process init messages
        //- clean up
        //- all in new thread

        synchronized (BluetoothServer.getInstance().lock)
        {
            for(BluetoothConnection connection : BluetoothServer.getInstance().connections)
            {
                connection.sendMessage(new PlayerInitData("SERVER", connection.getID()));
            }
        }

        GUIConnector.getInstance().initializeConnector(true);
        GUIConnector.getInstance().notificationsAdapter = new NotificationsAdapter(getActivity(), getActivity());

        final String names[] = new String[BluetoothServer.getInstance().connectionsNumber];
        final int ids[] = new int[BluetoothServer.getInstance().connectionsNumber];
        final MessagesQueue<Serializable> queue = BluetoothServer.getInstance().getIncomingQueue();
        Thread thread = new Thread(new Runnable()
        {
            int counter = BluetoothServer.getInstance().connectionsNumber;
            @Override
            public void run()
            {
                while(true)
                {
                    Serializable message;
                    if((message = queue.popMessage()) != null)
                    {
                        if(message instanceof PlayerInitData)
                        {
                            names[counter - 1] = ((PlayerInitData)message).playerName;
                            ids[counter - 1] = ((PlayerInitData)message).ID;
                            counter--;
                            if(counter == 0)
                            {
                                LogicConnector.getInstance().initializeConnector(BluetoothServer.getInstance().getIncomingQueue(),
                                                                                BluetoothServer.getInstance().getSendingQueue(),
                                                                                ids, names);

                                synchronized (BluetoothServer.getInstance().lock)
                                {
                                    for(BluetoothConnection connection : BluetoothServer.getInstance().connections)
                                    {
                                        connection.sendMessage(new StartGame());
                                    }
                                }

                                Intent intent = new Intent(getActivity().getApplicationContext(), GameOverviewActivity.class);
                                startActivity(intent);
                                return;
                            }
                        }

                    }
                    else
                    {
                        try
                        {
                            Thread.sleep(50);
                        }
                        catch(Exception e){}
                    }
                }
            }
        });
        thread.start();



        /*BluetoothServer.getInstance().stopWaitingConnection();

        String[] names = new String[BluetoothServer.getInstance().getConnectionsNumber()];

        BluetoothServer.getInstance().broadcastActivityChange(new ActivityLoadCall(ActivityLoadCall.START_GAME));
        //Clean after connection stage
        BluetoothConnectionFactory.destroyFactory();

        BluetoothConnectionFactory.getInstance().addListener(temporaryBluetoothKeeper);
        //Init GUI connector
        GUIConnector.getInstance().setConnection(BluetoothServer.getInstance().getHostConnection(),
                                                 BluetoothServer.getInstance().getIncomingQueue());

        if(GUIConnector.getInstance().notificationsAdapter == null)

        //Init logic connector
        LogicConnector.initializeConnector(BluetoothServer.getInstance().getIncomingQueue(), BluetoothServer.getInstance().getBroadcasterQueue());
        //Start new activity
        Intent intent = new Intent(getActivity().getApplicationContext(), GameOverviewActivity.class);
        startActivity(intent);*/
    }

    //************************************
}