/*
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 1, or (at your option)
** any later version.

** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.

** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "stdafx.h"

#include "BrowseViewModel.h"
#include "Persistent.h"
#include "CvsEntries.h"

#if qMacPP
#	include "MacMisc.h"
#endif

/////////////////////////////////////////////////////////////////////////////
// KoFilterModel implementation
static CPersistentBool persistentChanged("P_ViewChanged", false);
static CPersistentBool persistentAdded("P_ViewAdded", false);
static CPersistentBool persistentRemoved("P_ViewRemoved", false);
static CPersistentBool persistentConflicts("P_ViewConflicts", false);
static CPersistentBool persistentUnknown("P_ViewUnknown", false);
static CPersistentBool persistentHideUnknown("P_ViewHideUnknown", false);
static CPersistentBool persistentMissing("P_ViewMissing", false);
	
KoFilterModel::KoFilterModel()
: m_isChanged(persistentChanged)
, m_isAdded(persistentAdded)
, m_isRemoved(persistentRemoved)
, m_isConflicts(persistentConflicts)
, m_isUnknown(persistentUnknown)
, m_isMissing(persistentMissing)
, m_isHideUnknown(persistentHideUnknown)
{}

KoFilterModel::~KoFilterModel()
{
	persistentChanged = m_isChanged;
	persistentAdded = m_isAdded;
	persistentRemoved = m_isRemoved;
	persistentConflicts = m_isConflicts;
	persistentUnknown = m_isUnknown;
	persistentMissing = m_isMissing;
	persistentHideUnknown = m_isHideUnknown;
}

bool KoFilterModel::IsDefaultMode() const
{
	return !m_isConflicts && !m_isChanged && !m_isMissing && !m_isAdded && !m_isRemoved;
}

bool KoFilterModel::IsMatch(EntnodeData* data)
{
	// check to see if file name matches
	if (m_match.size() && !MatchIgnoredList(data->GetName(), m_match))
	{
		return false;
	}

	if (IsDefaultMode() && !m_isUnknown)
	{
		// check if unknown files are to be hidden
		if (data->IsUnknown() && m_isHideUnknown)
		{
			// unknown item match
			return false;
		}

		return true;
	}
	
	if (data->IsMissing() && data->IsRemoved() && m_isRemoved)
	{
		// removed item match
		return true;
	}

	if (data->IsMissing() && !data->IsRemoved() && m_isMissing)
	{
		// missing item match
		return true;
	}

	if (data->IsUnknown() && m_isUnknown)
	{
		// unknown item match
		return true;
	}

	if ((data->GetConflict() != NULL) && m_isConflicts)
	{
		// conflict match
		return true;
	}

	if (!data->IsUnmodified())
	{
		// can be either changed or added 
		const char* vn = (*data)[EntnodeFile::kVN];
		bool isAdded = vn && (strcmp(vn, "0") == 0);
		if (isAdded && m_isAdded)
		{
			// added file match
			return true;
		}
		if (!isAdded && m_isChanged)
		{
			// changed file match
			return true;
		}
	}

	// no match
	return false;
}

// toggles hide unknown flag
void KoFilterModel::ToggleHideUnknown()
{
	m_isHideUnknown = !m_isHideUnknown;
	if (m_isHideUnknown)
	{
		m_isUnknown = false;
	}
}

// toggles show conflict flag
void KoFilterModel::ToggleUnknown()
{
	m_isUnknown = !m_isUnknown;
	if (m_isUnknown)
	{
		m_isHideUnknown = false;
	}
}


void KoFilterModel::ToggleModified()
{
	m_isAdded = 
	m_isChanged = 
	m_isRemoved = 
	m_isConflicts = !IsModified();
}

//accessor for modified flag
bool KoFilterModel::IsModified() const
{
	bool isModified = m_isAdded && m_isChanged && m_isRemoved && m_isConflicts;
	return isModified;
}

NotificationManager* KoFilterModel::GetNotificationManager()
{
	return &m_manager;
}

bool KoFilterModel::SetMask(const char *fileMask)
{
	bool changed = m_mask.empty() || fileMask == 0L || stricmp(m_mask, fileMask) != 0;
	if (changed)
	{
		m_mask = fileMask;
		m_match.clear();
		if (!m_mask.empty())
		{
			// build match list 
			UStr mask = fileMask;
			char * buffer = mask;
			static const char separators[] = " \t;";
			for (char * token = strtok(buffer, separators); token; token = strtok(NULL, separators))
			{
				m_match.push_back(UStr(token));
			}
		}		
	}
	return changed;
}

////////////////////////////////////////////////////////////////////////
// recursion model implementation
static CPersistentBool persistentRecursive("P_DisplayRecursive", false);

KoRecursionModel::KoRecursionModel()
: m_isRecursive(persistentRecursive)
{}

KoRecursionModel::~KoRecursionModel()
{
	persistentRecursive = m_isRecursive;
}

bool KoRecursionModel::IsShowRecursive()
{
	return m_isRecursive;
}

NotificationManager* KoRecursionModel::GetNotificationManager()
{
	return &m_manager;
}

void KoRecursionModel::ToggleRecursion()
{
	m_isRecursive = !m_isRecursive;
};

////////////////////////////////////////////////////////////////////////
// ignore model implementation
static CPersistentBool persistentIgnore("P_FileViewIgnore", true);

KoIgnoreModel::KoIgnoreModel()
: m_isIgnore(persistentIgnore)
{}

KoIgnoreModel::~KoIgnoreModel()
{
	persistentIgnore = 	m_isIgnore;
}

bool KoIgnoreModel::IsShowIgnored()
{
	return m_isIgnore;
}

NotificationManager* KoIgnoreModel::GetNotificationManager()
{
	return &m_manager;
}

void KoIgnoreModel::ToggleIgnore()
{
	m_isIgnore = !m_isIgnore;
};
