// ==========================================================
// Multi-Page functions
//
// Design and implementation by
// - Floris van den Berg (flvdberg@wxs.nl)
// - checkered (checkered@users.sourceforge.net)
//
// This file is part of FreeImage 3
//
// COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES
// THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE
// OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED
// CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
// THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY
// SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL
// PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER
// THIS DISCLAIMER.
//
// Use at your own risk!
// ==========================================================

#ifdef _MSC_VER 
#pragma warning (disable : 4786) // identifier was truncated to 'number' characters
#endif 

#include "CacheFile.h"

// ----------------------------------------------------------

CacheFile::CacheFile(const char *filename, BOOL keep_in_memory) :
m_file(NULL),
m_filename(),
m_free_pages(),
m_page_cache_mem(),
m_page_cache_disk(),
m_page_map(),
m_page_count(0),
m_current_block(NULL),
m_keep_in_memory(keep_in_memory) {
	if (filename) {
		m_filename = filename;
	}
}

CacheFile::~CacheFile() {
}

BOOL
CacheFile::open() {
	if ((!m_filename.empty()) && (!m_keep_in_memory)) {
		m_file = fopen(m_filename.c_str(), "w+b");
		return (m_file != NULL);
	}

	return (m_keep_in_memory == TRUE);
}

void
CacheFile::close() {
	// dispose the cache entries

	while (!m_page_cache_disk.empty()) {
		Block *block = *m_page_cache_disk.begin();
		m_page_cache_disk.pop_front();
		delete [] block->data;
		delete block;
	}
	while (!m_page_cache_mem.empty()) { 
		Block *block = *m_page_cache_mem.begin(); 
		m_page_cache_mem.pop_front(); 
		delete [] block->data; 
		delete block; 
	} 

	if (m_file) {
		// close the file

		fclose(m_file);

		// delete the file

		remove(m_filename.c_str());
	}
}

void
CacheFile::cleanupMemCache() {
	if (!m_keep_in_memory) {
		if (m_page_cache_mem.size() > CACHE_SIZE) {
			// flush the least used block to file

			Block *old_block = m_page_cache_mem.back();
			fseek(m_file, old_block->nr * BLOCK_SIZE, SEEK_SET);
			fwrite(old_block->data, BLOCK_SIZE, 1, m_file);

			// remove the data

			delete [] old_block->data;
			old_block->data = NULL;

			// move the block to another list

			m_page_cache_disk.splice(m_page_cache_disk.begin(), m_page_cache_mem, --m_page_cache_mem.end());
			m_page_map[old_block->nr] = m_page_cache_disk.begin();
		}
	}
}

int
CacheFile::allocateBlock() {
	Block *block = new Block;
	block->data = new BYTE[BLOCK_SIZE];
	block->next = 0;

	if (!m_free_pages.empty()) {
		block->nr = *m_free_pages.begin();
		m_free_pages.pop_front();
	} else {
		block->nr = m_page_count++;
	}

	m_page_cache_mem.push_front(block);
	m_page_map[block->nr] = m_page_cache_mem.begin();

	cleanupMemCache();

	return block->nr;
}

Block *
CacheFile::lockBlock(int nr) {
	if (m_current_block == NULL) {
		PageMapIt it = m_page_map.find(nr);

		if (it != m_page_map.end()) {
			m_current_block = *(it->second);

			// the block is swapped out to disc. load it back
			// and remove the block from the cache. it might get cached
			// again as soon as the memory buffer fills up

			if (m_current_block->data == NULL) {
				m_current_block->data = new BYTE[BLOCK_SIZE];

				fseek(m_file, m_current_block->nr * BLOCK_SIZE, SEEK_SET);
				fread(m_current_block->data, BLOCK_SIZE, 1, m_file);

				m_page_cache_mem.splice(m_page_cache_mem.begin(), m_page_cache_disk, it->second);
				m_page_map[nr] = m_page_cache_mem.begin();
			}

			// if the memory cache size is too large, swap an item to disc

			cleanupMemCache();

			// return the current block

			return m_current_block;
		}
	}

	return NULL;
}

BOOL
CacheFile::unlockBlock(int nr) {
	if (m_current_block) {
		m_current_block = NULL;

		return TRUE;
	}

	return FALSE;
}

BOOL
CacheFile::deleteBlock(int nr) {
	if (!m_current_block) {
		PageMapIt it = m_page_map.find(nr);

		// remove block from cache

		if (it != m_page_map.end())
			m_page_map.erase(nr);

		// add block to free page list

		m_free_pages.push_back(nr);

		return TRUE;
	}

	return FALSE;
}

BOOL
CacheFile::readFile(BYTE *data, int nr, int size) {
	if ((data) && (size > 0)) {
		int s = 0;
		int block_nr = nr;

		do {
			int copy_nr = block_nr;

			Block *block = lockBlock(copy_nr);

			block_nr = block->next;

			memcpy(data + s, block->data, (s + BLOCK_SIZE > size) ? size - s : BLOCK_SIZE);

			unlockBlock(copy_nr);

			s += BLOCK_SIZE;
		} while (block_nr != 0);

		return TRUE;
	}

	return FALSE;
}

int
CacheFile::writeFile(BYTE *data, int size) {
	if ((data) && (size > 0)) {
		int nr_blocks_required = 1 + (size / BLOCK_SIZE);
		int count = 0;
		int s = 0;
		int stored_alloc;
		int alloc;
		
		stored_alloc = alloc = allocateBlock();

		do {
			int copy_alloc = alloc;

			Block *block = lockBlock(copy_alloc);

			block->next = 0;

			memcpy(block->data, data + s, (s + BLOCK_SIZE > size) ? size - s : BLOCK_SIZE);

			if (count + 1 < nr_blocks_required)
				alloc = block->next = allocateBlock();

			unlockBlock(copy_alloc);

			s += BLOCK_SIZE;			
		} while (++count < nr_blocks_required);

		return stored_alloc;
	}

	return 0;
}

void
CacheFile::deleteFile(int nr) {
	do {
		Block *block = lockBlock(nr);

		if (block == NULL)
			break;

		int next = block->next;

		unlockBlock(nr);

		deleteBlock(nr);

		nr = next;
	} while (nr != 0);
}

