package com.siyeh.ig.naming;

import com.intellij.openapi.util.InvalidDataException;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.RegExFormatter;
import com.siyeh.ig.RegExInputVerifier;
import org.jdom.Element;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import javax.swing.text.InternationalFormatter;
import java.awt.*;
import java.text.NumberFormat;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public abstract class ConventionInspection extends BaseInspection {
    /** @noinspection PublicField*/
    public String m_regex = getDefaultRegex();      // this is public for the DefaultJDomExternalizer
    /** @noinspection PublicField*/
    public int m_minLength = getDefaultMinLength();  // this is public for the DefaultJDomExternalizer
    /** @noinspection PublicField*/
    public int m_maxLength = getDefaultMaxLength();    // this is public for the DefaultJDomExternalizer
    protected Pattern m_regexPattern = Pattern.compile(m_regex);

    protected abstract String getDefaultRegex();

    protected abstract int getDefaultMinLength();

    protected abstract int getDefaultMaxLength();

    String getRegex() {
        return m_regex;
    }

    int getMinLength() {
        return m_minLength;
    }

    int getMaxLength() {
        return m_maxLength;
    }

    boolean isValid(String name) {
        final int length = name.length();
        if (length < m_minLength) {
            return false;
        }
        if (length > m_maxLength) {
            return false;
        }
        if ("serialVersionUID".equals(name)) {
            return true;
        }
        final Matcher matcher = m_regexPattern.matcher(name);
        return matcher.matches();
    }

    public void readSettings(Element element) throws InvalidDataException {
        super.readSettings(element);
        m_regexPattern = Pattern.compile(m_regex);
    }

    private static final int REGEX_COLUMN_COUNT = 25;

    public JComponent createOptionsPanel() {
        final GridBagLayout layout = new GridBagLayout();
        final JPanel panel = new JPanel(layout);

        final JLabel patternLabel = new JLabel("Pattern:");
        patternLabel.setHorizontalAlignment(SwingConstants.TRAILING);
        final JLabel minLengthLabel = new JLabel("Min Length:");
        minLengthLabel.setHorizontalAlignment(SwingConstants.TRAILING);
        final JLabel maxLengthLabel = new JLabel("Max Length:");
        maxLengthLabel.setHorizontalAlignment(SwingConstants.TRAILING);

        final NumberFormat numberFormat = NumberFormat.getIntegerInstance();
        numberFormat.setParseIntegerOnly(true);
        numberFormat.setMinimumIntegerDigits(1);
        numberFormat.setMaximumIntegerDigits(2);
        final InternationalFormatter formatter = new InternationalFormatter(numberFormat);
        formatter.setAllowsInvalid(false);
        formatter.setCommitsOnValidEdit(true);

        final JFormattedTextField minLengthField = new JFormattedTextField(formatter);
        final Font panelFont = panel.getFont();
        minLengthField.setFont(panelFont);
        minLengthField.setValue(m_minLength);
        minLengthField.setColumns(2);

        final JFormattedTextField maxLengthField = new JFormattedTextField(formatter);
        maxLengthField.setFont(panelFont);
        maxLengthField.setValue(m_maxLength);
        maxLengthField.setColumns(2);

        final JFormattedTextField regexField = new JFormattedTextField(new RegExFormatter());
        regexField.setFont(panelFont);
        regexField.setValue(m_regexPattern);
        regexField.setColumns(REGEX_COLUMN_COUNT);
        regexField.setInputVerifier(new RegExInputVerifier());
        regexField.setFocusLostBehavior(JFormattedTextField.COMMIT);

        final DocumentListener listener = new DocumentListener() {
            public void changedUpdate(DocumentEvent e) {
                textChanged();
            }

            public void insertUpdate(DocumentEvent e) {
                textChanged();
            }

            public void removeUpdate(DocumentEvent e) {
                textChanged();
            }

            private void textChanged() {
                m_regexPattern = (Pattern) regexField.getValue();
                m_regex = m_regexPattern.pattern();
                m_minLength = ((Number) minLengthField.getValue()).intValue();
                m_maxLength = ((Number) maxLengthField.getValue()).intValue();
            }
        };
        final Document regexDocument = regexField.getDocument();
        regexDocument.addDocumentListener(listener);
        final Document minLengthDocument = minLengthField.getDocument();
        minLengthDocument.addDocumentListener(listener);
        final Document maxLengthDocument = maxLengthField.getDocument();
        maxLengthDocument.addDocumentListener(listener);

        final GridBagConstraints constraints = new GridBagConstraints();
        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.weightx = 1.0;
        constraints.anchor = GridBagConstraints.EAST;
        constraints.fill = GridBagConstraints.HORIZONTAL;
        panel.add(patternLabel, constraints);

        constraints.gridx = 1;
        constraints.gridy = 0;
        constraints.gridwidth = 3;
        constraints.anchor = GridBagConstraints.WEST;
        panel.add(regexField, constraints);

        constraints.gridx = 0;
        constraints.gridy = 1;
        constraints.gridwidth = 1;
        constraints.anchor = GridBagConstraints.EAST;
        panel.add(minLengthLabel, constraints);

        constraints.gridx = 1;
        constraints.gridy = 1;
        constraints.anchor = GridBagConstraints.WEST;
        panel.add(minLengthField, constraints);

        constraints.gridx = 2;
        constraints.gridy = 1;
        constraints.anchor = GridBagConstraints.EAST;
        panel.add(maxLengthLabel, constraints);

        constraints.gridx = 3;
        constraints.gridy = 1;
        constraints.anchor = GridBagConstraints.WEST;
        panel.add(maxLengthField, constraints);

        return panel;
    }

}

@@ -186,24 +186,73 @@
 utVerifier;%0A
+import com.siyeh.ig.ui.FormattedTextFieldMacFix;%0A
 import org.j
@@ -3294,32 +3294,88 @@
 d.setColumns(2);
+%0A        FormattedTextFieldMacFix.apply(minLengthField);
 %0A%0A        final 
@@ -3573,16 +3573,72 @@
 umns(2);
+%0A        FormattedTextFieldMacFix.apply(maxLengthField);
 %0A%0A      
@@ -3992,16 +3992,67 @@
 OMMIT);%0A
+        FormattedTextFieldMacFix.apply(regexField);
 %0A       

Fix for IDEADEV-949