package com.adamnickle.deck.Game;
import android.content.Context;
import android.support.v7.widget.CardView;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.format.DateFormat;
import android.util.JsonReader;
import android.util.JsonWriter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.adamnickle.deck.BuildConfig;
import com.adamnickle.deck.R;
import com.adamnickle.deck.SwipeDismissTouchListener;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import ru.noties.debug.Debug;
public final class GameSaveIO
{
private static final String GAME_SAVE_FOLDER = "deck_game_saves";
private static final String GAME_SAVE_PREFIX = "deck_game_save_";
private static final String GAME_SAVE_FILE_EXTENSION = ".json";
private static final String PLAYERS_NAME = "players";
private static final String LEFT_PLAYERS_NAME = "left_players";
private GameSaveIO() { }
private static String getGameSaveFileName( String gameSaveName )
{
return GAME_SAVE_PREFIX + gameSaveName + GAME_SAVE_FILE_EXTENSION;
}
private static String getGameSaveNameFromFile( File gameSave )
{
final String fileName = gameSave.getName();
return fileName.substring( GAME_SAVE_PREFIX.length(), fileName.length() - GAME_SAVE_FILE_EXTENSION.length() );
}
public static boolean openGameSave( File gameSave, HashMap<String, CardHolder > players, HashMap<String, CardHolder > leftPlayers )
{
boolean success = true;
InputStreamReader inputStreamReader = null;
try
{
inputStreamReader = new FileReader( gameSave );
JsonReader reader = new JsonReader( inputStreamReader );
reader.beginObject();
while( reader.hasNext() )
{
String name = reader.nextName();
if( name.equals( PLAYERS_NAME ) )
{
reader.beginArray();
while( reader.hasNext() )
{
CardHolder player = CardHolder.readFromJson( reader );
players.put( player.getID(), player );
}
reader.endArray();
}
else if( name.equals( LEFT_PLAYERS_NAME ) )
{
reader.beginArray();
while( reader.hasNext() )
{
CardHolder player = CardHolder.readFromJson( reader );
leftPlayers.put( player.getID(), player );
}
reader.endArray();
}
else
{
reader.skipValue();
}
}
reader.endObject();
}
catch( IOException io )
{
Debug.e( "Failed to save game.", io );
success = false;
}
catch( IllegalStateException se )
{
Debug.e( "Failed to save game.", se );
success = false;
}
finally
{
try
{
if( inputStreamReader != null )
{
inputStreamReader.close();
}
}
catch( IOException io )
{
io.printStackTrace();
}
}
return success;
}
public static boolean saveGame( Context context, String gameSaveName, CardHolder[] players, CardHolder[] leftPlayers )
{
if( gameSaveName.isEmpty() || gameSaveName.contains( " " ) )
{
return false;
}
boolean success = true;
OutputStreamWriter outputStreamWriter = null;
try
{
File gameSaveDir = new File( context.getApplicationContext().getFilesDir(), GAME_SAVE_FOLDER );
if( !gameSaveDir.exists() || !gameSaveDir.isDirectory() )
{
if( !gameSaveDir.mkdirs() )
{
throw new IOException( "Could not create Deck game save folder." );
}
}
File saveFile = new File( gameSaveDir, getGameSaveFileName( gameSaveName ) );
outputStreamWriter = new FileWriter( saveFile );
JsonWriter writer = new JsonWriter( outputStreamWriter );
writer.setIndent( " " );
writer.beginObject();
writer.name( PLAYERS_NAME ).beginArray();
for( CardHolder player : players )
{
player.writeToJson( writer );
}
writer.endArray();
writer.name( LEFT_PLAYERS_NAME ).beginArray();
for( CardHolder player : leftPlayers )
{
player.writeToJson( writer );
}
writer.endArray();
writer.endObject();
}
catch( IOException io )
{
Debug.e( "Failed to save game.", io );
success = false;
}
catch( IllegalStateException se )
{
Debug.e( "Failed to save game.", se );
success = false;
}
finally
{
try
{
if( outputStreamWriter != null )
{
outputStreamWriter.close();
}
}
catch( IOException io )
{
io.printStackTrace();
}
}
return success;
}
public static RecyclerView getGameSaveCards( Context context )
{
final File file = new File( context.getFilesDir(), GAME_SAVE_FOLDER );
final File[] gameSaveFiles = file.listFiles( new FilenameFilter()
{
@Override
public boolean accept( File file, String s )
{
return s.startsWith( GAME_SAVE_PREFIX );
}
} );
if( gameSaveFiles == null || gameSaveFiles.length == 0 )
{
return null;
}
else
{
final GameSaveCardAdapter adapter = new GameSaveCardAdapter( context, gameSaveFiles );
final RecyclerView recyclerView = new RecyclerView( context );
recyclerView.setHasFixedSize( false );
recyclerView.setAdapter( adapter );
recyclerView.setLayoutManager( new LinearLayoutManager( context ) );
return recyclerView;
}
}
public static class GameSaveCardAdapter extends RecyclerView.Adapter<GameSaveCardAdapter.GameSaveHolder>
{
private final Context mContext;
private ArrayList<File> mData;
private GameSaveOnClickListener mListener;
public GameSaveCardAdapter( Context context, File[] data )
{
this( context, Arrays.asList( data ) );
}
public GameSaveCardAdapter( Context context, List<File> data )
{
mContext = context;
mData = new ArrayList<File>( data );
}
public void setGameSaveOnClickListener( GameSaveOnClickListener listener )
{
mListener = listener;
}
@Override
public GameSaveHolder onCreateViewHolder( ViewGroup viewGroup, int i )
{
return new GameSaveHolder( LayoutInflater.from( mContext ).inflate( R.layout.gamesave_card_layout, viewGroup, false ) );
}
@Override
public void onBindViewHolder( final GameSaveHolder gameSaveHolder, final int position )
{
final File gameSave = getItem( position );
gameSaveHolder.Title.setText( getGameSaveNameFromFile( gameSave ) );
gameSaveHolder.Subtitle.setText( DateFormat.format( "h:mm aa - MMMM d, yyyy", gameSave.lastModified() ) );
gameSaveHolder.Card.setOnTouchListener( new SwipeDismissTouchListener( gameSaveHolder.Card, null, new SwipeDismissTouchListener.OnDismissCallback()
{
@Override
public void onDismiss( View view, Object token )
{
GameSaveCardAdapter.this.removeItemAt( position );
}
} ) );
gameSaveHolder.Card.setOnClickListener( new View.OnClickListener()
{
@Override
public void onClick( View view )
{
if( mListener != null )
{
mListener.onGameSaveClick( gameSave );
}
}
} );
final HashMap< String, CardHolder > cardHolders = new HashMap< String, CardHolder >();
if( GameSaveIO.openGameSave( gameSave, cardHolders, cardHolders ) )
{
final StringBuilder sb = new StringBuilder();
for( CardHolder cardHolder : cardHolders.values() )
{
sb.append( cardHolder.getName() ).append( "\n" );
if( BuildConfig.DEBUG )
{
for( Card card : cardHolder.getCards() )
{
sb.append( "\t" ).append( card.toString() ).append( "\n" );
}
}
}
sb.deleteCharAt( sb.length() - 1 );
gameSaveHolder.Players.setText( sb.toString() );
}
}
public File getItem( int i )
{
return mData.get( i );
}
@Override
public int getItemCount()
{
return mData.size();
}
public boolean removeItemAt( int i )
{
final File gameSave = mData.get( i );
if( gameSave != null && gameSave.delete() )
{
mData.remove( i );
//notifyItemRemoved( i );
notifyDataSetChanged();
return true;
}
else
{
return false;
}
}
public class GameSaveHolder extends RecyclerView.ViewHolder
{
CardView Card;
TextView Title;
TextView Subtitle;
TextView Players;
public GameSaveHolder( View itemView )
{
super( itemView );
Card = (CardView) itemView;
Title = (TextView) itemView.findViewById( R.id.title );
Subtitle = (TextView) itemView.findViewById( R.id.subtitle );
Players = (TextView) itemView.findViewById( R.id.playerList );
}
}
public interface GameSaveOnClickListener
{
public void onGameSaveClick( File scratchPad );
}
}
}