/***************************************************************************
 *   Copyright (C) 2012 by Santiago González                               *
 *                                                                         *
 ***( see copyright.txt file at root folder )*******************************/

#pragma once

#include <QPlainTextEdit>

#include "compbase.h"

class BaseDebugger; 
class LineNumberArea; 
class Highlighter; 
class OutPanelText; 
class QCompleter; 

class CodeEditor : public QPlainTextEdit, public CompBase
{
    Q_OBJECT

    public:
        CodeEditor( QWidget* parent, OutPanelText* outPane ); 
        ~CodeEditor(); 

        void dummySetter( QString ) {; }

        void setFile( QString filePath ); 
        QString getFile() { return m_file ;  }

        QString compName(); 
        void setCompName( QString n ); 

        bool saveAtClose() { return m_saveAtClose;  }
        void setSaveAtClose( bool s ) { m_saveAtClose = s;  }

        bool loadCompiler() { return m_loadCompiler;  }
        void setLoadCompiler( bool l ) { m_loadCompiler = l;  }

        bool loadBreakp() { return m_loadBreakp;  }
        void setLoadBreakp( bool l ) { m_loadBreakp = l;  }

        bool openFiles() { return m_openFiles;  }
        void setOpenFiles( bool o ) { m_openFiles = o;  }

        QString circuit(); 
        void setCircuit( QString c ); 

        QString breakpoints(); 
        void setBreakpoints( QString bp ); 

        QString fileList(); 
        void setFileList( QString fl ); 

        void setAutoClose( uint8_t ac ) { m_autoClose = ac;  }

        void addKeyWords( QStringList words ); 
        void setFunctions( QStringList words ); 
        void setMemberWords( QMap<QString, QStringList> mb ); 
        void setExtraTypes( QStringList types ); 

        void setSyntaxFile( QString file ); 
        void reloadSyntax(); 

        void loadConfig(); 
        void saveConfig(); 

        void closing() { if( m_saveAtClose ) saveConfig();  }

        int debugLine() { return m_debugLine;  }
        void setDebugLine( int line ) { m_debugLine = line;  }

        void addBreakPoint( int line ); 
        void addError( int e )   { if( !m_errors.contains( e )   ) m_errors.append( e );  }
        void addWarning( int w ) { if( !m_warnings.contains( w ) ) m_warnings.append( w ); }

        QList<int>* getBreakPoints() { return &m_brkPoints;  }
        QList<int>* getErrors()      { return &m_errors;  }
        QList<int>* getWarnings()    { return &m_warnings;  }

        void startDebug(); 
        void stopDebug(); 

        void lineNumberAreaPaintEvent( QPaintEvent* event ); 
        int  lineNumberAreaWidth(); 

        BaseDebugger* getCompiler() { return m_compiler;  }
        //void setCompiler( BaseDebugger* comp ); 

        void fileProps(); 

        QList<int> getFound(); 
        void setFound( QList<QTextEdit::ExtraSelection> sel ); 

        void showMsg( QString msg ); 

        void updateScreen(); 

        void toggleBreak() { m_brkAction = 3;  }

        bool compile( bool debug=false ); 

    public slots:
        void slotAddBreak() { m_brkAction = 1;  }
        void slotRemBreak() { m_brkAction = 2;  }
        void slotClearBreak() { m_brkPoints.clear();  }
        void insertCompletion( QString text ); 

    private slots:
        void updateLineNumberAreaWidth(int) { setViewportMargins( lineNumberAreaWidth(), 0, 0, 0 );  }
        void updateLineNumberArea( const QRect &, int ); 
        void highlightCurrentLine(); 
        void deleteSelected(); 

    protected:
        void resizeEvent( QResizeEvent* event ); 
        void keyPressEvent( QKeyEvent* event ); 
        void contextMenuEvent( QContextMenuEvent* event ); 

    private:
        int  getSyntaxCoincidences(); 
        void remBreakPoint( int line ); 
        void indentSelection( bool unIndent ); 
        void complete( QKeyEvent* e ); 
        QString wordUnderCursor(); 

        BaseDebugger* m_compiler; 
        OutPanelText* m_outPane; 

        LineNumberArea* m_lNumArea; 
        Highlighter*    m_hlighter; 

        //QString m_prevWord; 
        QString m_object; 
        QStringList m_objects; 
        QStringList m_keyWords; 
        QMap<QString, QStringList> m_memberWords; 
        QCompleter* m_completer; 

        QList<QTextEdit::ExtraSelection> m_found; 

        QString m_file; 
        QString m_help; 

        QList<int> m_brkPoints; 
        QList<int> m_errors; 
        QList<int> m_warnings; 

        int m_brkAction;     // 0 = no action, 1 = add brkpoint, 2 = rem brkpoint
        int m_debugLine; 
        int m_numLines; 

        uint8_t m_autoClose; 

        bool m_saveAtClose; 
        bool m_openFiles; 
        bool m_openCircuit; 
        bool m_loadCompiler; 
        bool m_loadBreakp; 

        QString m_tab; 
        QFont m_font; 

        QString m_syntaxFile; 

 static QStringList m_picInstr; 
 static QStringList m_avrInstr; 
 static QStringList m_i51Instr; 

 static QList<CodeEditor*> m_documents; 
}; 


// ********************* CLASS LineNumberArea **********************************

class LineNumberArea : public QWidget
{
    Q_OBJECT
    
    public:
        LineNumberArea( CodeEditor* editor ); 
        ~LineNumberArea(); 

        QSize sizeHint() const { return QSize( m_codeEditor->lineNumberAreaWidth(), 0 );  }

        int lastPos; 

    protected:
        void contextMenuEvent( QContextMenuEvent* event); 
        void mousePressEvent( QMouseEvent* event ); 
        void paintEvent( QPaintEvent* event ) { m_codeEditor->lineNumberAreaPaintEvent( event );  }

    private:
        CodeEditor* m_codeEditor; 
}; 

/*#include <QTextBlockUserData>
class UserData : public QTextBlockUserData
{
    public:
        UserData()
        {
            breakp = false; 
            error   = false; 
            warning = false; 
        }
        ~UserData(){; }

        bool breakp; 
        bool error; 
        bool warning; 

}; */
