package com.savoirfairelinux.sflphone.adapters;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;

import android.app.Activity;
import android.content.Context;
import android.net.Uri;
import android.os.RemoteException;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.RadioButton;
import android.widget.TextView;

import com.savoirfairelinux.sflphone.R;
import com.savoirfairelinux.sflphone.account.AccountDetailBasic;
import com.savoirfairelinux.sflphone.service.ISipService;

public class AccountSelectionAdapter extends BaseAdapter {

    private static final String TAG = AccountSelectionAdapter.class.getSimpleName();

    ArrayList<String> accountIDs;
    Context mContext;
    AccountManager accManager;
    ISipService service;
    int selectedAccount = 0;

    public AccountSelectionAdapter(Context cont, ISipService s, ArrayList<String> newList) {
        super();
        accountIDs = newList;
        mContext = cont;
        service = s;
        accManager = new AccountManager(mContext);
    }

    @Override
    public int getCount() {
        return accountIDs.size();
    }

    @Override
    public String getItem(int pos) {
        return accountIDs.get(pos);
    }

    @Override
    public long getItemId(int pos) {
        return 0;
    }

    @Override
    public View getView(int pos, View convertView, ViewGroup parent) {
        View rowView = convertView;
        AccountView entryView = null;

        if (rowView == null) {
            LayoutInflater inflater = LayoutInflater.from(mContext);
            rowView = inflater.inflate(R.layout.item_account, null);

            entryView = new AccountView();
            entryView.alias = (TextView) rowView.findViewById(R.id.account_alias);
            entryView.host = (TextView) rowView.findViewById(R.id.account_host);
            entryView.select = (RadioButton) rowView.findViewById(R.id.account_checked);
            rowView.setTag(entryView);
        } else {
            entryView = (AccountView) rowView.getTag();
        }

        accManager.displayAccountDetails(accountIDs.get(pos), entryView);
        if(pos == selectedAccount){
            entryView.select.setChecked(true);
        }

        return rowView;
    }

    /*********************
     * ViewHolder Pattern
     *********************/
    public class AccountView {
        public TextView alias;
        public TextView host;
        public RadioButton select;
    }

    /**
     * Asynchronous account details retriever
     */
    public class AccountManager {

        // private static final String TAG = ImageManager.class.getSimpleName();

        private HashMap<String, HashMap<String, String>> accountMap = new HashMap<String, HashMap<String, String>>();
        private AccountQueue accountQueue = new AccountQueue();
        private Thread accountLoaderThread = new Thread(new AccountQueueManager());


        public AccountManager(Context context) {
            accountLoaderThread.setPriority(Thread.NORM_PRIORITY - 1);

        }

        public void displayAccountDetails(String id, AccountView account) {

            if (accountMap.containsKey(id)) {

                HashMap<String, String> details = accountMap.get(id);
                account.alias.setText(details.get(AccountDetailBasic.CONFIG_ACCOUNT_ALIAS));
                account.host.setText(details.get(AccountDetailBasic.CONFIG_ACCOUNT_HOSTNAME));

            } else {
                queueAccount(id, account);
            }
        }

        private void queueAccount(String id, AccountView row) {
            // This ImageView might have been used for other images, so we clear
            // the queue of old tasks before starting.
//            accountQueue.Clean(row);
            AccountRef p = new AccountRef(id, row);

            synchronized (accountQueue.accountRefsStack) {
                accountQueue.accountRefsStack.push(p);
                accountQueue.accountRefsStack.notifyAll();
            }

            // Start thread if it's not started yet
            if (accountLoaderThread.getState() == Thread.State.NEW) {
                accountLoaderThread.start();
            }
        }

        /** Classes **/

        private class AccountRef {
            public String accountID;
            public AccountView row;

            public AccountRef(String u, AccountView i) {
                accountID = u;
                row = i;
            }
        }

        private class AccountQueue {
            private Stack<AccountRef> accountRefsStack = new Stack<AccountRef>();

            // removes all instances of this account
//            public void Clean(AccountView view) {
//
//                for (int i = 0; i < accountRefsStack.size();) {
//                    if (accountRefsStack.get(i).row == view)
//                        accountRefsStack.remove(i);
//                    else
//                        ++i;
//                }
//            }
        }

        private class AccountQueueManager implements Runnable {
            @Override
            public void run() {
                try {
                    while (true) {
                        // Thread waits until there are accountsID in the queue to be retrieved
                        if (accountQueue.accountRefsStack.size() == 0) {
                            synchronized (accountQueue.accountRefsStack) {
                                accountQueue.accountRefsStack.wait();
                            }
                        }

                        // When we have accounts to load
                        if (accountQueue.accountRefsStack.size() != 0) {
                            AccountRef accountToLoad;

                            synchronized (accountQueue.accountRefsStack) {
                                accountToLoad = accountQueue.accountRefsStack.pop();
                            }

                            HashMap<String, String> details = (HashMap<String, String>) service.getAccountDetails(accountToLoad.accountID);
                            
                            accountMap.put(accountToLoad.accountID, details);
                            AccountDisplayer accDisplayer = new AccountDisplayer(details, accountToLoad.row);
                            Activity a = (Activity) mContext;

                            a.runOnUiThread(accDisplayer);

                        }

                        if (Thread.interrupted())
                            break;
                    }
                } catch (InterruptedException e) {
                    Log.e(TAG, e.toString());
                } catch (RemoteException e) {
                    Log.e(TAG, e.toString());
                }
            }
        }

        // Used to display details in the UI thread
        private class AccountDisplayer implements Runnable {
            HashMap<String, String> displayDetails;
            AccountView displayRow;

            public AccountDisplayer(HashMap<String, String> details, AccountView row) {
                displayRow = row;
                displayDetails = details;
            }

            public void run() {
                displayRow.alias.setText(displayDetails.get(AccountDetailBasic.CONFIG_ACCOUNT_ALIAS));
                displayRow.host.setText(displayDetails.get(AccountDetailBasic.CONFIG_ACCOUNT_HOSTNAME));
            }
        }

        public void removeFromCache(Uri uri) {
            if (accountMap.containsKey(uri)) {
                accountMap.remove(uri);
            }
        }
    }

    public void setSelectedAccount(int pos) {
       selectedAccount = pos;
    }

    public String getSelectedAccount() {
       return accountIDs.get(selectedAccount);
    }

}
