/*
 * Copyright (C) 2009 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.sdklib.internal.repository;

import com.android.sdklib.ISdkLog;
import com.android.util.Pair;


/**
 * A monitor interface for a {@link ITask}.
 * <p/>
 * Depending on the task factory that created the task, there might not be any UI
 * or it might not implement all the methods, in which case calling them would be
 * a no-op but is guaranteed not to crash.
 * <p/>
 * If the task runs in a non-UI worker thread, the task factory implementation
 * will take care of the update the UI in the correct thread. The task itself
 * must not have to deal with it.
 * <p/>
 * A monitor typically has 3 levels of text displayed: <br/>
 * - A <b>title</b> <em>may</em> be present on a task dialog, typically when a task
 *   dialog is created. This is not covered by this monitor interface. <br/>
 * - A <b>description</b> displays prominent information on what the task
 *   is currently doing. This is expected to vary over time, typically changing
 *   with each sub-monitor, and typically only the last description is visible.
 *   For example an updater would typically have descriptions such as "downloading",
 *   "installing" and finally "done". This is set using {@link #setDescription}. <br/>
 * - A <b>verbose</b> optional log that can provide more information than the summary
 *   description and is typically displayed in some kind of scrollable multi-line
 *   text field so that the user can keep track of what happened. 3 levels are
 *   provided: error, normal and verbose. An UI may hide the log till an error is
 *   logged and/or might hide the verbose text unless a flag is checked by the user.
 *   This is set using {@link #log}, {@link #logError} and {@link #logVerbose}.
 * <p/>
 * A monitor is also an {@link ISdkLog} implementation.
 */
public interface ITaskMonitor extends ISdkLog {

    /**
     * Sets the description in the current task dialog.
     * This method can be invoked from a non-UI thread.
     */
    public void setDescription(String format, Object...args);

    /**
     * Logs a "normal" information line.
     * This method can be invoked from a non-UI thread.
     */
    public void log(String format, Object...args);

    /**
     * Logs an "error" information line.
     * This method can be invoked from a non-UI thread.
     */
    public void logError(String format, Object...args);

    /**
     * Logs a "verbose" information line, that is extra details which are typically
     * not that useful for the end-user and might be hidden until explicitly shown.
     * This method can be invoked from a non-UI thread.
     */
    public void logVerbose(String format, Object...args);

    /**
     * Sets the max value of the progress bar.
     * This method can be invoked from a non-UI thread.
     *
     * This method MUST be invoked once before using {@link #incProgress(int)} or
     * {@link #getProgress()} or {@link #createSubMonitor(int)}. Callers are
     * discouraged from using more than once -- implementations can either discard
     * the next calls or behave incoherently.
     */
    public void setProgressMax(int max);

    /**
     * Returns the max valie of the progress bar, as last set by {@link #setProgressMax(int)}.
     * Returns 0 if the max has never been set yet.
     */
    public int getProgressMax();

    /**
     * Increments the current value of the progress bar.
     * This method can be invoked from a non-UI thread.
     *
     * Callers MUST use setProgressMax before using this method.
     */
    public void incProgress(int delta);

    /**
     * Returns the current value of the progress bar,
     * between 0 and up to {@link #setProgressMax(int)} - 1.
     *
     * Callers MUST use setProgressMax before using this method.
     */
    public int getProgress();

    /**
     * Returns true if the user requested to cancel the operation.
     * It is up to the task thread to pool this and exit as soon
     * as possible.
     */
    public boolean isCancelRequested();

    /**
     * Creates a sub-monitor that will use up to tickCount on the progress bar.
     * tickCount must be 1 or more.
     */
    public ITaskMonitor createSubMonitor(int tickCount);

    /**
     * Display a yes/no question dialog box.
     *
     * Implementations MUST allow this to be called from any thread, e.g. by
     * making sure the dialog is opened synchronously in the ui thread.
     *
     * @param title The title of the dialog box
     * @param message The error message
     * @return true if YES was clicked.
     */
    public boolean displayPrompt(final String title, final String message);

    /**
     * Launch an interface which asks for login and password. Implementations
     * MUST allow this to be called from any thread, e.g. by making sure the
     * dialog is opened synchronously in the UI thread.
     *
     * @param title The title of the dialog box.
     * @param message The message to be displayed as an instruction.
     * @return Returns a {@link Pair} holding the entered login and password.
     *         The information must always be in the following order:
     *         Login,Password. So in order to retrieve the <b>login</b> callers
     *         should retrieve the first element, and the second value for the
     *         <b>password</b>.
               If operation is <b>canceled</b> by user the return value must be <b>null</b>.
     */
    public Pair<String, String> displayLoginPasswordPrompt(String title, String message);
}
