package org.vostan.banvor.game;

import static org.vostan.banvor.App.theApp;

import android.content.SharedPreferences;
import android.util.Log;

import androidx.annotation.NonNull;

import org.vostan.banvor.model.Puzzle;

public class State {
    public static final String TAG = "Sokoban.Sate";
    public static final String CUR_LEVEL = "current_level";
    public static final String HIGH_LEVEL = "highest_unlocked_level";

    protected IPuzzleSource mPuzzleSource;
    protected int mCurrentLevel;
    protected int mHighestUnlockedLevel;
    public static final int MIN_LEVEL = 1;
    protected int mMaxLevel;

    public State(@NonNull IPuzzleSource ps){
        mPuzzleSource = ps;
        mCurrentLevel = 0;
        mHighestUnlockedLevel = 0;
        mMaxLevel = mPuzzleSource.getCount();
    }

    //
    //  These are to save the game state and restore it.
    //
    public void storeState(@NonNull SharedPreferences.Editor prefs){
        prefs.putInt(CUR_LEVEL, mCurrentLevel);
        prefs.putInt(HIGH_LEVEL, mHighestUnlockedLevel);
        prefs.apply();
        if ( !prefs.commit() ) {
            Log.d(TAG, "prefs.edit().commit() failed.");
        }
    }

    public void loadState(@NonNull SharedPreferences prefs){
        mCurrentLevel = prefs.getInt(CUR_LEVEL, MIN_LEVEL);
		mHighestUnlockedLevel = prefs.getInt(HIGH_LEVEL, MIN_LEVEL);
    }

    //
    //	Provide amount of puzzles.
    //
    public final int getPuzzleCount()
    {
        return mPuzzleSource.getCount();
    }

    //
    //	Puzzles.
    //
    public Puzzle getPuzzle(int level )
    {
        return mPuzzleSource.getPuzzle( level-1 );
    }
    public Puzzle getCurrentPuzzle()
    {
        return getPuzzle( getCurrentLevel() );
    }
    public Puzzle getPrevPuzzle()
    {
        if ( mCurrentLevel != MIN_LEVEL ) {
            return getPuzzle(getCurrentLevel() - 1);
        }
        else {
            return null;
        }
    }
    public Puzzle getNextPuzzle()
    {
        if ( mCurrentLevel != mHighestUnlockedLevel) {
            return getPuzzle(getCurrentLevel() + 1);
        }
        else {
            return null;
        }
    }

    //
    //  Level Unlock logic
    //
    public Boolean isLocked(int level){
        return level > mHighestUnlockedLevel;
    }
    private void unlockLevel( int l )
    {
        if ( l > mMaxLevel){
            l = mMaxLevel;
        }
        if ( l > mHighestUnlockedLevel) {
            mHighestUnlockedLevel = l;
        }
        theApp().storeGameState();
    }
    public void levelSolved(int l){
        unlockLevel(l+1);
    }

    //
    //	Provide highest solved puzzle.
    //
    public final int getHighestSolvedLevel(){
        return mHighestUnlockedLevel;
    }
    //
    //	Provide last played puzzle.
    //
    public final int getCurrentLevel(){
        return mCurrentLevel;
    }
    //
    //	Set the current puzzle level.
    //
    public void setCurrentLevel( int l ) {
        if ( l > mHighestUnlockedLevel){
            l = MIN_LEVEL;
        }
        else if ( l < MIN_LEVEL ) {
            l = mHighestUnlockedLevel;
        }
        mCurrentLevel = l;
        theApp().storeGameState();
    }
    public void advanceCurrentLevel(){
        setCurrentLevel(mCurrentLevel+1);
    }
}
