/***************************************************************************
                          SIMPLY POWERFUL TOOLKIT (SPTK)
                          CXmlNode.cpp  -  description
                             -------------------
    begin                : Wed June 21 2006
    based on the code    : Mikko Lahteenmaki <Laza@Flashmail.com>
    copyright            : (C) 2003-2006 by Alexey S.Parshin
    email                : alexeyp@gmail.com
 ***************************************************************************/

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

   This 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 Library
   General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; if not, write to the Free Software Foundation,
   Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

   Please report all bugs and problems to "alexeyp@gmail.com"
 ***************************************************************************/

#include <sptk3/cxml>

using namespace sptk;

const CXmlAttributeMap CXmlAttributes::emptyMap;

CXmlAttribute::operator bool() const {
   if (empty()) return false;
   char ch = c_str()[0];
   char *p = strchr("TtYy1",ch);
   return p != 0;
}

CXmlAttribute& CXmlAttribute::operator = (bool v) {
   if (v)
      assign("Y");
   else
      assign("N");
   return *this;
}

CXmlAttribute& CXmlAttribute::operator = (int v) {
   char buff[64];
   sprintf(buff,"%i",v);
   assign(buff);
   return *this;
}

CXmlAttribute& CXmlAttribute::operator = (unsigned v)  {
   char buff[64];
   sprintf(buff,"%u",v);
   assign(buff);
   return *this;
}

CXmlAttribute& CXmlAttribute::operator = (long v) {
   char buff[64];
   sprintf(buff,"%li",v);
   assign(buff);
   return *this;
}

CXmlAttribute& CXmlAttribute::operator = (unsigned long v)  {
   char buff[64];
   sprintf(buff,"%lu",v);
   assign(buff);
   return *this;
}

CXmlAttribute& CXmlAttribute::operator = (double v) {
   char buff[64];
   sprintf(buff,"%f",v);
   assign(buff);
   return *this;
}
//-----------------------------------------------------------------------------
CXmlAttributes::CXmlAttributes(CXmlNode* parentNode) 
: m_document(parentNode->document()) {
   m_map = 0;
}

CXmlAttribute& CXmlAttributes::operator[] (const char* attrName) {
   if (!m_map) m_map = new CXmlAttributeMap;
   iterator it = m_map->find(attrName);
   if (it == m_map->end()) 
      attrName = m_document->shareString(attrName).c_str();
   return (*m_map)[attrName];
}

CXmlAttributes& CXmlAttributes::operator = (const CXmlAttributes& s) {
   if (s.m_map) {
      if (!m_map) m_map = new CXmlAttributeMap;
      CXmlAttributes::const_iterator it = s.begin();
      for(; it != s.end(); it++) {
         (*this)[it->first] = it->second;
      }
   } else {
      if (!m_map) {
         delete m_map;
         m_map = 0;
      }
   }
   return *this;
}

CXmlAttribute CXmlAttributes::getAttribute(std::string attr,const char *defaultValue) const {
   if (!m_map) return "";
   const_iterator itor = m_map->find(attr.c_str());
   if (itor != end()) return itor->second;
   CXmlAttribute rc;
   if (defaultValue) rc = defaultValue;
   return rc;
}

void CXmlAttributes::setAttribute(std::string attr,CXmlAttribute value,const char *defaultValue) {
   if (!m_map) m_map = new CXmlAttributeMap;
   iterator itor = m_map->find(attr.c_str());
   if (defaultValue && value == defaultValue) {
      if (itor != end())
         m_map->erase(itor);
      return;
   }
   if (itor != end())
      itor->second = value;
   else
      (*this)[attr] = value;
}

bool CXmlAttributes::hasAttribute(std::string attr) const { 
   if (m_map)
      return m_map->find(attr.c_str()) != m_map->end(); 
   return false;
}

size_t CXmlAttributes::size() const { 
   if (m_map)
      return m_map->size();
   return 0;
}

void CXmlAttributes::clear() { 
   if (m_map) {
      delete m_map;
      m_map = 0;
   }
}

CXmlAttributes::iterator CXmlAttributes::begin() { 
   if (!m_map) m_map = new CXmlAttributeMap;
   return m_map->begin(); 
}

CXmlAttributes::const_iterator CXmlAttributes::begin() const { 
   if (!m_map) return emptyMap.begin();
   return m_map->begin(); 
}

CXmlAttributes::iterator CXmlAttributes::end() { 
   if (!m_map) m_map = new CXmlAttributeMap;
   return m_map->end(); 
}

CXmlAttributes::const_iterator CXmlAttributes::end() const { 	
   if (!m_map) return emptyMap.end();
   return m_map->end(); 
}


