package io.mrarm.irc;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import com.google.android.material.textfield.TextInputLayout;
import androidx.core.view.GravityCompat;
import androidx.appcompat.widget.ListPopupWindow;
import androidx.appcompat.widget.PopupMenu;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.TextView;

import java.util.Calendar;
import java.util.Date;

import io.mrarm.chatlib.dto.MessageInfo;
import io.mrarm.chatlib.dto.MessageSenderInfo;
import io.mrarm.irc.util.StyledAttributesHelper;
import io.mrarm.irc.view.FormattableEditText;
import io.mrarm.irc.util.MessageBuilder;
import io.mrarm.irc.util.SimpleTextWatcher;
import io.mrarm.irc.view.TextFormatBar;

public class MessageFormatSettingsActivity extends ThemedActivity {

    private MessageBuilder mMessageBuilder;

    private EditText mDateFormat;
    private TextInputLayout mDateFormatCtr;
    private View mDateFormatPresetButton;
    private CheckBox mDateFixedWidth;
    private FormattableEditText mMessageFormatNormal;
    private TextView mMessageFormatNormalExample;
    private FormattableEditText mMessageFormatNormalMention;
    private TextView mMessageFormatNormalMentionExample;
    private FormattableEditText mMessageFormatAction;
    private TextView mMessageFormatActionExample;
    private FormattableEditText mMessageFormatActionMention;
    private TextView mMessageFormatActionMentionExample;
    private FormattableEditText mMessageFormatNotice;
    private TextView mMessageFormatNoticeExample;
    private FormattableEditText mMessageFormatEvent;
    private TextView mMessageFormatEventExample;
    private CheckBox mMessageFormatEventHostname;
    private TextFormatBar mTextFormatBar;

    private MessageSenderInfo mTestSender;
    private MessageInfo mSampleMessage;
    private MessageInfo mSampleActionMessage;
    private MessageInfo mSampleNoticeMessage;
    private MessageInfo mSampleEventMessage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_message_format_settings);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        mMessageBuilder = new MessageBuilder(this);

        mTextFormatBar = findViewById(R.id.format_bar);
        mTextFormatBar.setVisibility(View.GONE);
        mTextFormatBar.setOnChangeListener((TextFormatBar bar, EditText text) -> {
            ((SimpleTextWatcher.OnTextChangedListener) text.getTag()).afterTextChanged(text.getText());
        });
        mTextFormatBar.setExtraButton(R.drawable.ic_add_circle_outline,
                getString(R.string.message_format_add_chip), (View v) -> {
                    PopupMenu menu = new PopupMenu(v.getContext(), v, GravityCompat.END);
                    MenuInflater inflater = menu.getMenuInflater();
                    inflater.inflate(R.menu.menu_format_add_chip, menu.getMenu());
                    menu.setOnMenuItemClickListener((MenuItem item) -> {
                        int id = item.getItemId();
                        if (id == R.id.message_format_time)
                            insertChip(MessageBuilder.MetaChipSpan.TYPE_TIME);
                        else if (id == R.id.message_format_sender)
                            insertChip(MessageBuilder.MetaChipSpan.TYPE_SENDER);
                        else if (id == R.id.message_format_message)
                            insertChip(MessageBuilder.MetaChipSpan.TYPE_MESSAGE);
                        else if (id == R.id.message_format_wrap_anchor)
                            insertChip(MessageBuilder.MetaChipSpan.TYPE_WRAP_ANCHOR);
                        else if (id == R.id.message_format_sender_prefix)
                            insertChip(MessageBuilder.MetaChipSpan.TYPE_SENDER_PREFIX);
                        return false;
                    });
                    menu.show();
                });


        mDateFormat = findViewById(R.id.date_format);
        mDateFormatCtr = findViewById(R.id.date_format_ctr);
        mDateFormat.setText(mMessageBuilder.getMessageTimeFormat().toPattern());
        mDateFormat.addTextChangedListener(new SimpleTextWatcher((Editable s) -> {
            try {
                mMessageBuilder.setMessageTimeFormat(s.toString());
                mDateFormatCtr.setError(null);
                mDateFormatCtr.setErrorEnabled(false);
            } catch (Exception e) {
                mDateFormatCtr.setError(getString(R.string.message_format_date_invalid));
                return;
            }
            refreshExamples();
        }));
        mDateFormatPresetButton = findViewById(R.id.date_format_preset);
        mDateFormatPresetButton.setOnClickListener((View v) -> {
            PopupMenu menu = new PopupMenu(v.getContext(), mDateFormat, GravityCompat.START);
            String[] presets = getResources().getStringArray(R.array.time_format_presets);
            String[] presetsText = getResources().getStringArray(R.array.time_format_presets_desc);

            int secondaryColor = StyledAttributesHelper.getColor(this, android.R.attr.textColorSecondary, Color.BLACK);

            for (int i = 0; i < presets.length; i++) {
                SpannableString s = new SpannableString(presets[i] + " " + presetsText[i]);
                s.setSpan(new ForegroundColorSpan(secondaryColor), presets[i].length() + 1, s.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE);
                menu.getMenu().add(s).setTitleCondensed(presets[i]);
            }
            menu.setOnMenuItemClickListener((MenuItem item) -> {
                mDateFormat.setText(item.getTitleCondensed());
                return false;
            });
            menu.show();
        });

        mDateFixedWidth = findViewById(R.id.date_fixed_width);
        mDateFixedWidth.setChecked(mMessageBuilder.isMessageTimeFixedWidth());
        mDateFixedWidth.setOnCheckedChangeListener((CompoundButton btn, boolean checked) -> {
            mMessageBuilder.setMessageTimeFixedWidth(checked);
            refreshExamples();
        });

        mMessageFormatNormal = findViewById(R.id.message_format_normal);
        mMessageFormatNormalExample = findViewById(R.id.message_format_normal_example);
        mMessageFormatNormal.setText(mMessageBuilder.getMessageFormat());
        setupFormatEntry(mMessageFormatNormal, R.id.message_format_normal_preset, (Editable s) -> {
            mMessageBuilder.setMessageFormat(prepareFormat(s));
            refreshExamples();
        }, new CharSequence[] {
                buildPresetMessageFormat(this, 0, false, false),
                buildPresetMessageFormat(this, 0, false, true),
                buildPresetMessageFormat(this, 1, false, true)
        });

        mMessageFormatNormalMention = findViewById(R.id.message_format_normal_mention);
        mMessageFormatNormalMentionExample = findViewById(R.id.message_format_normal_mention_example);
        mMessageFormatNormalMention.setText(mMessageBuilder.getMentionMessageFormat());
        setupFormatEntry(mMessageFormatNormalMention, R.id.message_format_normal_mention_preset, (Editable s) -> {
            mMessageBuilder.setMentionMessageFormat(prepareFormat(s));
            refreshExamples();
        }, new CharSequence[] {
                buildPresetMessageFormat(this, 0, true, false),
                buildPresetMessageFormat(this, 0, true, true),
                buildPresetMessageFormat(this, 1, true, true)
        });

        mMessageFormatAction = findViewById(R.id.message_format_action);
        mMessageFormatActionExample = findViewById(R.id.message_format_action_example);
        mMessageFormatAction.setText(mMessageBuilder.getActionMessageFormat());
        setupFormatEntry(mMessageFormatAction, R.id.message_format_action_preset, (Editable s) -> {
            mMessageBuilder.setActionMessageFormat(prepareFormat(s));
            refreshExamples();
        }, new CharSequence[] {
                buildActionPresetMessageFormat(this, 0, false),
                buildActionPresetMessageFormat(this, 1, false)
        });

        mMessageFormatActionMention = findViewById(R.id.message_format_action_mention);
        mMessageFormatActionMentionExample = findViewById(R.id.message_format_action_mention_example);
        mMessageFormatActionMention.setText(mMessageBuilder.getActionMentionMessageFormat());
        setupFormatEntry(mMessageFormatActionMention, R.id.message_format_action_mention_preset, (Editable s) -> {
            mMessageBuilder.setActionMentionMessageFormat(prepareFormat(s));
            refreshExamples();
        }, new CharSequence[] {
                buildActionPresetMessageFormat(this, 0, true),
                buildActionPresetMessageFormat(this, 1, true)
        });

        mMessageFormatNotice = findViewById(R.id.message_format_notice);
        mMessageFormatNoticeExample = findViewById(R.id.message_format_notice_example);
        mMessageFormatNotice.setText(mMessageBuilder.getNoticeMessageFormat());
        setupFormatEntry(mMessageFormatNotice, R.id.message_format_notice_preset, (Editable s) -> {
            mMessageBuilder.setNoticeMessageFormat(prepareFormat(s));
            refreshExamples();
        }, new CharSequence[] {
                buildNoticePresetMessageFormat(this, 0),
                buildNoticePresetMessageFormat(this, 1)
        });

        mMessageFormatEvent = findViewById(R.id.message_format_event);
        mMessageFormatEventExample = findViewById(R.id.message_format_event_example);
        mMessageFormatEventHostname = findViewById(R.id.message_format_event_hostname);
        mMessageFormatEvent.setText(mMessageBuilder.getEventMessageFormat());
        mMessageFormatEventHostname.setChecked(mMessageBuilder.getEventMessageShowHostname());
        setupFormatEntry(mMessageFormatEvent, R.id.message_format_event_preset, (Editable s) -> {
            mMessageBuilder.setEventMessageFormat(prepareFormat(s));
            refreshExamples();
        }, new CharSequence[] {
                buildEventPresetMessageFormat(this, 0),
                buildEventPresetMessageFormat(this, 1)
        });
        mMessageFormatEventHostname.setOnCheckedChangeListener((CompoundButton b, boolean ch) -> {
            mMessageBuilder.setEventMessageShowHostname(ch);
            refreshExamples();
        });

        refreshExamples();
    }

    private void refreshExamples() {
        if (mTestSender == null) {
            mTestSender = new MessageSenderInfo(getString(R.string.message_example_sender), "user", "test/host", null, null);
            Date date = getSampleMessageTime();
            mSampleMessage = new MessageInfo(mTestSender, date, getString(R.string.message_example_message), MessageInfo.MessageType.NORMAL);
            mSampleActionMessage = new MessageInfo(mTestSender, date, getString(R.string.message_example_message), MessageInfo.MessageType.ME);
            mSampleNoticeMessage = new MessageInfo(mTestSender, date, getString(R.string.message_example_message), MessageInfo.MessageType.NOTICE);
            mSampleEventMessage = new MessageInfo(mTestSender, date, null, MessageInfo.MessageType.JOIN);
        }

        mMessageFormatNormalExample.setText(mMessageBuilder.buildMessage(mSampleMessage));
        mMessageFormatNormalMentionExample.setText(mMessageBuilder.buildMessageWithMention(mSampleMessage));
        mMessageFormatActionExample.setText(mMessageBuilder.buildMessage(mSampleActionMessage));
        mMessageFormatActionMentionExample.setText(mMessageBuilder.buildMessageWithMention(mSampleActionMessage));
        mMessageFormatNoticeExample.setText(mMessageBuilder.buildMessage(mSampleNoticeMessage));
        mMessageFormatEventExample.setText(mMessageBuilder.buildMessage(mSampleEventMessage));
    }

    public void save() {
        MessageBuilder global = MessageBuilder.getInstance(this);
        global.setMessageTimeFormat(mMessageBuilder.getMessageTimeFormat().toPattern());
        global.setMessageTimeFixedWidth(mMessageBuilder.isMessageTimeFixedWidth());
        global.setMessageFormat(mMessageBuilder.getMessageFormat());
        global.setMentionMessageFormat(mMessageBuilder.getMentionMessageFormat());
        global.setActionMessageFormat(mMessageBuilder.getActionMessageFormat());
        global.setActionMentionMessageFormat(mMessageBuilder.getActionMentionMessageFormat());
        global.setNoticeMessageFormat(mMessageBuilder.getNoticeMessageFormat());
        global.setEventMessageFormat(mMessageBuilder.getEventMessageFormat());
        global.setEventMessageShowHostname(mMessageBuilder.getEventMessageShowHostname());
        global.saveFormats();
    }

    private void setupFormatEntry(FormattableEditText editText, int presetButtonId, SimpleTextWatcher.OnTextChangedListener textListener, CharSequence[] presets) {
        editText.setFormatBar(mTextFormatBar);
        editText.setOnFocusChangeListener(mEditTextFocusListener);
        editText.addTextChangedListener(new SimpleTextWatcher(textListener));
        editText.setTag(textListener);

        findViewById(presetButtonId).setOnClickListener((View v) -> {
            selectPreset(editText, presets);
        });
    }

    private CharSequence prepareFormat(Spannable s) {
        SpannableString ret = new SpannableString(s.toString());
        for (Object span : s.getSpans(0, s.length(), CharacterStyle.class)) {
            if ((ret.getSpanFlags(span) & Spannable.SPAN_COMPOSING) != 0)
                continue;
            ret.setSpan(span, s.getSpanStart(span), s.getSpanEnd(span), s.getSpanFlags(span) & Spanned.SPAN_PRIORITY);
        }
        return ret;
    }

    private void selectPreset(EditText editText, CharSequence[] presets) {
        ListPopupWindow menu = new ListPopupWindow(editText.getContext());
        menu.setAnchorView(editText);
        menu.setAdapter(new ArrayAdapter<>(this,
                R.layout.activity_message_format_settings_preset, presets));
        menu.setOnItemClickListener((AdapterView<?> parent, View view, int position, long id) -> {
            editText.setText(presets[position]);
            menu.dismiss();
        });
        menu.show();
    }

    public static SpannableString buildPresetMessageFormat(Context context, int preset, boolean mention, boolean prefix) {
        if (preset == 0) {
            SpannableString spannable = new SpannableString("\0 |" + (prefix ? "\0" : "") + "\0: \0");
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_TIMESTAMP), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_SENDER), 3, prefix ? 6 : 5, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_TIME), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            if (prefix)
                spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_SENDER_PREFIX), 3, 4, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_SENDER), prefix ? 4 : 3, prefix ? 5 : 4, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_MESSAGE), prefix ? 7 : 6, prefix ? 8 : 7, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_WRAP_ANCHOR), 2, 3, MessageBuilder.FORMAT_SPAN_FLAGS);
            if (mention) {
                spannable.setSpan(new StyleSpan(Typeface.BOLD), prefix ? 4 : 3, prefix ? 5 : 4, MessageBuilder.FORMAT_SPAN_FLAGS);
                spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_SENDER), prefix ? 7 : 6, prefix ? 8 : 7, MessageBuilder.FORMAT_SPAN_FLAGS);
            }
            return spannable;
        }
        if (preset == 1) {
            SpannableString spannable = new SpannableString("\0 |<" + (prefix ? "\0" : "") + "\0> \0");
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_TIMESTAMP), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_TIMESTAMP), 3, 4, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_SENDER), 4, prefix ? 6 : 5, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_TIMESTAMP), prefix ? 6 : 5, prefix ? 7 : 6, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_TIME), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            if (prefix)
                spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_SENDER_PREFIX), 4, 5, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_SENDER), prefix ? 5 : 4, prefix ? 6 : 5, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_MESSAGE), prefix ? 8 : 7, prefix ? 9 : 8, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_WRAP_ANCHOR), 2, 3, MessageBuilder.FORMAT_SPAN_FLAGS);
            if (mention) {
                spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_SENDER), prefix ? 8 : 7, prefix ? 9 : 8, MessageBuilder.FORMAT_SPAN_FLAGS);
                spannable.setSpan(new StyleSpan(Typeface.BOLD), 4, prefix ? 6 : 5, MessageBuilder.FORMAT_SPAN_FLAGS);
            }
            return spannable;
        }
        return null;
    }

    public static SpannableString buildActionPresetMessageFormat(Context context, int preset, boolean mention) {
        if (preset == 0 || preset == 1) {
            SpannableString spannable = new SpannableString("\0 |* \0 \0");
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_TIMESTAMP), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            if (preset == 0)
                spannable.setSpan(new StyleSpan(Typeface.ITALIC), 3, 8, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_TIME), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_SENDER), 5, 6, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_MESSAGE),  7, 8, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_WRAP_ANCHOR), 2, 3, MessageBuilder.FORMAT_SPAN_FLAGS);
            if (mention) {
                spannable.setSpan(new StyleSpan(Typeface.BOLD), 5, 6, MessageBuilder.FORMAT_SPAN_FLAGS);
                spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_SENDER),  3, 8, MessageBuilder.FORMAT_SPAN_FLAGS);
            } else {
                spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_STATUS), 3, 4, MessageBuilder.FORMAT_SPAN_FLAGS);
                spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_SENDER), 5, 6, MessageBuilder.FORMAT_SPAN_FLAGS);
            }
            return spannable;
        }
        return null;
    }

    public static SpannableString buildNoticePresetMessageFormat(Context context, int preset) {
        if (preset == 0) {
            SpannableString spannable = new SpannableString("\0 |\0: \0");
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_TIMESTAMP), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_SENDER), 3, 7, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_TIME), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_SENDER), 3, 4, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_MESSAGE), 6, 7, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new StyleSpan(Typeface.BOLD), 3, 7, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_WRAP_ANCHOR), 2, 3, MessageBuilder.FORMAT_SPAN_FLAGS);
            return spannable;
        }
        if (preset == 1) {
            SpannableString spannable = new SpannableString("\0 |-\0- \0");
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_TIMESTAMP), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_SENDER), 3, 6, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_TIME), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_SENDER), 4, 5, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_MESSAGE),  7, 8, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_WRAP_ANCHOR), 2, 3, MessageBuilder.FORMAT_SPAN_FLAGS);
            return spannable;
        }
        return null;
    }

    public static SpannableString buildEventPresetMessageFormat(Context context, int preset) {
        if (preset == 0 || preset == 1) {
            SpannableString spannable = new SpannableString("\0 |* \0");
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_TIMESTAMP), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            if (preset == 0)
                spannable.setSpan(new StyleSpan(Typeface.ITALIC), 3, 6, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaForegroundColorSpan(context, MessageBuilder.MetaForegroundColorSpan.COLOR_STATUS), 3, 6, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_TIME), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_MESSAGE),  5, 6, MessageBuilder.FORMAT_SPAN_FLAGS);
            spannable.setSpan(new MessageBuilder.MetaChipSpan(context, MessageBuilder.MetaChipSpan.TYPE_WRAP_ANCHOR), 2, 3, MessageBuilder.FORMAT_SPAN_FLAGS);
            return spannable;
        }
        return null;
    }

    private void insertChip(int type) {
        EditText editText = mTextFormatBar.getEditText();
        int sStart = editText.getSelectionStart();
        int sEnd = editText.getSelectionEnd();
        SpannableString ss = new SpannableString("\0");
        ss.setSpan(new MessageBuilder.MetaChipSpan(this, type), 0, 1, MessageBuilder.FORMAT_SPAN_FLAGS);
        editText.getText().replace(sStart, sEnd, ss);
        refreshExamples();
    }

    public static Date getSampleMessageTime() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR, 0);
        calendar.set(Calendar.AM_PM, Calendar.PM);
        calendar.set(Calendar.HOUR_OF_DAY, 12);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_edit_only_done, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_done || id == android.R.id.home) {
            if (id == R.id.action_done) {
                save();
            }

            InputMethodManager manager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
            manager.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
            finish();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }


    private final View.OnFocusChangeListener mEditTextFocusListener = (View v, boolean hasFocus) -> {
        mTextFormatBar.setVisibility(hasFocus ? View.VISIBLE : View.GONE);
    };

}