/***************************************************************************
 *   Copyright (C) 2005 by Thierry CHARLES   *
 *   thierry@les-charles.net   *
 *                                                                         *
 *   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.             *
 ***************************************************************************/
#ifndef _TSELECTION_H_
#define _TSELECTION_H_

#include "components/codeeditor/tpoint.h"
#include "components/codeeditor/tstyle.h"

#include <map>
#include <set>
#include <ostream>
#include "lib/commons.h"

class TSelectionListener;

/**
 * @short Une s�lection dans un �diteur de texte
 * @author Thierry CHARLES <thierry@les-charles.net>
 * @version 0.1
 */
class TSelection
{
    public :
        TSelection() : iStyleId(SELECTED_STYLE){}
        virtual ~TSelection(){}
        /** definit le debut de la selection. N'est pas necessairement inferieur a End */
        virtual void setBegin(TPoint pt);
        /** renvoie une copie du point de depart de la selection. N'est pas necessairement inferieur a End */
        virtual TPoint getBegin() const { return this->begin; }
        /** renvoie une reference constante point de depart de la selection. N'est pas necessairement inferieur a End */
        virtual const TPoint& getBegin() { return this->begin; }
        /** definit la fin de la selection. N'est pas necessairement superieur a begin */
        virtual void setEnd(TPoint pt);
        /** renvoie une copie de la fin de la selection. N'est pas necessairement superieur a begin */
        virtual TPoint getEnd() const { return this->end; }
        /** renvoie une reference constante la fin de la selection. N'est pas necessairement superieur a begin */
        virtual const TPoint& getEnd() { return this->end; }
        /** envoie un evenement demandant de ne plus afficher la selection courrante */
        virtual void fireClearSelection();
        /** envoie un evenement demandant de redessiner la selection courrante */
        virtual void fireSelectionChanged();
        /** ajoute un ecouteur � la selection courrante */
        virtual bool addSelectionListener(TSelectionListener * sl);
        /** enleve un ecouteur de la selection courrante */
        virtual bool removeSelectionListener(TSelectionListener * sl);
        /** renvoie true si la selection est valide (ses 2 extremites sont valides) */
        virtual bool isValid() const { return (this->begin.isValid() && this->end.isValid()); }
        /** reinitialise la selection et la rend invalide aux 2 extremites */
        virtual void clear();

        /** defini le style a utiliser pour dessiner la selection */
        virtual void setStyle(const int iStyleId) { this->iStyleId = iStyleId; }
        /** renvoie le style a utiliser pour dessiner la selection */
        virtual int getStyle() const { return this->iStyleId; }

    private :
        /** debut de la selection */
        TPoint begin;
        /** fin de la selection */
        TPoint end;

        /** style qui devrait etre utilise pour dessiner la selection */
        int iStyleId;

        typedef std::set<TSelectionListener *> TSelectionListenersList;
        /** liste des ecouteurs */
        TSelectionListenersList listeners;
};

typedef std::map<int,TSelection> TSelectionMap;

/**
 * @short Definition d'un ecouteur de modifications de selections
 * @author Thierry CHARLES <thierry@les-charles.net>
 * @version 0.1
 */
class TSelectionListener
{
    public :
        virtual ~TSelectionListener(){}
        virtual void selectionChanged(TSelection * sel) = 0;
        virtual void clearSelection(TSelection * sel) = 0;
};


std::ostream & operator << (std::ostream &out, const TSelection &sel);

#endif
