/*
 * ************************************************************************************************************
 * 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/>.
 * ************************************************************************************************************
 */

#ifndef __MZSTD_STD_OBJECT_H__
#define __MZSTD_STD_OBJECT_H__

#include "mzstdCommon.h"
#include "mzObject.h"
#include "mzString.h"
#include "mzArrayList.h"

class CStdObject;

#define STDOBJ_DEFAULT_INDENT			L"    "
#define STDOBJ_PROPERTY_NONE			0
#define STDOBJ_PROPERTY_VALUE			1
#define STDOBJ_PROPERTY_VALUE_INT		2
#define STDOBJ_PROPERTY_VALUE_DOUBLE	3
#define STDOBJ_PROPERTY_ARRAY			4
#define STDOBJ_PROPERTY_OBJECT			5

class DECLSPEC_MZSTD CStdObjectProperty : public CObject {
public:

    // dostępne typy:
    //   'scalar' - pole value przechowuje wartość (typu CString) dla tej właściwości
    //   'scalar_int' - pole value przechowuje wartość (typu LONG) dla tej właściwości
    //   'scalar_double' - pole value przechowuje wartość (typu double) dla tej właściwości
    //   'array'  - pole aValue zawiera tablicę obiektów CStdObjectProperty
    //   'object' - pole oValue zawiera wskaźnik na obiekt CStdObject
    LONG type;
    CString name;
    CString value;
	LONG iValue;
	double fValue;
    CArrayList *aValue;
    CStdObject *oValue;
	CStdObject *extraData;

    WINAPI CStdObjectProperty(CString name, CString value);
    WINAPI CStdObjectProperty(CString name, LONG value);
    WINAPI CStdObjectProperty(CString name, double value);
    WINAPI CStdObjectProperty(CString name, CArrayList *value_array);
    WINAPI CStdObjectProperty(CString name, CStdObject *value_object);
    WINAPI CStdObjectProperty(CStdObjectProperty& copyObj);
    WINAPI ~CStdObjectProperty();

    VOID WINAPI clearValue();
    BOOL WINAPI hasOnlyScalars();
    CStdObjectProperty* WINAPI clone();
    CString WINAPI getAsString();

protected:
    VOID WINAPI _commonInit();

private:
    WINAPI CStdObjectProperty() {};
    BOOL WINAPI _arrayHasOnlyScalars();
    BOOL WINAPI _objectHasOnlyScalars();
};
typedef CStdObjectProperty *PStdObjectProperty;




class DECLSPEC_MZSTD CStdObject : public CObject {
public:
    WINAPI CStdObject();
    WINAPI CStdObject(CStdObject& copyObj);
    virtual WINAPI ~CStdObject();

    VOID WINAPI set(WCHAR* name, CString value);
    inline VOID WINAPI set(CString name, CString value) { return this->set(name.toWCHAR(), value); }
    VOID WINAPI set(WCHAR* name, LONG value);
    inline VOID WINAPI set(CString name, LONG value) { return this->set(name.toWCHAR(), value); }
    VOID WINAPI set(WCHAR* name, double value);
    inline VOID WINAPI set(CString name, double value) { return this->set(name.toWCHAR(), value); }
    VOID WINAPI set(WCHAR* name, CArrayList *aValue);
    inline VOID WINAPI set(CString name, CArrayList* aValue) { return this->set(name.toWCHAR(), aValue); }
    VOID WINAPI set(WCHAR* name, CStdObject *oValue);
    inline VOID WINAPI set(CString name, CStdObject* oValue) { return this->set(name.toWCHAR(), oValue); }
    CStdObjectProperty* WINAPI get(WCHAR *name);
    inline CStdObjectProperty* WINAPI get(CString name) { return this->get(name.toWCHAR()); }
    CString WINAPI getAsString(WCHAR *name);
    inline CString WINAPI getAsString(CString name) { return this->getAsString(name.toWCHAR()); }
    LONG WINAPI getAsInt(WCHAR *name);
    inline LONG WINAPI getAsInt(CString name) { return this->getAsInt(name.toWCHAR()); }
    double WINAPI getAsDouble(WCHAR *name);
    inline double WINAPI getAsDouble(CString name) { return this->getAsDouble(name.toWCHAR()); }
    CArrayList* WINAPI getAsArray(WCHAR *name);
    inline CArrayList* WINAPI getAsArray(CString name) { return this->getAsArray(name.toWCHAR()); }
    CStdObject* WINAPI getAsObject(WCHAR *name);
    inline CStdObject* WINAPI getAsObject(CString name) { return this->getAsObject(name.toWCHAR()); }
    CString WINAPI toJson(CString quote = "\"");
    BOOL WINAPI loadFromFile(CString fname);
    inline ULONG WINAPI itemsCount() { return this->_properties->size(); }
    CStdObject* WINAPI clone();
    VOID WINAPI clean();
    
    // przeciążone operatory
    CStdObjectProperty* WINAPI operator[](WCHAR *name);

protected:
    VOID WINAPI _commonInit();

private:
    CArrayList *_properties;
    CString _quote;

    CString WINAPI _propertyToJson(CStdObjectProperty *p, CString indent);
    CString WINAPI _valueToJson(CStdObjectProperty *p, CString indent, BOOL withName = FALSE);
    CString WINAPI _arrayToJson(CStdObjectProperty *p, CString indent, BOOL withName = FALSE);
    CString WINAPI _objectToJson(CStdObjectProperty *p, CString indent, BOOL withName = FALSE);
};
typedef CStdObject* PStdObject;

#endif
