/*
 * Copyright (C) 2007 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.app.Activity;
import android.app.AlertDialog;
import android.content.ActivityNotFoundException;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ContentUris;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.Downloads;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.AdapterView.OnItemClickListener;

import java.io.File;
import java.util.List;

/**
 *  View showing the user's current browser downloads
 */
public class BrowserDownloadPage extends Activity 
        implements View.OnCreateContextMenuListener, OnItemClickListener {
    
    private ListView                mListView;
    private Cursor                  mDownloadCursor;
    private BrowserDownloadAdapter  mDownloadAdapter;
    private int                     mStatusColumnId;
    private int                     mIdColumnId;
    private int                     mTitleColumnId;
    private int                     mContextMenuPosition;
    
    @Override 
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.browser_downloads_page);
        
        setTitle(getText(R.string.download_title));

        mListView = (ListView) findViewById(R.id.list);
        mListView.setEmptyView(findViewById(R.id.empty));
        
        mDownloadCursor = managedQuery(Downloads.CONTENT_URI, 
                new String [] {"_id", Downloads.COLUMN_TITLE, Downloads.COLUMN_STATUS,
                Downloads.COLUMN_TOTAL_BYTES, Downloads.COLUMN_CURRENT_BYTES, 
                Downloads._DATA, Downloads.COLUMN_DESCRIPTION, 
                Downloads.COLUMN_MIME_TYPE, Downloads.COLUMN_LAST_MODIFICATION,
                Downloads.COLUMN_VISIBILITY}, 
                null, null);
        
        // only attach everything to the listbox if we can access
        // the download database. Otherwise, just show it empty
        if (mDownloadCursor != null) {
            mStatusColumnId = 
                    mDownloadCursor.getColumnIndexOrThrow(Downloads.COLUMN_STATUS);
            mIdColumnId =
                    mDownloadCursor.getColumnIndexOrThrow(Downloads._ID);
            mTitleColumnId = 
                    mDownloadCursor.getColumnIndexOrThrow(Downloads.COLUMN_TITLE);
            
            // Create a list "controller" for the data
            mDownloadAdapter = new BrowserDownloadAdapter(this, 
                    R.layout.browser_download_item, mDownloadCursor);

            mListView.setAdapter(mDownloadAdapter);
            mListView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
            mListView.setOnCreateContextMenuListener(this);
            mListView.setOnItemClickListener(this);
            
            Intent intent = getIntent();
            if (intent != null && intent.getData() != null) {
                int position = checkStatus(
                        ContentUris.parseId(intent.getData()));
                if (position >= 0) {
                    mListView.setSelection(position);
                }
            }
        }
    }
        
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (mDownloadCursor != null) {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.downloadhistory, menu);
        }
        return true;
    }
    
    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        boolean showCancel = getCancelableCount() > 0;
        menu.findItem(R.id.download_menu_cancel_all).setEnabled(showCancel);
        
        boolean showClear = getClearableCount() > 0;
        menu.findItem(R.id.download_menu_clear_all).setEnabled(showClear);
        return super.onPrepareOptionsMenu(menu);
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.download_menu_cancel_all:
                promptCancelAll();
                return true;
                
            case R.id.download_menu_clear_all:
                promptClearList();
                return true;
        }
        return false;
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        mDownloadCursor.moveToPosition(mContextMenuPosition);
        switch (item.getItemId()) {
            case R.id.download_menu_open:
                hideCompletedDownload();
                openCurrentDownload();
                return true;
                
            case R.id.download_menu_clear:
            case R.id.download_menu_cancel:
                getContentResolver().delete(
                        ContentUris.withAppendedId(Downloads.CONTENT_URI,
                        mDownloadCursor.getLong(mIdColumnId)), null, null);
                return true;
        }
        return false;
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        if (mDownloadCursor != null) {
            AdapterView.AdapterContextMenuInfo info = 
                    (AdapterView.AdapterContextMenuInfo) menuInfo;
            mDownloadCursor.moveToPosition(info.position);
            mContextMenuPosition = info.position;
            menu.setHeaderTitle(mDownloadCursor.getString(mTitleColumnId));
            
            MenuInflater inflater = getMenuInflater();
            int status = mDownloadCursor.getInt(mStatusColumnId);
            if (Downloads.isStatusSuccess(status)) {
                inflater.inflate(R.menu.downloadhistorycontextfinished, menu);
            } else if (Downloads.isStatusError(status)) {
                inflater.inflate(R.menu.downloadhistorycontextfailed, menu);
            } else {
                inflater.inflate(R.menu.downloadhistorycontextrunning, menu);
            }
        }
    }

    /**
     * This function is called to check the status of the download and if it
     * has an error show an error dialog.
     * @param id Row id of the download to check
     * @return position of item
     */
    int checkStatus(final long id) {
        int position = -1;
        for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast(); 
                mDownloadCursor.moveToNext()) {
            if (id == mDownloadCursor.getLong(mIdColumnId)) {
                position = mDownloadCursor.getPosition();
                break;
            }
            
        }
        if (!mDownloadCursor.isAfterLast()) {
            int status = mDownloadCursor.getInt(mStatusColumnId);
            if (!Downloads.isStatusError(status)) {
                return position;
            }
            
            if (status == Downloads.STATUS_FILE_ERROR) {
                String title = mDownloadCursor.getString(mTitleColumnId);
                if (title == null || title.length() == 0) {
                    title = getString(R.string.download_unknown_filename);
                }
                String msg = getString(R.string.download_file_error_dlg_msg, 
                        title);
                new AlertDialog.Builder(this)
                        .setTitle(R.string.download_file_error_dlg_title)
                        .setIcon(android.R.drawable.ic_popup_disk_full)
                        .setMessage(msg)
                        .setPositiveButton(R.string.ok, null)
                        .setNegativeButton(R.string.retry, 
                                new DialogInterface.OnClickListener() {
                                    public void onClick(DialogInterface dialog, 
                                            int whichButton) {
                                        resumeDownload(id);
                                    }
                                })
                        .show();
            } else {
                new AlertDialog.Builder(this)
                        .setTitle(R.string.download_failed_generic_dlg_title)
                        .setIcon(R.drawable.ssl_icon)
                        .setMessage(BrowserDownloadAdapter.getErrorText(status))
                        .setPositiveButton(R.string.ok, null)
                        .show();
            }
        }
        return position;
    }
    
    /**
     * Resume a given download
     * @param id Row id of the download to resume
     */
    private void resumeDownload(final long id) {
        // the relevant functionality doesn't exist in the download manager
    }
    
    /**
     * Prompt the user if they would like to clear the download history
     */
    private void promptClearList() {
        new AlertDialog.Builder(this)
               .setTitle(R.string.download_clear_dlg_title)
               .setIcon(R.drawable.ssl_icon)
               .setMessage(R.string.download_clear_dlg_msg)
               .setPositiveButton(R.string.ok, 
                       new DialogInterface.OnClickListener() {
                           public void onClick(DialogInterface dialog, 
                                   int whichButton) {
                               clearAllDownloads();
                           }
                       })
                .setNegativeButton(R.string.cancel, null)
                .show();
    }
    
    /**
     * Return the number of items in the list that can be canceled.
     * @return count
     */
    private int getCancelableCount() {
        // Count the number of items that will be canceled.
        int count = 0;
        if (mDownloadCursor != null) {
            for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast(); 
                    mDownloadCursor.moveToNext()) {
                int status = mDownloadCursor.getInt(mStatusColumnId);
                if (!Downloads.isStatusCompleted(status)) {
                    count++;
                }
            }
        }
        
        return count;
    }
    
    /**
     * Prompt the user if they would like to clear the download history
     */
    private void promptCancelAll() {
        int count = getCancelableCount();
        
        // If there is nothing to do, just return
        if (count == 0) {
            return;
        }
        
        // Don't show the dialog if there is only one download
        if (count == 1) {
            cancelAllDownloads();
            return;
        }
        String msg = 
            getString(R.string.download_cancel_dlg_msg, count);
        new AlertDialog.Builder(this)
                .setTitle(R.string.download_cancel_dlg_title)
                .setIcon(R.drawable.ssl_icon)
                .setMessage(msg)
                .setPositiveButton(R.string.ok, 
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, 
                                    int whichButton) {
                                cancelAllDownloads();
                            }
                        })
                 .setNegativeButton(R.string.cancel, null)
                 .show();
    }
    
    /**
     * Cancel all downloads. As canceled downloads are not
     * listed, we removed them from the db. Removing a download
     * record, cancels the download.
     */
    private void cancelAllDownloads() {
        if (mDownloadCursor.moveToFirst()) {
            StringBuilder where = new StringBuilder();
            boolean firstTime = true;
            while (!mDownloadCursor.isAfterLast()) {
                int status = mDownloadCursor.getInt(mStatusColumnId);
                if (!Downloads.isStatusCompleted(status)) {
                    if (firstTime) {
                        firstTime = false;
                    } else {
                        where.append(" OR ");
                    }
                    where.append("( ");
                    where.append(Downloads._ID);
                    where.append(" = '");
                    where.append(mDownloadCursor.getLong(mIdColumnId));
                    where.append("' )");
                }
                mDownloadCursor.moveToNext();
            }
            if (!firstTime) {
                getContentResolver().delete(Downloads.CONTENT_URI,
                        where.toString(), null);
            }
        }
    }
    
    private int getClearableCount() {
        int count = 0;
        if (mDownloadCursor.moveToFirst()) {
            while (!mDownloadCursor.isAfterLast()) {
                int status = mDownloadCursor.getInt(mStatusColumnId);
                if (Downloads.isStatusCompleted(status)) {
                    count++;
                }
                mDownloadCursor.moveToNext();
            }
        }
        return count;
    }
    
    /**
     * Clear all stopped downloads, ie canceled (though should not be
     * there), error and success download items.
     */
    private void clearAllDownloads() {
        if (mDownloadCursor.moveToFirst()) {
            StringBuilder where = new StringBuilder();
            boolean firstTime = true;
            while (!mDownloadCursor.isAfterLast()) {
                int status = mDownloadCursor.getInt(mStatusColumnId);
                if (Downloads.isStatusCompleted(status)) {
                    if (firstTime) {
                        firstTime = false;
                    } else {
                        where.append(" OR ");
                    }
                    where.append("( ");
                    where.append(Downloads._ID);
                    where.append(" = '");
                    where.append(mDownloadCursor.getLong(mIdColumnId));
                    where.append("' )");
                }
                mDownloadCursor.moveToNext();
            }
            if (!firstTime) {
                getContentResolver().delete(Downloads.CONTENT_URI,
                        where.toString(), null);
            }
        }
    }
    
    /**
     * Open the content where the download db cursor currently is
     */
    private void openCurrentDownload() {
        int filenameColumnId = 
                mDownloadCursor.getColumnIndexOrThrow(Downloads._DATA);
        String filename = mDownloadCursor.getString(filenameColumnId);
        int mimetypeColumnId =
                mDownloadCursor.getColumnIndexOrThrow(Downloads.COLUMN_MIME_TYPE);
        String mimetype = mDownloadCursor.getString(mimetypeColumnId);
        Uri path = Uri.parse(filename);
        // If there is no scheme, then it must be a file
        if (path.getScheme() == null) {
            path = Uri.fromFile(new File(filename));
        }
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(path, mimetype);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        try {
            startActivity(intent);
        } catch (ActivityNotFoundException ex) {
            new AlertDialog.Builder(this)
                    .setTitle(R.string.download_failed_generic_dlg_title)
                    .setIcon(R.drawable.ssl_icon)
                    .setMessage(R.string.download_no_application)
                    .setPositiveButton(R.string.ok, null)
                    .show();
        }
    }

    /*
     * (non-Javadoc)
     * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
     */
    public void onItemClick(AdapterView parent, View view, int position, 
            long id) {
        // Open the selected item
        mDownloadCursor.moveToPosition(position);
        
        hideCompletedDownload();

        int status = mDownloadCursor.getInt(mStatusColumnId);
        if (Downloads.isStatusSuccess(status)) {
            // Open it if it downloaded successfully
            openCurrentDownload();
        } else {
            // Check to see if there is an error.
            checkStatus(id);
        }
    }
    
    /**
     * hides the notification for the download pointed by mDownloadCursor
     * if the download has completed.
     */
    private void hideCompletedDownload() {
        int status = mDownloadCursor.getInt(mStatusColumnId);

        int visibilityColumn = mDownloadCursor.getColumnIndexOrThrow(Downloads.COLUMN_VISIBILITY);
        int visibility = mDownloadCursor.getInt(visibilityColumn);

        if (Downloads.isStatusCompleted(status) &&
                visibility == Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
            ContentValues values = new ContentValues();
            values.put(Downloads.COLUMN_VISIBILITY, Downloads.VISIBILITY_VISIBLE);
            getContentResolver().update(
                    ContentUris.withAppendedId(Downloads.CONTENT_URI,
                    mDownloadCursor.getLong(mIdColumnId)), values, null, null);
        }
    }
}
