void SyntaxHighlightDlg::OnItemSelected(wxCommandEvent& event)
{
    CHECK_PTR_RET(m_lexer);

    // update colour picker & font pickers
    wxString selectionString = event.GetString();
    StyleProperty::List_t& properties = m_lexer->GetLexerProperties();
    StyleProperty::List_t::iterator iter = properties.begin();
    for(; iter != properties.end(); iter++) {
        if(iter->GetName() == selectionString) {
            // update font & color
            StyleProperty p = (*iter);
            wxString colour = p.GetFgColour();
            wxString bgColour = p.GetBgColour();
            wxFont font = wxNullFont;

            int size = p.GetFontSize();
            wxString face = p.GetFaceName();
            bool bold = p.IsBold();

            font = wxFont(size,
                          wxFONTFAMILY_TELETYPE,
                          p.GetItalic() ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL,
                          bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL,
                          p.GetUnderlined(),
                          face);
            m_fontPicker->SetSelectedFont(font);
            m_bgColourPicker->SetColour(bgColour);
            m_colourPicker->SetColour(colour);
            m_eolFilled->SetValue(p.GetEolFilled());
        }
    }
}
ContextGeneric::ContextGeneric(LEditor *container, const wxString &name) 
: ContextBase(container)
{
	//-----------------------------------------------
	// Load laguage settings from configuration file
	//-----------------------------------------------
	SetName(name);

	// Set the key words and the lexer
	wxString keyWords;
	std::list<StyleProperty> styles;
	LexerConfPtr lexPtr;
	// Read the configuration file
	if(EditorConfigST::Get()->IsOk()){
		lexPtr = EditorConfigST::Get()->GetLexer(name);
	}

	// Update the control
	LEditor &rCtrl = GetCtrl();
	rCtrl.SetLexer(lexPtr->GetLexerId());
	rCtrl.SetKeyWords(0, lexPtr->GetKeyWords());
	rCtrl.StyleClearAll();
	
	styles = lexPtr->GetProperties();
	std::list<StyleProperty>::iterator iter = styles.begin();
	for(; iter != styles.end(); iter++)
	{
		StyleProperty st = (*iter);
		int size = st.GetFontSize();
		wxString face = st.GetFaceName();
		bool bold = st.IsBold();
		
		wxFont font(size, wxFONTFAMILY_TELETYPE, wxNORMAL, bold ? wxBOLD : wxNORMAL, false, face);

		if(st.GetId() == 0){ //default
			rCtrl.StyleSetFont(wxSCI_STYLE_DEFAULT, font);
			rCtrl.StyleSetSize(wxSCI_STYLE_DEFAULT, (*iter).GetFontSize());
			rCtrl.StyleSetForeground(wxSCI_STYLE_DEFAULT, (*iter).GetFgColour());
		}

		rCtrl.StyleSetFont(st.GetId(), font);
		rCtrl.StyleSetSize(st.GetId(), (*iter).GetFontSize());
		rCtrl.StyleSetForeground(st.GetId(), (*iter).GetFgColour());
	}
}
void SyntaxHighlightDlg::CreateLexerPage()
{
    CHECK_PTR_RET(m_lexer);

    const StyleProperty::List_t& m_propertyList = m_lexer->GetLexerProperties();
    std::list<StyleProperty>::const_iterator it = m_propertyList.begin();
    StyleProperty selTextProperties;

    for(; it != m_propertyList.end(); it++) {
        if(it->GetId() != SEL_TEXT_ATTR_ID) {
            m_properties->Append((*it).GetName());
        } else {
            selTextProperties = *it;
        }
    }

    if(m_properties->GetCount()) m_properties->SetSelection(0);

    wxString initialColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT).GetAsString();
    wxString bgInitialColor = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW).GetAsString();
    wxFont initialFont = wxNullFont;
    // bool     initialEolFilled (false);
    bool initialStyleWithinPreProcessor(true);

    if(m_propertyList.empty() == false) {
        StyleProperty p;
        p = (*m_propertyList.begin());
        initialColor = p.GetFgColour();
        bgInitialColor = p.GetBgColour();

        int size = p.GetFontSize();
        wxString face = p.GetFaceName();
        bool bold = p.IsBold();
        initialFont = wxFont(size,
                             wxFONTFAMILY_TELETYPE,
                             wxFONTSTYLE_NORMAL,
                             bold ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL,
                             false,
                             face);
    }
    initialStyleWithinPreProcessor = m_lexer->GetStyleWithinPreProcessor();

    m_fontPicker->SetSelectedFont(initialFont);
    m_colourPicker->SetColour(wxColour(initialColor));
    m_bgColourPicker->SetColour(wxColour(bgInitialColor));
    m_globalFontPicker->SetSelectedFont(initialFont);
    m_globalBgColourPicker->SetColour(wxColour(bgInitialColor));
    m_fileSpec->ChangeValue(m_lexer->GetFileSpec());
    m_styleWithinPreProcessor->SetValue(initialStyleWithinPreProcessor);

    // Update selected text properties
    m_colourPickerSelTextBgColour->SetColour(selTextProperties.GetBgColour());
    m_colourPickerSelTextFgColour->SetColour(selTextProperties.GetFgColour());
    m_checkBoxCustomSelectionFgColour->SetValue(m_lexer->IsUseCustomTextSelectionFgColour());

    if(m_propertyList.empty()) {
        m_fontPicker->Enable(false);
        m_colourPicker->Enable(false);
    }

    // Fill the themes for this lexer
    m_choiceLexerThemes->Clear();
    wxArrayString themes = ColoursAndFontsManager::Get().GetAvailableThemesForLexer(m_lexer->GetName());
    int sel = themes.Index(m_lexer->GetThemeName());
    if(sel == -1) {
        sel = 0;
    }
    m_choiceLexerThemes->Append(themes);
    if(!m_choiceLexerThemes->IsEmpty()) {
        m_choiceLexerThemes->SetSelection(sel);
    }
}
void LexerConf::Apply(wxStyledTextCtrl* ctrl, bool applyKeywords)
{
    ctrl->SetLexer(GetLexerId());
    ctrl->StyleClearAll();
    ctrl->SetStyleBits(ctrl->GetStyleBitsNeeded());

    OptionsConfigPtr options = EditorConfigST::Get()->GetOptions();
    bool tooltip(false);

    const StyleProperty::Map_t& styles = GetLexerProperties();
    ctrl->SetProperty(wxT("styling.within.preprocessor"), this->GetStyleWithinPreProcessor() ? wxT("1") : wxT("0"));

    // turn off PP tracking/updating by default
    ctrl->SetProperty(wxT("lexer.cpp.track.preprocessor"), wxT("0"));
    ctrl->SetProperty(wxT("lexer.cpp.update.preprocessor"), wxT("0"));
    
    if(GetName() == "scss") {
        // Enable SCSS property (will tell the lexer to search for variables)
        ctrl->SetProperty("lexer.css.scss.language", "1");
    }
    ctrl->SetUseAntiAliasing(true);

    // Find the default style
    wxFont defaultFont;
    bool foundDefaultStyle = false;
    int nDefaultFontSize = DEFAULT_FONT_SIZE;
    
    StyleProperty defaultStyle;
    StyleProperty::Map_t::const_iterator iter = styles.begin();
    for(; iter != styles.end(); ++iter) {
        const StyleProperty& prop = iter->second;
        if(prop.GetId() == 0) {
            defaultStyle = prop;
            wxString fontFace = prop.GetFaceName().IsEmpty() ? DEFAULT_FACE_NAME : prop.GetFaceName();
            if(!prop.GetFaceName().IsEmpty()) {
                nDefaultFontSize = prop.GetFontSize();
            }
            defaultFont = wxFont(nDefaultFontSize,
                                 wxFONTFAMILY_TELETYPE,
                                 prop.GetItalic() ? wxFONTSTYLE_ITALIC : wxFONTSTYLE_NORMAL,
                                 prop.IsBold() ? wxFONTWEIGHT_BOLD : wxFONTWEIGHT_NORMAL,
                                 prop.GetUnderlined(),
                                 fontFace);
            foundDefaultStyle = true;
            break;
        }
    }

    // Reset all colours to use the default style colour
    if(foundDefaultStyle) {
        for(int i = 0; i < 256; i++) {
            ctrl->StyleSetBackground(i, defaultStyle.GetBgColour());
            ctrl->StyleSetForeground(i, defaultStyle.GetFgColour());
        }
    }

    if(foundDefaultStyle && defaultFont.IsOk()) {
        for(int i = 0; i < 256; i++) {
            ctrl->StyleSetFont(i, defaultFont);
        }
    }

    iter = styles.begin();
    for(; iter != styles.end(); ++iter) {

        StyleProperty sp = iter->second;
        int size = nDefaultFontSize;
        wxString face = sp.GetFaceName();
        bool bold = sp.IsBold();
        bool italic = sp.GetItalic();
        bool underline = sp.GetUnderlined();
        // int           alpha     = sp.GetAlpha();
        // handle special cases
        switch(sp.GetId()) {
        case WHITE_SPACE_ATTR_ID: {
            // whitespace colour. We dont allow changing the background colour, only the foreground colour
            wxColour whitespaceColour = sp.GetFgColour();
            if(whitespaceColour.IsOk()) {
                ctrl->SetWhitespaceForeground(true, whitespaceColour);
            }
            break;
        }
        case FOLD_MARGIN_ATTR_ID:
            // fold margin foreground colour
            ctrl->SetFoldMarginColour(true, sp.GetBgColour());
            ctrl->SetFoldMarginHiColour(true, sp.GetFgColour());
            break;
        case SEL_TEXT_ATTR_ID: {
            // selection colour
            if(wxColour(sp.GetBgColour()).IsOk()) {
                ctrl->SetSelBackground(true, sp.GetBgColour());
            }
            if(IsUseCustomTextSelectionFgColour() && wxColour(sp.GetFgColour()).IsOk()) {
                ctrl->SetSelForeground(true, sp.GetFgColour());
            } else {
                // provide a "dummy" selection colour (we pass 'false' so it does not matter
                // which colour we use here)
                ctrl->SetSelForeground(false, wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
            }
            break;
        }
        case CARET_ATTR_ID: {
            // caret colour
            wxColour caretColour = sp.GetFgColour();
            if(!caretColour.IsOk()) {
                caretColour = *wxBLACK;
            }
            ctrl->SetCaretForeground(caretColour);
            break;
        }
        default: {

            wxString faceName = face;
            int fontSize(size);
            if(face.IsEmpty()) {
                // defaults
                fontSize = nDefaultFontSize;
                faceName = DEFAULT_FACE_NAME;
            }

            wxFontInfo fontInfo = wxFontInfo(fontSize)
                                      .Family(wxFONTFAMILY_TELETYPE)
                                      .Italic(italic)
                                      .Bold(bold)
                                      .Underlined(underline)
                                      .FaceName(faceName.IsEmpty() ? DEFAULT_FACE_NAME : faceName);
            wxFont font(fontInfo);

            if(sp.GetId() == 0) { // default
                ctrl->StyleSetFont(wxSTC_STYLE_DEFAULT, font);
                ctrl->StyleSetSize(wxSTC_STYLE_DEFAULT, size);
                ctrl->StyleSetForeground(wxSTC_STYLE_DEFAULT, iter->second.GetFgColour());

                // Set the inactive state colours
                // Inactive state is greater by 64 from its counterpart
                wxColor inactiveColor = GetInactiveColor(defaultStyle);
                ctrl->StyleSetForeground(wxSTC_STYLE_DEFAULT + 64, inactiveColor);
                ctrl->StyleSetFont(wxSTC_STYLE_DEFAULT + 64, font);
                ctrl->StyleSetSize(wxSTC_STYLE_DEFAULT + 64, size);
                ctrl->StyleSetBackground(wxSTC_STYLE_DEFAULT + 64, iter->second.GetBgColour());

                ctrl->StyleSetBackground(wxSTC_STYLE_DEFAULT, iter->second.GetBgColour());
                ctrl->StyleSetSize(wxSTC_STYLE_LINENUMBER, size);

            } else if(sp.GetId() == wxSTC_STYLE_CALLTIP) {
                tooltip = true;
                if(sp.GetFaceName().IsEmpty()) {
                    font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
                    fontSize = font.GetPointSize();
                }
            }

            ctrl->StyleSetFont(sp.GetId(), font);
            ctrl->StyleSetSize(sp.GetId(), fontSize);
            ctrl->StyleSetEOLFilled(sp.GetId(), iter->second.GetEolFilled());

            if(iter->second.GetId() == LINE_NUMBERS_ATTR_ID) {
                // Set the line number colours only if requested
                // otherwise, use default colours provided by scintilla
                if(sp.GetBgColour().IsEmpty() == false) ctrl->StyleSetBackground(sp.GetId(), sp.GetBgColour());

                if(sp.GetFgColour().IsEmpty() == false)
                    ctrl->StyleSetForeground(sp.GetId(), sp.GetFgColour());
                else
                    ctrl->StyleSetForeground(sp.GetId(), wxT("BLACK"));

            } else {
                ctrl->StyleSetForeground(sp.GetId(), sp.GetFgColour());

                // Inactive state is greater by 64 from its counterpart
                wxColor inactiveColor = GetInactiveColor(sp);
                ctrl->StyleSetForeground(sp.GetId() + 64, inactiveColor);
                ctrl->StyleSetFont(sp.GetId() + 64, font);
                ctrl->StyleSetSize(sp.GetId() + 64, size);
                ctrl->StyleSetBackground(sp.GetId() + 64, defaultStyle.GetBgColour());

                ctrl->StyleSetBackground(sp.GetId(), sp.GetBgColour());
            }
            break;
        }
        } // switch
    }

    // set the calltip font
    if(!tooltip) {
        wxFont font = wxSystemSettings::GetFont(wxSYS_DEFAULT_GUI_FONT);
        ctrl->StyleSetFont(wxSTC_STYLE_CALLTIP, font);
    }

    if(applyKeywords) {
        ctrl->SetKeyWords(0, GetKeyWords(0));
        ctrl->SetKeyWords(1, GetKeyWords(1));
        ctrl->SetKeyWords(2, GetKeyWords(2));
        ctrl->SetKeyWords(3, GetKeyWords(3));
        ctrl->SetKeyWords(4, GetKeyWords(4));
    }

    // by default indicators are set to be opaque rounded box
    if(DrawingUtils::IsDark(defaultStyle.GetBgColour())) {
        ctrl->IndicatorSetStyle(1, wxSTC_INDIC_BOX);
        ctrl->IndicatorSetStyle(2, wxSTC_INDIC_BOX);
    } else {
        ctrl->IndicatorSetStyle(1, wxSTC_INDIC_ROUNDBOX);
        ctrl->IndicatorSetStyle(2, wxSTC_INDIC_ROUNDBOX);
    }

    // Annotations markers
    // Warning style
    wxColour textColour = IsDark() ? *wxWHITE : *wxBLACK;
    ctrl->StyleSetBackground(ANNOTATION_STYLE_WARNING, defaultStyle.GetBgColour());
    ctrl->StyleSetForeground(ANNOTATION_STYLE_WARNING, textColour);
    ctrl->StyleSetSizeFractional(ANNOTATION_STYLE_WARNING, (ctrl->StyleGetSizeFractional(wxSTC_STYLE_DEFAULT) * 4) / 5);

    // Error style
    ctrl->StyleSetBackground(ANNOTATION_STYLE_ERROR, defaultStyle.GetBgColour());
    ctrl->StyleSetForeground(ANNOTATION_STYLE_ERROR, textColour);
    ctrl->StyleSetSizeFractional(ANNOTATION_STYLE_ERROR, (ctrl->StyleGetSizeFractional(wxSTC_STYLE_DEFAULT) * 4) / 5);

    // Code completion errors
    ctrl->StyleSetBackground(ANNOTATION_STYLE_CC_ERROR, defaultStyle.GetBgColour());
    ctrl->StyleSetForeground(ANNOTATION_STYLE_CC_ERROR, textColour);
    ctrl->StyleSetSizeFractional(ANNOTATION_STYLE_CC_ERROR,
                                 (ctrl->StyleGetSizeFractional(wxSTC_STYLE_DEFAULT) * 4) / 5);

    // annotation style 'boxed'
    ctrl->AnnotationSetVisible(wxSTC_ANNOTATION_BOXED);

    // Define the styles for the editing margin
    ctrl->StyleSetBackground(CL_LINE_SAVED_STYLE, wxColour(wxT("FOREST GREEN")));
    ctrl->StyleSetBackground(CL_LINE_MODIFIED_STYLE, wxColour(wxT("ORANGE")));
    
    // Indentation
    ctrl->SetUseTabs(options->GetIndentUsesTabs());
    ctrl->SetTabWidth(options->GetIndentWidth());
    ctrl->SetIndent(options->GetIndentWidth());
}
wxXmlNode* LexerConf::ToXml() const
{
    // convert the lexer back xml node
    wxXmlNode* node = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Lexer"));
    // set the lexer name
    node->AddProperty(wxT("Name"), GetName());
    node->AddProperty("Theme", GetThemeName());
    node->AddProperty("IsActive", IsActive() ? "Yes" : "No");
    node->AddAttribute("UseCustomTextSelFgColour", IsUseCustomTextSelectionFgColour() ? "Yes" : "No");
    node->AddProperty(wxT("StylingWithinPreProcessor"), BoolToString(GetStyleWithinPreProcessor()));
    wxString strId;
    strId << GetLexerId();
    node->AddProperty(wxT("Id"), strId);

    // set the keywords node
    wxXmlNode* keyWords0 = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("KeyWords0"));
    XmlUtils::SetNodeContent(keyWords0, GetKeyWords(0));
    node->AddChild(keyWords0);

    wxXmlNode* keyWords1 = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("KeyWords1"));
    XmlUtils::SetNodeContent(keyWords1, GetKeyWords(1));
    node->AddChild(keyWords1);

    wxXmlNode* keyWords2 = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("KeyWords2"));
    XmlUtils::SetNodeContent(keyWords2, GetKeyWords(2));
    node->AddChild(keyWords2);

    wxXmlNode* keyWords3 = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("KeyWords3"));
    XmlUtils::SetNodeContent(keyWords3, GetKeyWords(3));
    node->AddChild(keyWords3);

    wxXmlNode* keyWords4 = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("KeyWords4"));
    XmlUtils::SetNodeContent(keyWords4, GetKeyWords(4));
    node->AddChild(keyWords4);

    // set the extensions node
    wxXmlNode* extesions = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Extensions"));
    XmlUtils::SetNodeContent(extesions, GetFileSpec());
    node->AddChild(extesions);

    // set the properties
    wxXmlNode* properties = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Properties"));
    std::map<long, StyleProperty>::const_iterator iter = m_properties.begin();
    for(; iter != m_properties.end(); ++iter) {
        StyleProperty p = iter->second;
        wxXmlNode* property = new wxXmlNode(NULL, wxXML_ELEMENT_NODE, wxT("Property"));

        strId.Clear();
        strId << p.GetId();
        property->AddProperty(wxT("Id"), strId);
        property->AddProperty(wxT("Name"), p.GetName());
        property->AddProperty(wxT("Bold"), BoolToString(p.IsBold()));
        property->AddProperty(wxT("Face"), p.GetFaceName());
        property->AddProperty(wxT("Colour"), p.GetFgColour());
        property->AddProperty(wxT("BgColour"), p.GetBgColour());
        property->AddProperty(wxT("Italic"), BoolToString(p.GetItalic()));
        property->AddProperty(wxT("Underline"), BoolToString(p.GetUnderlined()));
        property->AddProperty(wxT("EolFilled"), BoolToString(p.GetEolFilled()));

        strId.Clear();
        strId << p.GetAlpha();
        property->AddProperty(wxT("Alpha"), strId);

        wxString strSize;
        strSize << p.GetFontSize();
        property->AddProperty(wxT("Size"), strSize);
        properties->AddChild(property);
    }
    node->AddChild(properties);
    return node;
}