/*
 * Copyright (c) 2015 LingoChamp Inc.
 *
 * 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.liulishuo.filedownloader;

import java.util.List;

/**
 * Created by Jacksgong on 1/22/16.
 */
public class FileDownloadQueueSet {

    private FileDownloadListener target;
    private boolean isSerial;


    private Integer autoRetryTimes;
    private Boolean syncCallback;
    private Boolean isForceReDownload;
    private Integer callbackProgressTimes;
    private Object tag;

    private BaseDownloadTask[] tasks;

    /**
     * @param target for all tasks callback status change
     */
    public FileDownloadQueueSet(FileDownloadListener target) {
        // TODO, support target is null
        if (target == null) {
            throw new IllegalArgumentException("create FileDownloadQueueSet must with valid target!");
        }
        this.target = target;
    }

    /**
     * Form a queue with same {@link #target} and will {@link #start()} in parallel
     */
    public FileDownloadQueueSet downloadTogether(BaseDownloadTask... tasks) {
        this.isSerial = false;
        this.tasks = tasks;

        return this;

    }

    /**
     * Form a queue with same {@link #target} and will {@link #start()} in parallel
     */
    public FileDownloadQueueSet downloadTogether(List<BaseDownloadTask> tasks) {
        this.isSerial = false;
        this.tasks = new BaseDownloadTask[tasks.size()];
        tasks.toArray(this.tasks);

        return this;

    }

    /**
     * Form a queue with same {@link #target} and will {@link #start()} linearly
     */
    public FileDownloadQueueSet downloadSequentially(BaseDownloadTask... tasks) {
        this.isSerial = true;
        this.tasks = tasks;

        return this;
    }

    /**
     * Form a queue with same {@link #target} and will {@link #start()} linearly
     */
    public FileDownloadQueueSet downloadSequentially(List<BaseDownloadTask> tasks) {
        this.isSerial = true;
        this.tasks = new BaseDownloadTask[tasks.size()];
        tasks.toArray(this.tasks);

        return this;
    }

    /**
     * Execute tasks
     *
     * @see #downloadSequentially(BaseDownloadTask...)
     * @see #downloadSequentially(List)
     * @see #downloadTogether(BaseDownloadTask...)
     * @see #downloadTogether(List)
     */
    public void start() {
        for (BaseDownloadTask task : tasks) {
            task.setListener(target);

            if (autoRetryTimes != null) {
                task.setAutoRetryTimes(autoRetryTimes);
            }

            if (syncCallback != null) {
                task.setSyncCallback(syncCallback);
            }

            if (isForceReDownload != null) {
                task.setForceReDownload(isForceReDownload);
            }

            if (callbackProgressTimes != null) {
                task.setCallbackProgressTimes(callbackProgressTimes);
            }

            if (tag != null) {
                task.setTag(tag);
            }

            task.ready();
        }

        FileDownloader.getImpl().start(target, isSerial);
    }

    public FileDownloadQueueSet setAutoRetryTimes(int autoRetryTimes) {
        this.autoRetryTimes = autoRetryTimes;
        return this;
    }

    /**
     * @see BaseDownloadTask#setSyncCallback(boolean)
     */
    public FileDownloadQueueSet setSyncCallback(final boolean syncCallback) {
        this.syncCallback = syncCallback;
        return this;
    }

    /**
     * @see BaseDownloadTask#setForceReDownload(boolean)
     */
    public FileDownloadQueueSet setForceReDownload(final boolean isForceReDownload) {
        this.isForceReDownload = isForceReDownload;
        return this;
    }

    /**
     * @see BaseDownloadTask#setCallbackProgressTimes(int)
     */
    public FileDownloadQueueSet setCallbackProgressTimes(final int callbackProgressTimes) {
        this.callbackProgressTimes = callbackProgressTimes;
        return this;
    }

    /**
     * @see BaseDownloadTask#setCallbackProgressTimes(int)
     */
    public FileDownloadQueueSet disableCallbackProgressTimes() {
        return setCallbackProgressTimes(0);
    }

    /**
     * @see BaseDownloadTask#setTag(Object)
     */
    public FileDownloadQueueSet setTag(final Object tag) {
        this.tag = tag;
        return this;
    }

}

@@ -635,16 +635,44 @@
 oader;%0A%0A
+import java.util.ArrayList;%0A
 import j
@@ -841,16 +841,90 @@
 rial;%0A%0A%0A
+    private List%3CBaseDownloadTask.FinishListener%3E taskFinishListenerList;%0A
     priv
@@ -3571,32 +3571,271 @@
 %0A            %7D%0A%0A
+            if (taskFinishListenerList != null) %7B%0A                for (BaseDownloadTask.FinishListener finishListener : taskFinishListenerList) %7B%0A                    task.addFinishListener(finishListener);%0A                %7D%0A            %7D%0A%0A
             task
@@ -5140,10 +5140,437 @@
 %0A    %7D%0A%0A
+    /**%0A     * @see BaseDownloadTask#addFinishListener(BaseDownloadTask.FinishListener)%0A     */%0A    public FileDownloadQueueSet addTaskFinishListener(%0A            final BaseDownloadTask.FinishListener finishListener) %7B%0A        if (this.taskFinishListenerList == null) %7B%0A            this.taskFinishListenerList = new ArrayList%3C%3E();%0A        %7D%0A%0A        this.taskFinishListenerList.add(finishListener);%0A        return this;%0A    %7D%0A%0A
 %7D%0A

support add FinishListener to each task in a queue