
package jp.sourceforge.nicoro;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;

public interface VideoLoaderInterface extends FFmpegIOCallback {

    public interface EventListener {
    	/**
    	 * キャッシュのダウンロードを開始した（＝ダウンロードの必要があった）
    	 * @param streamLoader
    	 */
    	void onStarted(VideoLoaderInterface streamLoader);
    	/**
    	 * ファイルの先頭部分の読み込み完了
    	 * @param streamLoader
    	 */
    	void onCached(VideoLoaderInterface streamLoader);
    	/**
    	 * ファイル全体の読み込み完了
    	 * @param streamLoader
    	 */
    	void onFinished(VideoLoaderInterface streamLoader);
    	/**
    	 * エラー発生
    	 * @param streamLoader
    	 * @param errorMessage
    	 */
    	void onOccurredError(VideoLoaderInterface streamLoader, String errorMessage);
    	/**
    	 * 読み込み経過の通知
    	 * @param seekOffsetWrite 分子
    	 * @param contentLength 分母
    	 */
    	void onNotifyProgress(int seekOffsetWrite, int contentLength);
        /**
         * キャッシュのダウンロードを再開した（＝いったんネットワーク接続が切れた）
         * @param streamLoader
         */
        void onRestarted(VideoLoaderInterface streamLoader);
    }

    boolean isNull();

    void startLoad();

    void finish();

    void finishAsync(ExecutorService executorService, final CallbackMessage<Void, Void> callback);

    void finishAsync(ExecutorService executorService, final CountDownLatch latch);

    boolean hasCache();

    void setEventListener(VideoLoaderInterface.EventListener eventListener);

    String getFilePath();

    String getVideoV();

    long getContentLength();

    String getETag();

    String getLastModified();

    long getSeekOffsetRead();

    int getEcoType();

    String getMovieType();

    String getContentType();

    boolean isCacheCompleted();

    String getUrl();

    InputStream createInputStream();

    public static class NullObject implements VideoLoaderInterface {
        private static final NullObject sInstance = new NullObject();
        public static NullObject getInstance() {
            return sInstance;
        }

        private NullObject() {
        }

        @Override
        public int readFromNativeCallback(int bufSize, byte[] buffer) {
            return -1;
        }

        @Override
        public long seekFromNativeCallback(long offset, int whence) {
            return -1;
        }

        @Override
        public boolean isNull() {
            return true;
        }

        @Override
        public void startLoad() {
        }

        @Override
        public void finish() {
        }

        @Override
        public void finishAsync(ExecutorService executorService,
                CallbackMessage<Void, Void> callback) {
            if (callback != null) {
                callback.sendMessageSuccess(null);
            }
        }

        @Override
        public void finishAsync(ExecutorService executorService, CountDownLatch latch) {
            latch.countDown();
        }

        @Override
        public boolean hasCache() {
            return false;
        }

        @Override
        public void setEventListener(EventListener eventListener) {
        }

        @Override
        public String getFilePath() {
            return "";
        }

        @Override
        public String getVideoV() {
            return "";
        }

        @Override
        public long getContentLength() {
            return 0;
        }

        @Override
        public String getETag() {
            return "";
        }

        @Override
        public String getLastModified() {
            return "";
        }

        @Override
        public long getSeekOffsetRead() {
            return 0;
        }

        @Override
        public int getEcoType() {
            return NicoroAPIManager.ECO_TYPE_HIGH;
        }

        @Override
        public String getMovieType() {
            return "";
        }

        @Override
        public String getContentType() {
            return "";
        }

        @Override
        public boolean isCacheCompleted() {
            return false;
        }

        @Override
        public String getUrl() {
            return "";
        }

        @Override
        public InputStream createInputStream() {
            return new InputStream() {
                @Override
                public int read() throws IOException {
                    return -1;
                }
            };
        }
    }
}
