/*==LICENSE==*

CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011  Cyan Worlds, Inc.

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 3 of the License, 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, see <http://www.gnu.org/licenses/>.

You can contact Cyan Worlds, Inc. by email legal@cyan.com
 or by snail mail at:
      Cyan Worlds, Inc.
      14617 N Newport Hwy
      Mead, WA   99021

*==LICENSE==*/
/*****************************************************************************
*
*   $/Plasma20/Sources/Plasma/NucleusLib/pnUtils/Private/pnUtPath.cpp
*   
***/

#include "../Pch.h"
#pragma hdrstop


/****************************************************************************
*
*   Exported functions
*
***/

//===========================================================================
void PathGetProgramDirectory (
    wchar       *dst,
    unsigned     dstChars
) {
    ASSERT(dst);
    ASSERT(dstChars);

    PathGetProgramName(dst, dstChars);
    PathRemoveFilename(dst, dst, dstChars);
}

//===========================================================================
void PathAddFilename (
    wchar       *dst, 
    const wchar  src[], 
    const wchar  fname[],
    unsigned     dstChars
) {
    ASSERT(dst);
    ASSERT(dstChars);

    wchar temp[MAX_PATH];
    if (dst == src) {
        StrCopy(temp, src, arrsize(temp));
        src = temp;
    }
    else if (dst == fname) {
        StrCopy(temp, fname, arrsize(temp));
        fname = temp;
    }

    PathMakePath(dst, dstChars, 0, src, fname, 0);
}

//===========================================================================
void PathRemoveFilename (
    wchar       *dst, 
    const wchar  src[], 
    unsigned     dstChars
) {
    ASSERT(dst);
    ASSERT(src);
    ASSERT(dstChars);

    wchar drive[MAX_DRIVE];
    wchar dir[MAX_DIR];
    PathSplitPath(src, drive, dir, 0, 0);
    PathMakePath(dst, dstChars, drive, dir, 0, 0);
}

//===========================================================================
void PathRemoveExtension (
    wchar       *dst, 
    const wchar  src[], 
    unsigned     dstChars
) {
    ASSERT(dst);
    ASSERT(src);
    ASSERT(dstChars);

    wchar drive[MAX_DRIVE];
    wchar dir[MAX_DIR];
    wchar fname[MAX_FNAME];
    PathSplitPath(src, drive, dir, fname, 0);
    PathMakePath(dst, dstChars, drive, dir, fname, 0);
}

//===========================================================================
void PathSetExtension (
    wchar       *dst, 
    const wchar  src[],
    const wchar  ext[],
    unsigned     dstChars
) {
    ASSERT(dst);
    ASSERT(src);
    ASSERT(dst != ext);
    ASSERT(dstChars);

    wchar drive[MAX_DRIVE];
    wchar dir[MAX_DIR];
    wchar fname[MAX_FNAME];
    PathSplitPath(src, drive, dir, fname, 0);
    PathMakePath(dst, dstChars, drive, dir, fname, ext);
}

//===========================================================================
void PathAddExtension (
    wchar       *dst, 
    const wchar  src[],
    const wchar  ext[],
    unsigned     dstChars
) {
    ASSERT(dst);
    ASSERT(src);
    ASSERT(dst != ext);
    ASSERT(dstChars);

    wchar drive[MAX_DRIVE];
    wchar dir[MAX_DIR];
    wchar fname[MAX_FNAME];
    wchar oldext[MAX_EXT];
    PathSplitPath(src, drive, dir, fname, oldext);
    PathMakePath(
        dst, 
        dstChars,
        drive, 
        dir, 
        fname, 
        oldext[0] ? oldext : ext
    );
}

//===========================================================================
void PathRemoveDirectory (
    wchar       *dst, 
    const wchar  src[], 
    unsigned     dstChars
) {
    ASSERT(dst);
    ASSERT(src);
    ASSERT(dstChars);

    wchar fname[MAX_FNAME];
    wchar ext[MAX_EXT];
    PathSplitPath(src, 0, 0, fname, ext);
    PathMakePath(dst, dstChars, 0, 0, fname, ext);
}


/*****************************************************************************
*
*   Email formatting functions
*
***/

//============================================================================
void PathSplitEmail (
	const wchar	emailAddr[],
	wchar *		user,
	unsigned	userChars,
	wchar *		domain,
	unsigned	domainChars,
	wchar *		tld,
	unsigned	tldChars,
	wchar *		subDomains,
	unsigned	subDomainChars,
	unsigned	subDomainCount
) {
	ASSERT(emailAddr);
	
	#define SUB_DOMAIN(i) subDomains[(i) * subDomainChars]

	// null-terminate all output parameters
	if (userChars) {
		ASSERT(user);
		user[0] = 0;
	}
	if (domainChars) {
		ASSERT(domain);
		domain[0] = 0;
	}
	if (tldChars) {
		ASSERT(tld);
		tld[0] = 0;
	}
	if (subDomainChars || subDomainCount) {
		ASSERT(subDomains);
		for (unsigned i = 0; i < subDomainCount; ++i)
			SUB_DOMAIN(i) = 0;
	}

	// bail now if email address is zero-length
	unsigned len = StrLen(emailAddr);
	if (!len)
		return;

	// copy email address so we can tokenize it
	wchar * tmp = ALLOCA(wchar, len + 1);
	StrCopy(tmp, emailAddr, len + 1);
	const wchar * work = tmp;

	// parse user	
	wchar token[MAX_PATH];
	if (!StrTokenize(&work, token, arrsize(token), L"@"))
		return;

	// copy user to output parameter
	if (userChars)
		StrCopy(user, token, userChars);

	// skip past the '@' symbol
	if (!*work++)
		return;
	
	// parse all domains
	ARRAY(wchar *) arr;
	while (StrTokenize(&work, token, arrsize(token), L".")) {
		unsigned toklen = StrLen(token);
		wchar * str = ALLOCA(wchar, toklen + 1);
		StrCopy(str, token, toklen + 1);
		arr.Add(str);
	}

	// copy domains to output parameters
	unsigned index = 0;
	if (arr.Count() > 2) {
		// all domains except for the last two are sub-domains
		for (index = 0; index < arr.Count() - 2; ++index) {
			if (index < subDomainCount)
				if (subDomains)
					StrCopy(&SUB_DOMAIN(index), arr[index], subDomainChars);
		}
	}
	if (arr.Count() > 1) {
		// second to last domain is the primary domain
		if (domain)
			StrCopy(domain, arr[index], domainChars);
		// last comes the top level domain
		++index;
		if (tld)
			StrCopy(tld, arr[index], tldChars);
	}
	else if (arr.Count() == 1) {
		// if only one domain, return it as a sub-domain
		if (index < subDomainCount)
			if (subDomains)
				StrCopy(&SUB_DOMAIN(index), arr[index], subDomainChars);
	}
	
	#undef SUB_DOMAIN
}