// Copyright (c) 2020 - 2021 kio@little-bat.de
// BSD-2-Clause license
// https://opensource.org/licenses/BSD-2-Clause

#include "Machine.h"
#include "unix/FD.h"


Machine::Machine(char* m) :
	memory(m),
	firstitem(nullptr),
	lastitem(nullptr),
	cpu(nullptr),
	is_power_on(no),
	is_suspended(no)
{}

Machine::~Machine()
{
	is_power_on = no;

	for (Item* item = lastitem; item; item = item->prev)
	{
		delete item;
	}
}

void Machine::addItem (Item* item)
{
	if (item->isA(isa_CpuRiscV))
	{
		cpu = reinterpret_cast<Cpu*>(item);

		item->machine = this;
		item->prev = nullptr;
		item->next = firstitem;

		if (firstitem) firstitem->prev = item;

		if (!lastitem) lastitem = item;
		firstitem = item;
	}
	else
	{

		item->machine = this;
		item->prev = lastitem;
		item->next = nullptr;

		if (lastitem) lastitem->next = item;

		if (!firstitem) firstitem = item;
		lastitem = item;
	}
}

void Machine::removeItem (Item* item)
{
	if (item->next)
	{
		item->next->prev = item->prev;
	}
	if (item->prev)
	{
		item->prev->next = item->next;
	}
	if (firstitem == item)
	{
		firstitem = item->next;
	}
	if (lastitem == item)
	{
		lastitem = item->prev;
	}
	if (cpu == item)
	{
		cpu = nullptr;
	}

	item->next = nullptr;
	item->prev = nullptr;
	item->machine = nullptr;
}

void Machine::powerOn()
{
	for (Item* p = firstitem; p; p = p->next)
	{
		p->powerOn();
	}

	is_power_on = true;
}

bool Machine::powerOff()
{
	bool f = !is_power_on;
	is_power_on = false;
	return f;
}

void Machine::powerCycle()
{
	powerOff();
	powerOn();
}

void Machine::reset()
{
	Time  t = now();

	for (Item* p = firstitem; p; p = p->next)
	{
		p->reset(t);
	}
}


void Machine::loadBinaryFile ()
{
	TODO();
}
















