// Stores information about the current content of the user's selection
export interface MutableSelectionFormatting {
	bolded: boolean;
	italicized: boolean;
	inChecklist: boolean;
	inCode: boolean;
	inUnorderedList: boolean;
	inOrderedList: boolean;
	inMath: boolean;
	inLink: boolean;
	spellChecking: boolean;
	unspellCheckableRegion: boolean;

	// Link data, both fields are null if not in a link.
	linkData: {
		readonly linkText: string|null;
		readonly linkURL: string|null;
	};

	// If [headerLevel], [listLevel], etc. are zero, then the
	// selection isn't in a header/list
	headerLevel: number;
	listLevel: number;

	// Content of the selection
	selectedText: string;
}
type SelectionFormatting = Readonly<MutableSelectionFormatting>;
export default SelectionFormatting;

export const defaultSelectionFormatting: SelectionFormatting = {
	bolded: false,
	italicized: false,
	inChecklist: false,
	inCode: false,
	inUnorderedList: false,
	inOrderedList: false,
	inMath: false,
	inLink: false,
	spellChecking: false,
	unspellCheckableRegion: false,

	linkData: {
		linkText: null,
		linkURL: null,
	},

	headerLevel: 0,
	listLevel: 0,

	selectedText: '',
};

export const selectionFormattingEqual = (a: SelectionFormatting, b: SelectionFormatting): boolean => {
	// Get keys from the default so that only SelectionFormatting key/value pairs are
	// considered. If a and/or b inherit from SelectionFormatting, we want to ignore
	// keys added by child interfaces.
	const keys = Object.keys(defaultSelectionFormatting) as (keyof SelectionFormatting)[];

	for (const key of keys) {
		if (key === 'linkData') {
			// A deeper check is required for linkData
			if (a[key].linkText !== b[key].linkText || a[key].linkURL !== b[key].linkURL) {
				return false;
			}
		} else if (a[key] !== b[key]) {
			return false;
		}
	}

	return true;
};