/*
* Copyright 2023, Ali Arya
* Anyone Can Code: Algorithmic Thinking
* Example 5.12c
*/

//simple program demonstrating linked lists

#include <stdio.h>
#include <iostream>
using namespace std;


/////////////////////////////////
// linked list item type

struct Player
{
    int ID;
    Player* Next;
};

//global data for list. 
Player* firstPlayer = NULL; 
Player* lastPlayer = NULL;
Player* newPlayer = NULL;
int numPlayers = 0;  //number of players on the list

/////////////////////////////////
// linked list functions

//create a new player item
void CreatePlayer()
{
    newPlayer = new Player(); //or malloc(sizeof(Player))
    newPlayer->Next = NULL;
    //initialize player data
    //this is just an example: setting ID randomly from 1000 to 1100
    newPlayer->ID = 1000 + rand()%100;
}
//add the new player item to the end
//we could just call InsertPlayer with numPlayers (end of the list) as parameter
void AddPlayer()
{
    //error checking: don't add if there is no new player
    if (newPlayer == NULL)
        return;
    //add the new item
    if (lastPlayer == NULL) //no existing item
        firstPlayer = lastPlayer = newPlayer;
    else //at least one item exists
    {
        lastPlayer->Next = newPlayer;
        lastPlayer = newPlayer;
    }
    numPlayers++;
    newPlayer = NULL;	//to show the new player is already added
}
void InsertPlayer(int i)
{
    //error checking: don't add if there is no new player
    if (newPlayer == NULL)
        return;
    //add the new item
    if (lastPlayer == NULL) //no existing item
        firstPlayer = lastPlayer = newPlayer;
    else if (i >= numPlayers)
    {
        lastPlayer->Next = newPlayer;
        lastPlayer = newPlayer;
    }
    else
    {
        int n = 0;
        Player* tempPlayer = firstPlayer;
        Player* prevPlayer = NULL;
        while (tempPlayer != NULL)
        {
            if (n == i - 1) //point previous to new
            {
                prevPlayer = tempPlayer;
            }
            if (n == i) //insert here
            {
                newPlayer->Next = tempPlayer;
                if(prevPlayer != NULL)
                    prevPlayer->Next = newPlayer;
                if (i == 0)
                    firstPlayer = newPlayer;
                break; //get out of the loop (optional. otherwise the loop finishes doing nothing more)
            }
            else //go to the next item
            {
                n++;
                tempPlayer = tempPlayer->Next;
            }
        }
    }
    numPlayers++;
    newPlayer = NULL;	
}
void DeletePlayer(int i)
{
    int n = 0;
    Player* tempPlayer = firstPlayer;
    Player* prevPlayer = NULL;
    while (tempPlayer != NULL)
    {
        if (n == i - 1) //save the previous to fix its reference later
        {
            prevPlayer = tempPlayer;
        }
        if (n == i) //remove this item
        {
            if (prevPlayer != NULL)
                prevPlayer->Next = tempPlayer->Next;
            if (tempPlayer->Next == NULL) //last
                lastPlayer = prevPlayer;
            if(i == 0)
                firstPlayer = tempPlayer->Next;
            delete tempPlayer;
            numPlayers--;
            break; //get out of the loop (optional)
        }
        else //go to the next item
        {
            n++;
            tempPlayer = tempPlayer->Next;
        }
    }
}
void ReportList()
{
    Player* tempPlayer = firstPlayer;
    while (tempPlayer != NULL)
    {
        cout << tempPlayer->ID;
        cout << "\n";
        tempPlayer = tempPlayer->Next;
    }
}

///////////////////////////////////////////////////////////
//main function

int main()
{

	bool quit = false;
    while (quit == false)
    {
        int command;
        cout << "\n >> 0 - exit, 1 - add, 2 - insert, 3 - delete, 4 - report : ";
        cin >> command;
        switch (command)
        {
        case 0:
            quit = true;
            break;
        case 1:
            CreatePlayer();
            AddPlayer();
            break;
        case 2:
            cout << "enter index: ";
            cin >> command;
            CreatePlayer();
            InsertPlayer(command);
            break;
        case 3:
            cout << "enter index: ";
            cin >> command;
            DeletePlayer(command);
            break;
        case 4:
            ReportList();
            break;
        default:
            cout << "\n enter valid command 0-4\n";
            break;
        }
    }
}