/*
 * Copyright (C) 2011 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.
 */

package com.example.training.deviceadmin;

import android.app.Activity;
import android.app.admin.DevicePolicyManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;

/**
 * Main Activity for the sample application.
 *
 * The Activity maintains and presents 2 different
 * screens to the user -- a screen for configuring device administration policy and another screen
 * for viewing configured policy.  When it is detected that the screen-lock password satisfies
 * the password strength required by the policy, the user is sent to an Activity containing
 * protected content.
 */
public class PolicySetupActivity extends Activity {
    private static final int REQ_ACTIVATE_DEVICE_ADMIN = 10;
    private static final String SCREEN_ID_KEY = "LAYOUT_ID";

    private static final String APP_PREF = "APP_PREF";
    private static final int UNKNOWN_SCREEN_ID = -1;

    // UI controls in policy setup screen.
    private Spinner mPasswordQualityInputField;
    private EditText mPasswordLengthInputField;
    private EditText mPasswordMinUppercaseInputField;

    private Policy mPolicy;
    private int mCurrentScreenId;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mPolicy = new Policy(this);
    }

    @Override
    protected void onResume() {
        super.onResume();

        SharedPreferences prefs = getSharedPreferences(APP_PREF, MODE_PRIVATE);
        final int savedScreenId = prefs.getInt(SCREEN_ID_KEY, UNKNOWN_SCREEN_ID);
        if (savedScreenId == UNKNOWN_SCREEN_ID || !mPolicy.isAdminActive()) {
            setScreenContent(R.layout.activity_policy_setup);
        } else {
            setScreenContent(savedScreenId);
        }
    }

    private void setScreenContent(final int screenId) {
        mCurrentScreenId = screenId;
        setContentView(mCurrentScreenId);
        getSharedPreferences(APP_PREF, MODE_PRIVATE).edit().putInt(
                SCREEN_ID_KEY, mCurrentScreenId).commit();
        switch (mCurrentScreenId) {
        case R.layout.activity_policy_setup:
            initPolicySetupScreen();
            initNavigation();
            break;
        case R.layout.activity_view_policy:
            initViewPolicyScreen();
            initNavigation();
            break;
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mCurrentScreenId == R.layout.activity_policy_setup) writePolicy();
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQ_ACTIVATE_DEVICE_ADMIN && resultCode == RESULT_OK) {
            // User just activated the application as a device administrator.
            setScreenContent(mCurrentScreenId);
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    @Override
    public void onBackPressed() {
        if (mCurrentScreenId == R.layout.activity_view_policy) {
            setScreenContent(R.layout.activity_policy_setup);
            return;
        }
        super.onBackPressed();
    }

    // Initialize policy set up screen.
    private void initPolicySetupScreen() {
        mPasswordQualityInputField = (Spinner) findViewById(R.id.policy_password_quality);
        mPasswordLengthInputField = (EditText) findViewById(R.id.policy_password_length);
        mPasswordMinUppercaseInputField = (EditText) findViewById(R.id.policy_password_uppercase);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
                R.array.password_types, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mPasswordQualityInputField.setAdapter(adapter);
        mPasswordQualityInputField.setOnItemSelectedListener(
                new AdapterView.OnItemSelectedListener() {
            public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
                LinearLayout passwordMinUppercaseView =
                        (LinearLayout) findViewById(R.id.password_uppercase_view);
                // The minimum number of upper case field is only applicable for password
                // qualities: alpha, alphanumeric, or complex.
                if (pos > 2)
                    passwordMinUppercaseView.setVisibility(View.VISIBLE);
                else
                    passwordMinUppercaseView.setVisibility(View.GONE);
            }

            public void onNothingSelected(AdapterView<?> parent) {}
        });

        // Read previously saved policy and populate on the UI.
        mPolicy.readFromLocal();
        mPasswordQualityInputField.setSelection(mPolicy.getPasswordQuality());
        if (mPolicy.getPasswordLength() > 0) {
            mPasswordLengthInputField.setText(String.valueOf(mPolicy.getPasswordLength()));
        } else {
            mPasswordLengthInputField.setText("");
        }

        if (mPolicy.getPasswordMinUpperCase() > 0) {
            mPasswordMinUppercaseInputField.setText(
                    String.valueOf(mPolicy.getPasswordMinUpperCase()));
        } else {
            mPasswordMinUppercaseInputField.setText("");
        }
    }

    // Initialize policy viewing screen.
    private void initViewPolicyScreen() {
        TextView passwordQualityView = (TextView) findViewById(R.id.policy_password_quality);
        TextView passwordLengthView = (TextView) findViewById(R.id.policy_password_length);

        // Read previously saved policy and populate on the UI.
        mPolicy.readFromLocal();
        int passwordQualitySelection = mPolicy.getPasswordQuality();
        passwordQualityView.setText(
                getResources().getStringArray(R.array.password_types)[passwordQualitySelection]);
        passwordLengthView.setText(String.valueOf(mPolicy.getPasswordLength()));
        if (passwordQualitySelection > 2) {
            LinearLayout passwordMinUppercaseView =
                    (LinearLayout) findViewById(R.id.password_uppercase_view);
            passwordMinUppercaseView.setVisibility(View.VISIBLE);
            ((TextView) findViewById(R.id.policy_password_uppercase)).setText(
                    String.valueOf(mPolicy.getPasswordMinUpperCase()));
        }
    }

    // Set up navigation message and action button.
    private void initNavigation() {
        if (!mPolicy.isAdminActive()) {
            // Activates device administrator.
            setupNavigation(R.string.setup_message_activate,
                    R.string.setup_action_activate,
                    mActivateButtonListener);
        } else if (mCurrentScreenId == R.layout.activity_policy_setup) {
            setupNavigation(R.string.setup_message_set_policy,
                    R.string.setup_action_set_policy,
                    new View.OnClickListener() {
                        public void onClick(View view) {
                            writePolicy();
                            mPolicy.configurePolicy();
                            setScreenContent(R.layout.activity_view_policy);
                        }
                    });
        }
        else if (!mPolicy.isActivePasswordSufficient()) {
            // Launches password set-up screen in Settings.
            setupNavigation(R.string.setup_message_enforce_policy,
                    R.string.setup_action_enforce_policy,
                    mEnforcePolicyListener);
        } else {
            // Grants access to secure content.
            setupNavigation(R.string.setup_message_go_secured,
                    R.string.setup_action_go_secured,
                    new View.OnClickListener() {
                        public void onClick(View view) {
                            startActivity(new Intent(view.getContext(), SecureActivity.class));
                        }
                    });
        }
    }

    private View.OnClickListener mActivateButtonListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // First, persist the policy.  Then, launch intent to trigger the system screen
            // requesting user to confirm the activation of the device administrator.
            writePolicy();
            Intent activateDeviceAdminIntent =
                new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
            activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN,
                    mPolicy.getPolicyAdmin());
            // It is good practice to include the optional explanation text to explain to
            // user why the application is requesting to be a device administrator.  The system
            // will display this message on the activation screen.
            activateDeviceAdminIntent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                    getResources().getString(R.string.device_admin_activation_message));
            startActivityForResult(activateDeviceAdminIntent, REQ_ACTIVATE_DEVICE_ADMIN);
        }
    };

    private View.OnClickListener mEnforcePolicyListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            writePolicy();
            // The device administration API does not "fix" the password if it is
            // determined that the current password does not conform to what is requested
            // by the policy.  The caller is responsible for triggering the password set up
            // screen via the below intent.
            Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
            startActivity(intent);
        }
    };

    // Setup action button text and listener.
    private void setupNavigation(int messageResId, int buttonTextResId,
            View.OnClickListener listener) {
        TextView setupMessage = (TextView) findViewById(R.id.setup_message);
        setupMessage.setText(messageResId);
        Button actionBtn = (Button) findViewById(R.id.setup_action_btn);
        actionBtn.setText(buttonTextResId);
        actionBtn.setOnClickListener(listener);
    }

    // Save policy to shared preferences.
    private void writePolicy() {
        int passwordQuality = (int) mPasswordQualityInputField.getSelectedItemId();

        int passwordLength = 0;
        try {
            passwordLength = Integer.parseInt(mPasswordLengthInputField.getText().toString());
        } catch (NumberFormatException nfe) {}  // Defaults to 0.

        int passwordMinUppercase = 0;
        try {
            passwordMinUppercase =
                    Integer.parseInt(mPasswordMinUppercaseInputField.getText().toString());
        } catch (NumberFormatException nfe) {}  // Defaults to 0.

        mPolicy.saveToLocal(passwordQuality, passwordLength, passwordMinUppercase);
    }
}

