/*
 * ************************************************************************************************************
 * Author: Marcin Załęczny
 * Copyright (C)2010 Marcin Załęczny <mzaleczny@hotmail.com>
 * License: The GNU Lesser General Public License, version 3.0 (LGPLv3)
 * Library Name: mzstd
 * Version: 1.07
 * First release date:   2010-11-08
 * Current release date: 2011-03-04
 *
 *
 * This file is part of mzstd library
 * 
 * mzstd library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * mzstd library 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 * ************************************************************************************************************
 */

#include "mzstdCommon.h"
#include "mzCommandLine.h"

#define PARAM_NAME_STARTING_CHARS       L"-/"


VOID CCommandLine::_commonInit(WCHAR* commandLine) {
    this->setRealClassName(L"CKeyboard");
    
    if (commandLine) {
        ULONG i;
        ULONG len = wcslen(commandLine);
        BOOL longparam_started = FALSE;
        WCHAR cur_ch;
        CString param;
        
        for (i = 0; i < len; i++) {
            cur_ch = commandLine[i];
            if (cur_ch == L'"') {
                if (!longparam_started) {
                    longparam_started = TRUE;
                } else {
                    if (param.length() > 0) {
                        this->append(param);
                    }
                    param = COMMON_EMPTY_STRING;
                    longparam_started = FALSE;
                }
                continue;
            }
            
            if (isCharSpace(cur_ch)) {
                if (longparam_started) {
                    param += cur_ch;
                } else {
                    if (param.length() > 0) {
                        this->append(param);
                    }
                    param = COMMON_EMPTY_STRING;
                }
                continue;
            }
            
            param += cur_ch;
        }
        
        if (param.length() > 0) {
            this->append(param);
        }
    }
}

CCommandLine::CCommandLine() {
    this->_commonInit(NULL);
}

CCommandLine::CCommandLine(LONG argc, WCHAR** argv) {
    CString commandLine;
    for (ULONG i = 1; i < argc; i++) { // we skip program name in first array element
        CString param(argv[i]);
        if (param.containsWhiteSpace()) {
            commandLine += CString(L"\"") + argv[i] + L"\"";
        } else {
            commandLine += argv[i];
        }
        if (i < argc-1) {
            commandLine += L" ";
        }
    }
    
    this->_commonInit(commandLine.getBuffer());
}

CCommandLine::CCommandLine(WCHAR* commandLine) {
    this->_commonInit(commandLine);
}

CCommandLine::~CCommandLine() {
}

LONG CCommandLine::getParamPos(WCHAR* param) {
    if (!param || wcslen(param) < 1) {
        return -1;
    }
    
    CString sparam(param);
    CString cparam;
    sparam.ltrimAllChars(PARAM_NAME_STARTING_CHARS);
    
    ULONG size = this->size();
    for (ULONG i = 0; i < size; i++) {
        cparam = this->getAt(i);
        cparam.ltrimAllChars(PARAM_NAME_STARTING_CHARS);
        if (cparam == sparam) {
            return i;
        }
    }
    
    return -1;
}

BOOL CCommandLine::hasParam(WCHAR* param) {
    return this->getParamPos(param) != -1;
}

CString CCommandLine::getParam(ULONG pos) {
    if (pos < this->size()) {
        return this->getAt(pos);
    }
    return COMMON_EMPTY_STRING;
}

CString CCommandLine::getParamValue(WCHAR* param) {
    LONG paramPos = this->getParamPos(param);
    if (paramPos == -1 || paramPos + 1 == this->size()) {
        return COMMON_EMPTY_STRING;
    }
    
    return this->getAt(paramPos+1);
}

VOID CCommandLine::removeParam(WCHAR* param) {
    LONG paramPos = this->getParamPos(param);
    if (paramPos == -1) {
        return;
    }
    
    this->delAt(paramPos);
    while (paramPos < this->size() && this->getAt(paramPos).startsWithOneOfChars(PARAM_NAME_STARTING_CHARS)) {
        this->delAt(paramPos);
    }
}

ULONG CCommandLine::getParamsCount() {
    if (this->size() < 1) {
        return 0;
    }
    
    CString cparam;    
    ULONG size = this->size();
    ULONG count = 0;
    for (ULONG i = 0; i < size; i++) {
        cparam = this->getAt(i);
        if (cparam.startsWithOneOfChars(PARAM_NAME_STARTING_CHARS)) {
            count++;
        }
    }
    
    return count;
}

ULONG CCommandLine::getItemsCount() {
    return this->size();
}
