/*******************************************************************************
 * Copyright (c) 2003, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.internal.progress;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.osgi.util.NLS;

/**
 * The TaskInfo is the info on a task with a job. It is assumed that there is
 * only one task running at a time - any previous tasks in a Job will be
 * deleted.
 */
public class TaskInfo extends SubTaskInfo {
	double preWork;
	int totalWork;

	/**
	 * Creates a new instance of the receiver with the supplied total work and task
	 * name.
	 *
	 * @param parentJobInfo
	 * @param infoName
	 * @param total
	 */
	TaskInfo(JobInfo parentJobInfo, String infoName, int total) {
		super(parentJobInfo, infoName);
		totalWork = total;
	}

	/**
	 * Adds the work increment to the total.
	 *
	 * @param workIncrement
	 */
	void addWork(double workIncrement) {
		// Don't bother if we are indeterminate
		if (totalWork == IProgressMonitor.UNKNOWN) {
			return;
		}
		preWork += workIncrement;
	}

	/**
	 * Adds the amount of work to the receiver. Update a parent monitor by the
	 * increment scaled to the amount of ticks this represents.
	 *
	 * @param workIncrement int the amount of work in the receiver
	 * @param parentMonitor The IProgressMonitor that is also listening
	 * @param parentTicks   the number of ticks this monitor represents
	 */
	void addWork(double workIncrement, IProgressMonitor parentMonitor, int parentTicks) {
		// Don't bother if we are indeterminate.
		if (totalWork == IProgressMonitor.UNKNOWN) {
			return;
		}

		addWork(workIncrement);
		parentMonitor.internalWorked(workIncrement * parentTicks / totalWork);
	}

	@Override
	String getDisplayString(boolean showProgress) {
		if (totalWork == IProgressMonitor.UNKNOWN) {
			return unknownProgress();
		}

		if (taskName == null) {
			return getDisplayStringWithoutTask(showProgress);
		}

		if (showProgress) {
			String[] messageValues = new String[3];
			messageValues[0] = String.valueOf(getPercentDone());
			messageValues[1] = jobInfo.getJob().getName();
			messageValues[2] = taskName;

			return NLS.bind(ProgressMessages.JobInfo_DoneMessage, messageValues);
		}
		String[] messageValues = new String[2];
		messageValues[0] = jobInfo.getJob().getName();
		messageValues[1] = taskName;

		return NLS.bind(ProgressMessages.JobInfo_DoneNoProgressMessage, messageValues);
	}

	/**
	 * Returns the display String without the task name.
	 *
	 * @param showProgress Whether or not we are showing progress
	 *
	 * @return String
	 */
	String getDisplayStringWithoutTask(boolean showProgress) {
		if (!showProgress || totalWork == IProgressMonitor.UNKNOWN) {
			return jobInfo.getJob().getName();
		}

		return NLS.bind(ProgressMessages.JobInfo_NoTaskNameDoneMessage, jobInfo.getJob().getName(),
				String.valueOf(getPercentDone()));
	}

	/**
	 * Returns an integer representing the amount of work completed. If progress is
	 * indeterminate return IProgressMonitor.UNKNOWN.
	 *
	 * @return int IProgressMonitor.UNKNOWN or a value between 0 and 100.
	 */
	int getPercentDone() {
		if (totalWork == IProgressMonitor.UNKNOWN) {
			return IProgressMonitor.UNKNOWN;
		}

		return Math.min((int) (preWork * 100 / totalWork), 100);
	}

	/**
	 * Returns the progress for a monitor whose totalWork is
	 * <code>IProgressMonitor.UNKNOWN</code>.
	 *
	 * @return String
	 */
	private String unknownProgress() {
		if (taskName == null) {
			return jobInfo.getJob().getName();
		}
		String[] messageValues = new String[2];
		messageValues[0] = jobInfo.getJob().getName();
		messageValues[1] = taskName;
		return NLS.bind(ProgressMessages.JobInfo_UnknownProgress, messageValues);
	}
}
