/***************************************************************************
 *   Copyright (C) 2006 by Luis Quintela   *
 *   lois_qu@web.de   *
 *                                                                         *
 *   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 2 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, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "skxmlloader.h"

SkXMLLoader::SkXMLLoader(SkCommands * commList,QString * clistNames)
 : QXmlDefaultHandler(),
reg_exp_buffer(),
commandsList(commList),		//commandsList and commListNames are coming from outside
commListNames(clistNames),	//we don't need to delete them
current_comm(0),
current_comm_name(),
current_opt(0),
current_opt_name(),
friends_count(0),
current_widget_opt(FALSE)

{}

SkXMLLoader::~SkXMLLoader()
{
}

 

bool SkXMLLoader::startElement( const QString & , 
								const QString & , 
								const QString & qName, 
								const QXmlAttributes & atts )
{
	if(qName=="Option")
	{
		
			if(atts.value("is_widget").toShort())
			{	
				current_widget_opt=TRUE;
				if(current_comm->opts_map==0)		
					current_comm->opts_map=new SkOptions();
				
				current_opt=new SkOption();
				current_opt_name=atts.value("op_name");
				short prf = atts.value("prefix").toShort();
				while(prf--)
					current_opt->prefix+= "-";
				
				current_opt->argument=atts.value("argument").toShort()?TRUE:FALSE;
		
				setOptRegExp();
				prf=atts.value("prefix").toShort();
				if(prf==0)
				{
					current_comm->no_prefix_opts+=current_opt_name+"|";
					current_comm->long_opts_names+=current_opt_name;
				}
				else
					if(prf==1)
						current_comm->opts_names+=current_opt_name;
					else
						current_comm->long_opts_names+=current_opt->prefix+current_opt_name;
				int i=atts.index("comment");
				if(i>-1 )
					current_opt->comment.append(format(atts.value(i)));
				i=atts.index("widget_comment");
				if(i>-1 )
					current_opt->widgetComment.append(format(atts.value(i)));
			}
		
	}else
		if(qName=="FriendOption")
		{
			if(!current_widget_opt)return TRUE;
			if(current_opt->friends==0)			
				current_opt->friends=new FriendOptions();
				
			
			
			current_opt->friends->insert(atts.value("friend"),(OptRelation)atts.value("relation").toShort());
			friends_count++;
				if(current_comm->opts_map->contains(atts.value("friend")))
				{					
					friends_count-=2;//each friend makes friends_count++
				}					//hier 2 friends are matched, than friends_count-2
			
			
		}else
			if(qName=="Command")
			{
				current_comm=new SkCommand();
				current_comm_name=atts.value("name");
				commListNames->append(current_comm_name+"|");
				current_comm->bound_simple_ops= atts.value("posible_boundary_of_simple_ops").toShort()?TRUE:FALSE;
				
				current_comm->reg_exp= atts.value("reg_exp");

				int i=atts.index("comment");
				if(i>-1 )
					current_comm->comment.append(format(atts.value(i)));
				
				
			}else
				if(qName=="CommandList")
					*commListNames="\\b(";
				else	return FALSE;
	return TRUE;
}

bool SkXMLLoader::endElement( 	const QString & , 
								const QString & , 
								const QString & qName )
{
	if(qName=="FriendOption");
	else
	if(qName=="Option")
	{
		if(current_widget_opt)
		{
			current_comm->opts_map->insert(current_opt_name,*current_opt);
			if(friends_count==0)
				current_opt->friends_completed=TRUE;
			else 
				friends_count=0;
			current_opt=0;
			current_opt_name=QString::null;
			current_widget_opt=FALSE;
		}
		
	}else
		
			if(qName=="Command")
			{
				
				current_comm->no_prefix_opts.remove(current_comm->no_prefix_opts.length()-1,1);
				current_comm->no_prefix_opts+=")\\b";
				
				commandsList->insert(current_comm_name,*current_comm);				
				current_comm=0;
				current_comm_name=QString::null;
				
			}else
				if(qName=="CommandList")
				{
					*commListNames=commListNames->remove(commListNames->length()-1,1);
					commListNames->append(")\\b");
				}
				else	return FALSE;
	return TRUE;
}



bool SkXMLLoader::fatalError( const QXmlParseException & exception )
{
	qWarning("line %d, coll %d: %s",exception.lineNumber(),exception.columnNumber(),exception.message().ascii());
	return FALSE;
}

//BEGIN OF PRIVATE MENBERS //////////////////////////////////////

void SkXMLLoader::setOptRegExp(  )//maybe not needed
{
// this regexp matches "* --b*" or "* --*b*"
// ([\w]|[\W])*\s+\x002D{2,2}\w*b


	QString pls=QString::number(current_opt->prefix.length());
	QString rx=QString::null;
	rx.append("([\w]|[\W])*\\s+\\x002D{");
	rx.append(pls);
	rx.append(",");
	rx.append(pls);
	rx.append("}\\w*");
	rx.append(current_opt_name);
	

	current_opt->rexp.setPattern(rx);
	current_opt->rexp.setCaseSensitive(TRUE);
	//current_opt->rexp.setMinimal(TRUE);
}

QString SkXMLLoader::format( QString txt )
{
	uint i=0,n=0;
	while(i<txt.length())
	{
		if(txt.at(i).isSpace())
		{
			n=(++n)%LINE_LENGTH;
			if(n==0)
				txt.insert(i,"\n");
		}
		++i;
	}
	return txt;
}



//END OF PRIVATE MENBERS //////////////////////////////////////

