/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * This file references fs_error.png, fs_good.png, fs_indeterminate.png,
 * and fs_warning.png which are licensed under Creative Commons 3.0
 * by fatcow.com.
 * http://www.fatcow.com/free-icons/
 * http://creativecommons.org/licenses/by/3.0/us/
 */

package com.android.cts.verifier.features;

import com.android.cts.verifier.PassFailButtons;
import com.android.cts.verifier.R;

import android.content.pm.FeatureInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;

public class FeatureSummaryActivity extends PassFailButtons.ListActivity {
    /**
     * Simple storage class for data about an Android feature.
     */
    static class Feature {
        /**
         * The name of the feature. Should be one of the PackageManager.FEATURE*
         * constants.
         */
        public String name;

        /**
         * Indicates whether the field is present on the current device.
         */
        public boolean present;

        /**
         * Indicates whether the field is required for the current device.
         */
        public boolean required;

        /**
         * Constructor does not include 'present' because that's a detected
         * value, and not set during creation.
         *
         * @param name value for this.name
         * @param required value for this.required
         */
        public Feature(String name, boolean required) {
            this.name = name;
            this.required = required;
            this.present = false;
        }
    }

    /**
     * A list of all features added in Eclair (API=7).
     */
    public static final Feature[] ALL_ECLAIR_FEATURES = {
            new Feature(PackageManager.FEATURE_CAMERA, true),
            new Feature(PackageManager.FEATURE_CAMERA_AUTOFOCUS, false),
            new Feature(PackageManager.FEATURE_CAMERA_FLASH, false),
            new Feature(PackageManager.FEATURE_LIVE_WALLPAPER, false),
            new Feature(PackageManager.FEATURE_SENSOR_LIGHT, false),
            new Feature(PackageManager.FEATURE_SENSOR_PROXIMITY, false),
            new Feature(PackageManager.FEATURE_TELEPHONY, false),
            new Feature(PackageManager.FEATURE_TELEPHONY_CDMA, false),
            new Feature(PackageManager.FEATURE_TELEPHONY_GSM, false),
    };

    /**
     * A list of all features added in FroYo (API=8) and Gingerbread (API=9).
     * Because we want to run on Eclair devices,
     * we can't use static references to constants added later
     * than Eclair. We could use Reflection, but we'd still need a list of
     * string literals (for constant names) anyway, and there's little point in
     * using Reflection to to look up a constant String value for a constant
     * String name.
     */
    public static final Feature[] ALL_FROYO_FEATURES = {
            new Feature("android.hardware.bluetooth", true),
            new Feature("android.hardware.location", true),
            new Feature("android.hardware.location.gps", true),
            new Feature("android.hardware.location.network", true),
            new Feature("android.hardware.microphone", true),
            new Feature("android.hardware.sensor.accelerometer", true),
            new Feature("android.hardware.sensor.compass", true),
            new Feature("android.hardware.touchscreen", true),
            new Feature("android.hardware.touchscreen.multitouch", false),
            new Feature("android.hardware.touchscreen.multitouch.distinct", false),
            new Feature("android.hardware.wifi", false),
    };

    public static final Feature[] ALL_GINGERBREAD_FEATURES = {
            new Feature("android.hardware.audio.low_latency", false),
            new Feature("android.hardware.camera.front", false),
            new Feature("android.hardware.nfc", false),
            new Feature("android.hardware.sensor.barometer", false),
            new Feature("android.hardware.sensor.gyroscope", false),
            new Feature("android.hardware.touchscreen.multitouch.jazzhand", false),
            new Feature("android.software.sip", false),
            new Feature("android.software.sip.voip", false),
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fs_main);
        setPassFailButtonClickListeners();
        setInfoResources(R.string.feature_summary, R.string.feature_summary_info, R.layout.fs_info);

        // some values used to detect warn-able conditions involving multiple
        // features
        boolean hasWifi = false;
        boolean hasTelephony = false;
        boolean hasIllegalFeature = false;

        // get list of all features device thinks it has, & store in a HashMap
        // for fast lookups
        HashMap<String, String> actualFeatures = new HashMap<String, String>();
        for (FeatureInfo fi : getPackageManager().getSystemAvailableFeatures()) {
            actualFeatures.put(fi.name, fi.name);
        }

        // data structure that the SimpleAdapter will use to populate ListView
        ArrayList<HashMap<String, Object>> listViewData = new ArrayList<HashMap<String, Object>>();

        // roll over all known features & check whether device reports them
        boolean present = false;
        int statusIcon;
        ArrayList<Feature> features = new ArrayList<Feature>();
        int apiVersion = Build.VERSION.SDK_INT;
        if (apiVersion >= Build.VERSION_CODES.ECLAIR_MR1) {
            Collections.addAll(features, ALL_ECLAIR_FEATURES);
        }
        if (apiVersion >= Build.VERSION_CODES.FROYO) {
            Collections.addAll(features, ALL_FROYO_FEATURES);
        }
        if (apiVersion >= Build.VERSION_CODES.GINGERBREAD) {
            Collections.addAll(features, ALL_GINGERBREAD_FEATURES);
        }
        for (Feature f : features) {
            HashMap<String, Object> row = new HashMap<String, Object>();
            listViewData.add(row);
            present = actualFeatures.containsKey(f.name);
            if (present) {
                // device reports it -- yay! set the happy icon
                hasWifi = hasWifi || PackageManager.FEATURE_WIFI.equals(f.name);
                hasTelephony = hasTelephony || PackageManager.FEATURE_TELEPHONY.equals(f.name);
                statusIcon = R.drawable.fs_good;
                actualFeatures.remove(f.name);
            } else if (!present && f.required) {
                // it's required, but device doesn't report it. Boo, set the
                // bogus icon
                statusIcon = R.drawable.fs_error;
            } else {
                // device doesn't report it, but it's not req'd, so can't tell
                // if there's a problem
                statusIcon = R.drawable.fs_indeterminate;
            }
            row.put("feature", f.name);
            row.put("icon", statusIcon);
        }

        // now roll over any remaining features (which are non-standard)
        for (String feature : actualFeatures.keySet()) {
            if (feature == null || "".equals(feature))
                continue;
            HashMap<String, Object> row = new HashMap<String, Object>();
            listViewData.add(row);
            row.put("feature", feature);
            if (feature.startsWith("android")) { // intentionally not "android."
                // sorry, you're not allowed to squat in the official namespace;
                // set bogus icon
                row.put("icon", R.drawable.fs_error);
                hasIllegalFeature = true;
            } else {
                // non-standard features are okay, but flag them just in case
                row.put("icon", R.drawable.fs_warning);
            }
        }

        // sort the ListView's data to group by icon type, for easier reading by
        // humans
        final HashMap<Integer, Integer> idMap = new HashMap<Integer, Integer>();
        idMap.put(R.drawable.fs_error, 0);
        idMap.put(R.drawable.fs_warning, 1);
        idMap.put(R.drawable.fs_indeterminate, 2);
        idMap.put(R.drawable.fs_good, 3);
        Collections.sort(listViewData, new Comparator<HashMap<String, Object>>() {
            public int compare(HashMap<String, Object> left, HashMap<String, Object> right) {
                int leftId = idMap.get(left.get("icon"));
                int rightId = idMap.get(right.get("icon"));
                if (leftId == rightId) {
                    return ((String) left.get("feature")).compareTo((String) right.get("feature"));
                }
                if (leftId < rightId)
                    return -1;
                return 1;
            }
        });

        // Set up the SimpleAdapter used to populate the ListView
        SimpleAdapter adapter = new SimpleAdapter(this, listViewData, R.layout.fs_row,
                new String[] {
                        "feature", "icon"
                }, new int[] {
                        R.id.fs_feature, R.id.fs_icon
                });
        adapter.setViewBinder(new SimpleAdapter.ViewBinder() {
            public boolean setViewValue(View view, Object data, String repr) {
                try {
                    if (view instanceof ImageView) {
                        ((ImageView) view).setImageResource((Integer) data);
                    } else if (view instanceof TextView) {
                        ((TextView) view).setText((String) data);
                    } else {
                        return false;
                    }
                    return true;
                } catch (ClassCastException e) {
                    return false;
                }
            }
        });
        setListAdapter(adapter);

        // finally, check for our second-order error cases and set warning text
        // if necessary
        StringBuffer sb = new StringBuffer();
        if (hasIllegalFeature) {
            sb.append(getResources().getString(R.string.fs_disallowed)).append("\n");
        }
        if (!hasWifi && !hasTelephony) {
            sb.append(getResources().getString(R.string.fs_missing_wifi_telephony)).append("\n");
        }
        String warnings = sb.toString().trim();
        if (warnings == null || "".equals(warnings)) {
            ((TextView) (findViewById(R.id.fs_warnings))).setVisibility(View.GONE);
        } else {
            ((TextView) (findViewById(R.id.fs_warnings))).setText(warnings);
        }
    }
}
