/*
 * Copyright (C) 2014 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.android.browser;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.webkit.GeolocationPermissions;
import android.webkit.PermissionRequest;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;

public class PermissionsPrompt extends RelativeLayout {
    private TextView mMessage;
    private Button mAllowButton;
    private Button mDenyButton;
    private CheckBox mRemember;
    private Context mContext;
    private PermissionRequest mRequest;

    public PermissionsPrompt(Context context) {
        this(context, null);
        mContext = context;
    }

    public PermissionsPrompt(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        init();
    }

    private void init() {
        mMessage = (TextView) findViewById(R.id.message);
        mAllowButton = (Button) findViewById(R.id.allow_button);
        mDenyButton = (Button) findViewById(R.id.deny_button);
        mRemember = (CheckBox) findViewById(R.id.remember);

        mAllowButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handleButtonClick(true);
            }
        });
        mDenyButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handleButtonClick(false);
            }
        });
    }

    public void show(PermissionRequest request) {
        mRequest = request;
        setMessage();
        mRemember.setChecked(true);
        setVisibility(View.VISIBLE);
    }

    public void setMessage() {
        String[] resources = mRequest.getResources();
        Vector<String> strings = new Vector<String>();
        for (String resource : resources) {
            if (resource.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE))
                strings.add(getResources().getString(R.string.resource_video_capture));
            else if (resource.equals(PermissionRequest.RESOURCE_AUDIO_CAPTURE))
                strings.add(getResources().getString(R.string.resource_audio_capture));
            else if (resource.equals(PermissionRequest.RESOURCE_PROTECTED_MEDIA_ID))
                strings.add(getResources().getString(R.string.resource_protected_media_id));
        }
        if (strings.isEmpty()) return;

        Enumeration<String> e = strings.elements();
        StringBuilder sb = new StringBuilder(e.nextElement());
        if (e.hasMoreElements()) {
            sb.append(", ");
            sb.append(e.nextElement());
        }

        mMessage.setText(String.format(
                getResources().getString(R.string.permissions_prompt_message),
                mRequest.getOrigin(), sb.toString()));
    }

    /**
     * Hides the prompt.
     */
    public void hide() {
        setVisibility(View.GONE);
    }

    /**
     * Handles a click on one the buttons by invoking the callback.
     */
    private void handleButtonClick(boolean allow) {
        hide();
        if (allow) {
            String[] resources = mRequest.getResources();
            List<String> permissionsToRequest = new ArrayList<String>();

            for (String resource : resources) {
                if (resource.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE) &&
                        mContext.checkSelfPermission(Manifest.permission.CAMERA) !=
                        PackageManager.PERMISSION_GRANTED) {
                    permissionsToRequest.add(Manifest.permission.CAMERA);
                } else if (resource.equals(PermissionRequest.RESOURCE_AUDIO_CAPTURE) &&
                        mContext.checkSelfPermission(Manifest.permission.RECORD_AUDIO) !=
                        PackageManager.PERMISSION_GRANTED) {
                    permissionsToRequest.add(Manifest.permission.RECORD_AUDIO);
                }
            }

            if (permissionsToRequest.size() > 0) {
                String[] permissions = permissionsToRequest.toArray(
                        new String[permissionsToRequest.size()]);
                ((Activity) mContext).requestPermissions(permissions, 1);
                Intent intent = new Intent(mContext, PermissionsActivity.class);
                mContext.startActivity(intent);
            } else {
                mRequest.grant(mRequest.getResources());
            }
        } else {
            mRequest.deny();
        }
    }
}
