using Android.App;
using Android.OS;
using Android.Widget;
using Ozeki.Media;
using Ozeki.VoIP;
using System;
using System.Collections.Generic;

namespace _06_Codecs_handler
{
    [Activity(Label = "DialingActivity")]
    public class DialingActivity : Activity
    {
        Softphone _mySoftphone;

        TextView _status;
        bool _registered;

        Button _btnInteractions;
        Button _btnZero;
        Button _btnOne;
        Button _btnTwo;
        Button _btnThree;
        Button _btnFour;
        Button _btnFive;
        Button _btnSix;
        Button _btnSeven;
        Button _btnEight;
        Button _btnNine;
        Button _btnStar;
        Button _btnHashtag;
        TextView _btnClear;
        TextView _btnLogOut;

        TextView _inputNumberToCall;

        Spinner _spinner;
        CallState _callState;
        CodecInfo _actualCodec;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            SetContentView(Resource.Layout.activity_dialing);


            InitSoftphone();
            _registered = false;
            Register();

            PopulateSpinner();

            _btnInteractions = FindViewById<Button>(Resource.Id.btnInteractions);
            _btnInteractions.Click += OnClick__btnInteractions;

            _btnLogOut = FindViewById<TextView>(Resource.Id.btnLogOut);
            _btnLogOut.Click += delegate { Xamarin.Essentials.Preferences.Clear(); StartActivity(typeof(MainActivity)); };

            _btnClear = FindViewById<TextView>(Resource.Id.btnClear);
            _btnClear.Click += delegate { _inputNumberToCall.Text = ""; };

            _btnZero = FindViewById<Button>(Resource.Id.btnZero);
            _btnZero.Click += delegate { _inputNumberToCall.Text += "0"; };

            _btnOne = FindViewById<Button>(Resource.Id.btnOne);
            _btnOne.Click += delegate { _inputNumberToCall.Text += "1"; };

            _btnTwo = FindViewById<Button>(Resource.Id.btnTwo);
            _btnTwo.Click += delegate { _inputNumberToCall.Text += "2"; };

            _btnThree = FindViewById<Button>(Resource.Id.btnThree);
            _btnThree.Click += delegate { _inputNumberToCall.Text += "3"; };

            _btnFour = FindViewById<Button>(Resource.Id.btnFour);
            _btnFour.Click += delegate { _inputNumberToCall.Text += "4"; };

            _btnFive = FindViewById<Button>(Resource.Id.btnFive);
            _btnFive.Click += delegate { _inputNumberToCall.Text += "5"; };

            _btnSix = FindViewById<Button>(Resource.Id.btnSix);
            _btnSix.Click += delegate { _inputNumberToCall.Text += "6"; };

            _btnSeven = FindViewById<Button>(Resource.Id.btnSeven);
            _btnSeven.Click += delegate { _inputNumberToCall.Text += "7"; };

            _btnEight = FindViewById<Button>(Resource.Id.btnEight);
            _btnEight.Click += delegate { _inputNumberToCall.Text += "8"; };

            _btnNine = FindViewById<Button>(Resource.Id.btnNine);
            _btnNine.Click += delegate { _inputNumberToCall.Text += "9"; };

            _btnStar = FindViewById<Button>(Resource.Id.btnStar);
            _btnStar.Click += delegate { _inputNumberToCall.Text += "*"; };

            _btnHashtag = FindViewById<Button>(Resource.Id.btnHashtag);
            _btnHashtag.Click += delegate { _inputNumberToCall.Text += "#"; };

            _inputNumberToCall = FindViewById<TextView>(Resource.Id.inputNumberToCall);
            _status = FindViewById<TextView>(Resource.Id.status);

            _spinner = FindViewById<Spinner>(Resource.Id.spinner);
        }

        private void InitSoftphone()
        {
            _mySoftphone = new Softphone();
            _mySoftphone.PhoneLineStateChanged += mySoftphone_PhoneLineStateChanged;
            _mySoftphone.CallStateChanged += _mySoftphone_CallStateChanged;
        }

        private void OnClick__btnInteractions(object sender, EventArgs e)
        {
            if (_callState == CallState.Answered || _callState == CallState.InCall
                || _callState == CallState.Ringing)
            {
                _mySoftphone.HangUp();


                if (_actualCodec != null)
                {
                    _mySoftphone.DisableCodec(_actualCodec.PayloadType);
                    _spinner.SetSelection(0);
                }
            }
            else
            {
                string currentNumber = _inputNumberToCall.Text;
                _inputNumberToCall.Text = "";

                if (!string.IsNullOrEmpty(currentNumber) && _registered == true)
                {
                    if (_spinner.SelectedItem.ToString() != "None")
                    {
                        foreach (var codec in _mySoftphone.Codecs())
                        {
                            if (codec.CodecName == _spinner.SelectedItem.ToString())
                            {
                                _mySoftphone.EnableCodec(codec.PayloadType);
                                _actualCodec = codec;
                            }
                        }
                    }

                    _mySoftphone.StartCall(currentNumber);
                }
            }
        }

        /*
            This method will fill the dropdown menu, that contains the name of
            the aviable codecs.
        */

        private void PopulateSpinner()
        {
            Spinner spinner = FindViewById<Spinner>(Resource.Id.spinner);
            ArrayAdapter<string> adapter = new ArrayAdapter<string>(this,
                Android.Resource.Layout.SimpleSpinnerItem, getCodecs());
            adapter.SetDropDownViewResource(Android.Resource.Layout.SimpleSpinnerDropDownItem);
            spinner.Adapter = adapter;
        }

        /*
            This method will collect the name of all the aviable codecs. 
        */

        private List<string> getCodecs()
        {
            List<string> codecs = new List<string>();
            codecs.Add("None");
            foreach(var codec in _mySoftphone.Codecs())
            {
                if (codec.MediaType == CodecMediaType.Audio)
                {
                    codecs.Add(codec.CodecName);
                }
            }

            return codecs;
        }

        /*
            Everytime the PhoneLineState changes this method will test, what is the
            current PhoneLineState.
        */

        private void mySoftphone_PhoneLineStateChanged(object sender, RegistrationStateChangedArgs e)
        {
            if (e.State == RegState.Error || e.State == RegState.NotRegistered)
            {
                _registered = false;
                _status.Text = "Not registered.";
            }
            else if (e.State == RegState.RegistrationSucceeded)
            {
                _registered = true;
                _status.Text = "Registered.";
            }
        }

        /*
            Everytime the CallState changes this method will test, what is the
            current CallState.
        */

        private void _mySoftphone_CallStateChanged(object sender, CallStateChangedArgs e)
        {
            _callState = e.State;

            if (_callState == CallState.Answered || _callState == CallState.InCall
                || _callState == CallState.Setup || _callState == CallState.Ringing)
            {
                _btnInteractions.Text = "Hang up";
            }
            else
            {
                _btnInteractions.Text = "Dial";
            }
        }


        /*
            The Register method will issue a SIP registration to the Ozeki Phone
            System.
        */

        private void Register()
        {
            bool registrationRequired = true;
            string displayName = Xamarin.Essentials.Preferences.Get("display_name", "");
            string userName = Xamarin.Essentials.Preferences.Get("user_name", "");
            string authenticationId = Xamarin.Essentials.Preferences.Get("authentication_id", "");
            string registerPassword = Xamarin.Essentials.Preferences.Get("register_password", "");
            string domainHost = Xamarin.Essentials.Preferences.Get("domain_host", "");
            int domainPort = Xamarin.Essentials.Preferences.Get("domain_port", 5060);

            _mySoftphone.Register(registrationRequired, displayName, userName, authenticationId,
                registerPassword, domainHost, domainPort);
        }

        /*
            This function overwrites the OnBackPressed() method of the class
            so if you press the back button, you will not be able to go back to
            the previous page. The only way you can go back to the registration
            page is if you press the logout button.
        */

        public override void OnBackPressed()
        {
            return;
        }

    }
}