package jp.sourceforge.nicoro;

import android.app.Service;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;

// TODO 将来的にはFFmpegVideoDecoderやMediaPlayerをApplication経由で受け取って独自にバックグラウンド再生
// FIXME Service実行しっぱなしだと呼び出し元のActivityも死ななくなる？のでちょっとまずい。Activityが正常に終了しなかったエラーToastが表示される

public class BackgroundPlayerService extends Service
implements Handler.Callback {
    private static final String KEY_SAVE_CURRENT_PLAY_TIME = "key_save_current_play_time";
    private static final String KEY_SAVE_IS_PAUSE_PLAY = "key_save_is_pause_play";

    private static final int SAVE_TIMER_INTERVAL = 1000 * 5;

    private static final int MSG_ID_SAVE_PLAY_STATE = 0;
    private static final int MSG_ID_UPDATE_PLAY_STATE = 1;

    private SharedPreferences.Editor mPrefEditorPlayState;
    private final HandlerWrapper mHandler = new HandlerWrapper(this);
    private final Messenger mMessenger = new Messenger(mHandler);

    @Override
    public boolean handleMessage(Message msg) {
        switch (msg.what) {
            case MSG_ID_SAVE_PLAY_STATE:
                mPrefEditorPlayState.commit();
                break;
            case MSG_ID_UPDATE_PLAY_STATE:
                Bundle data = msg.peekData();
                if (data != null) {
                    data.setClassLoader(getClassLoader());
                    if (data.containsKey(KEY_SAVE_CURRENT_PLAY_TIME)
                            && data.containsKey(KEY_SAVE_IS_PAUSE_PLAY)) {
                        Rational currentPlayTime = data.getParcelable(
                                KEY_SAVE_CURRENT_PLAY_TIME);
                        AbstractPlayerFragment.putCurrentPlayTime(mPrefEditorPlayState,
                                currentPlayTime);
                        boolean isPausePlay = data.getBoolean(KEY_SAVE_IS_PAUSE_PLAY, false);
                        AbstractPlayerFragment.putIsPausePlay(mPrefEditorPlayState,
                                isPausePlay);
                        mHandler.removeMessages(MSG_ID_SAVE_PLAY_STATE);
                        mHandler.sendEmptyMessageDelayed(MSG_ID_SAVE_PLAY_STATE,
                                SAVE_TIMER_INTERVAL);
                    }
                }
                break;
        }
        return true;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mPrefEditorPlayState = NicoroApplication.getInstance(this).getPrefEditorPlayState();
    }

    @Override
    public void onStart(Intent intent, int startId) {
        handleStart(intent);
    }

    // API Level 5からのためoverrideは行わない
    public int onStartCommand(Intent intent, int flags, int startId) {
        handleStart(intent);
        return START_NOT_STICKY;
    }

    private void handleStart(Intent intent) {
        if (intent == null) {
            return;
        }
    }

    @Override
    public void onDestroy() {
        mHandler.removeMessages(MSG_ID_SAVE_PLAY_STATE);
        mHandler.release();
        mPrefEditorPlayState.commit();
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mMessenger.getBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        mHandler.removeMessages(MSG_ID_SAVE_PLAY_STATE);
        mHandler.sendEmptyMessage(MSG_ID_SAVE_PLAY_STATE);
        return super.onUnbind(intent);
    }

    public static Intent createIntent(Context context) {
        return new Intent(context, BackgroundPlayerService.class);
    }

    public static ComponentName startService(Context context) {
        Intent intent = createIntent(context);
        return context.startService(intent);
    }

    public static void putPlayState(Message msg,
            Rational currentPlayTime, boolean isPausePlay) {
        msg.what = MSG_ID_UPDATE_PLAY_STATE;
        Bundle data = msg.getData();
        data.putParcelable(KEY_SAVE_CURRENT_PLAY_TIME, currentPlayTime);
        data.putBoolean(KEY_SAVE_IS_PAUSE_PLAY, isPausePlay);
    }

    public static boolean stopService(Context context) {
        Intent intent = createIntent(context);
        return context.stopService(intent);
    }
}
