#include "stdafx.h"

#include "NameMatcher.hpp"

#include "Utility.hpp"

#include <assert.h>


CNameMatcher::CNameMatcher(const tstring& pattern, const bool ignoreCase)
	: ignoreCase_(ignoreCase)
	, hasWildcard_(false)
{
	// セミコロン区切りで分割する。
	LPCTSTR p = pattern.c_str();
	LPCTSTR pSt = p;
	while (*p) {
		while (*p && *p != ';') {
			p = CharNext(p);
		}

		size_t len = p - pSt;
		if (len > 0) {
			tstring ptn(pSt, len);
			ptn = StrTrim(ptn);

			if ( !ptn.empty()) {
				// 大文字・小文字を区別しない場合はパターンを小文字に揃えておく
				if (ignoreCase) {
					ToLower(ptn);
				}

				// ワイルドカードが含まれているか?
				if (ptn.find('?') != tstring.npos || ptn.find('*') != tstring.npos) {
					hasWildcard_ = true;
				}

				patterns_.push_back(ptn);
			}
		}
		p = CharNext(p);
		pSt = p;
	}
}


bool CNameMatcher::operator()(const tstring& name) const throw()
{
	const tstring *pName;

	// 大文字・小文字を区別しない場合は比較対象を小文字に揃える.
	tstring ignoreCaseName;
	if ( !ignoreCase_) {
		pName = &name;

	} else {
		ignoreCaseName = name;
		ToLower(ignoreCaseName);
		pName = &ignoreCaseName;
	}

	for (std::list<tstring>::const_iterator ite = patterns_.begin();
		ite != patterns_.end();
		++ite) {
		const tstring& ptn = *ite;
		if (IsMatch(pName->c_str(), ptn.c_str())) {
			return true;
		}
	}
	return false;
}


bool CNameMatcher::empty() const throw()
{
	return patterns_.empty();
}

bool CNameMatcher::hasWildcard() const throw()
{
	return hasWildcard_;
}

size_t CNameMatcher::size() const throw()
{
	return patterns_.size();
}

const tstring& CNameMatcher::operator[](size_t idx) const
{
	assert(idx >= 0 && idx < patterns_.size());
	std::list<tstring>::const_iterator ite = patterns_.begin();
	while (idx > 0) {
		idx--;
		++ite;
	}
	return *ite;
}

tstring CNameMatcher::str() const
{
	tstring buf;
	for (std::list<tstring>::const_iterator ite = patterns_.begin();
		ite != patterns_.end();
		++ite)
	{
		if (buf.length() > 0) {
			buf += _T(";");
		}
		buf += *ite;
	}
	return buf;
}

