/*******************************************************************************
 * ADOBE CONFIDENTIAL
 *  ___________________
 *
 *  Copyright 2014 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 *  NOTICE:  All information contained herein is, and remains
 *  the property of Adobe Systems Incorporated and its suppliers,
 *  if any.  The intellectual and technical concepts contained
 *  herein are proprietary to Adobe Systems Incorporated and its
 *  suppliers and are protected by trade secret or copyright law.
 *  Dissemination of this information or reproduction of this material
 *  is strictly forbidden unless prior written permission is obtained
 *  from Adobe Systems Incorporated.
 ******************************************************************************/

package com.adobe.primetime.reference.ui.entitlement;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.TextView;
import com.adobe.primetime.reference.PrimetimeReference;
import com.adobe.primetime.reference.R;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.TreeMap;

/**
 * Displays a list of MVPDs objects either as a List or a Grid of icons. If displayed as a Grid, only the top
 * preferred MVPDs are displayed. If displayed as a List, all the MVPDs are listed alphabetically.
 */
public class MvpdPickerFragment extends Fragment
{
    /**
     * Possible view types for this fragment to display MVPDs
     */
    public enum ViewType
    {
        GRID (R.layout.entitlement_picker_grid, R.layout.entitlement_picker_icon),
        LIST (R.layout.entitlement_picker_list, R.layout.entitlement_picker_text);

        private final int listLayout;
        private final int itemLayout;

        ViewType(int listLayout, int itemLayout)
        {
            this.listLayout = listLayout;
            this.itemLayout = itemLayout;
        }

        public int getListLayout() { return listLayout; }
        public int getItemLayout() { return itemLayout; }
    }

    private static final String LOG_TAG = PrimetimeReference.LOG_APP_NAME + "MvpdPickerFragment";

    // the ViewType for this fragment
    private ViewType currentType;

    // callback methods implemented by the containing Activity
    private IMvpdPickerClickListener clickListener;

    // The max number of MVPDs to display in a Grid of icons, based on CTAM recommendations
    // {@link http://www.ctamtve.com/serviceproviderselection}
    private static final int MAX_DISPLAY_ICONS = 9;

    /* Array of MVPDs to display in a Grid of icons
     When displaying a grid, only the MVPDs which intersect this array and the ArrayList of all MVPDs are displayed.
     The array contents are ordered by display preference as only a maximum of MAX_DISPLAY_ICONS are displayed.
     */
    private static final String[] PRIMARY_MVPDS = {
            "AdobeREF01",                        // Adobe test MVPD
            "AdobeREF02",                        // Adobe test MVPD
            "AdobeREF03",                        // Adobe test MVPD
            "AdobeREF04",                        // Adobe test MVPD
            "AdobeREF05",                        // Adobe test MVPD
            "AdobeREF06",                        // Adobe test MVPD
            "AdobeREF07",                        // Adobe test MVPD
            "AdobeREF08",                        // Adobe test MVPD
            "AdobeREF09",                        // Adobe test MVPD
            "Comcast_SSO",                       // Comcast XFINITY
            "DTV",                               // DirectTV
            "Dish",                              // Dish
            "TWC",                               // Time Warner Cable
            "Cox",                               // Cox
            "Charter_Direct",                    // Charter
            "Verizon",                           // Verizon FiOS
            "Cablevision",                       // Cablevision Optimum
            "ATT",                               // AT&T U-verse
            "Brighthouse",                       // Brighthouse
            "Suddenlink",                        // Suddenlink
            "Mediacom",                          // Mediacom
            "CableOne",                          // CableOne
            "WOW",                               // WOW!
            "RCN",                               // RCN
            "auth_atlanticbb_net",               // Atlantic Broadband
            "auth_armstrongmywire_com",          // Armstrong
            "knology_auth-gateway_net",          // KNOLOGY
            "serviceelectric_auth-gateway_net",  // Service Electric Cablevision
            "msauth_midco_net",                  // Midcontinent Communications
            "auth_metrocast_net",                // MetroCast
            "www_websso_mybrctv_com",            // Blue Ridge Communications
    };

    // the full list of MVPDs
    private final ArrayList<MvpdListItem> mvpdList = new ArrayList<MvpdListItem>();

    // used to hide keyboard on pause
    private EditText textFilter;

    /**
     * Create a new instance of MvpdPickerFragment.
     *
     * @param type The {@link com.adobe.primetime.reference.ui.entitlement.MvpdPickerFragment.ViewType} used to
     *             display the MVPDs.
     * @param mvpdListItems The list of MVPDs to display
     * @return A new MvpdPikcerFragment instance
     */
    public static MvpdPickerFragment newInstance(ViewType type, ArrayList<MvpdListItem> mvpdListItems)
    {
        MvpdPickerFragment fragment = new MvpdPickerFragment();

        Bundle args = new Bundle();
        args.putSerializable("type", type);
        args.putParcelableArrayList("list", mvpdListItems);
        fragment.setArguments(args);

        return fragment;
    }


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

        try
        {
            clickListener = (IMvpdPickerClickListener) activity;
        }
        catch (ClassCastException e)
        {
            throw new ClassCastException(activity.toString() + " must implement IMvpdPickerClickListener.");
        }
    }

    @Override
    public void onPause() {

        if (textFilter != null)
        {
            InputMethodManager imm = (InputMethodManager) getActivity().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(textFilter.getWindowToken(), 0);
        }

        super.onPause();
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        ArrayList<MvpdListItem> items = null;

        if (getArguments() != null)
        {
            currentType = (ViewType) getArguments().getSerializable("type");

            items = getArguments().getParcelableArrayList("list");
        }

        if (currentType == null)
        {
            currentType = ViewType.GRID;
        }

        if (items != null)
        {
            mvpdList.addAll(items);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        ArrayList<MvpdListItem> filterList = new ArrayList<MvpdListItem>();
        final ViewType nextType;

        switch (currentType)
        {
            case LIST:
                // in list view, initially display all items
                filterList.addAll(mvpdList);
                nextType = ViewType.GRID;
                break;

            case GRID:
                // in grid view, only display icons for primary mvpds
                filterList.addAll(filterListByPrimaryItems(mvpdList));
                nextType = ViewType.LIST;
                break;

            default:
                // default is GRID view
                currentType = ViewType.GRID;
                filterList.addAll(filterListByPrimaryItems(mvpdList));
                nextType = ViewType.LIST;
                break;

        }

        View view = inflater.inflate(currentType.getListLayout(), container, false);

        // get reference to clickable text, which loads list fragment view
        TextView btnList = (TextView) view.findViewById(R.id.btnPickerChangeView);
        btnList.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                clickListener.handleViewChange(nextType);
            }
        });

        // get references grid adapter
        AdapterView mvpdListView = (AdapterView) view.findViewById(R.id.mvpd_list);
        mvpdListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Object item = parent.getItemAtPosition(position);
                clickListener.handleItemSelection(item);
            }
        });

        // bind the MVPD list to the array adapter
        final MvpdListArrayAdapter adapter = new MvpdListArrayAdapter(getActivity(), currentType.getItemLayout(), filterList);
        mvpdListView.setAdapter(adapter);

        // setup filter text box in list view
        final EditText editText = (EditText) view.findViewById(R.id.filter);
        if (editText != null)
        {
            editText.clearFocus(); // fixes issue on older devices where soft keyboard doesn't appear

            textFilter = editText; // save EditText for onPause, but also need final variable

            editText.addTextChangedListener(new TextWatcher() {

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                }

                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {

                }

                @Override
                public void afterTextChanged(Editable s) {
                    String text = editText.getText().toString().toLowerCase(Locale.US);
                    adapter.filter(text);
                }
            });
        }

        return view;
    }

    /**
     * Filter the full list of MVPDs by an ordered array of primary MVPDs. Only MVPDs which are contained in both
     * lists will appear in the result list. The resulting list will contain at most MAX_DISPLAY_ICONS entries.
     * the resulting list will have the same ordering as in the PRIMARY_MVPDS array.
     *
     * @param fullList The full list of MVPDs
     * @return A sub-list of at most MAX_DISPLAY_ICONS MVPDs which appear both in the given fullList and in the
     * PRIMARY_MVPDS array, using the same ordering as the PRIMARY_MVPDS array.
     */
    private List<MvpdListItem> filterListByPrimaryItems(final List<MvpdListItem> fullList)
    {
        // first create a map of the full list keyed by id
        TreeMap<String, MvpdListItem> map = new TreeMap<String, MvpdListItem>(String.CASE_INSENSITIVE_ORDER);
        for (MvpdListItem item : fullList)
        {
            map.put(item.getMvpd().getId(), item);
        }

        // second create a filtered list with at most MAX_DISPLAY_ICONS items
        // list is ordered based on PRIMARY_MVPDS list order
        List<MvpdListItem> result = new ArrayList<MvpdListItem>();
        MvpdListItem item;
        for (int i = 0; i < PRIMARY_MVPDS.length && result.size() < MAX_DISPLAY_ICONS; i++)
        {
            if ((item = map.get(PRIMARY_MVPDS[i])) != null)
            {
                result.add(item);
            }
        }

        return result;
    }

}
