/*
 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
 *           (C) 2000 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2003, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights
 * reserved.
 * Copyright (C) 2006 Graham Dennis (graham.dennis@gmail.com)
 * Copyright (C) 2009 Torch Mobile Inc. All rights reserved.
 * (http://www.torchmobile.com/)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef ComputedStyleConstants_h
#define ComputedStyleConstants_h

#include "core/ComputedStyleBaseConstants.h"
#include <cstddef>

namespace blink {

// TODO(sashab): Change these enums to enum classes with an unsigned underlying
// type. Enum classes provide better type safety, and forcing an unsigned
// underlying type prevents msvc from interpreting enums as negative numbers.
// See: crbug.com/628043

// Sides used when drawing borders and outlines. The values should run clockwise
// from top.
enum BoxSide { BSTop, BSRight, BSBottom, BSLeft };

// See core/dom/stylerecalc.md for an explanation on what each state means
enum StyleRecalcChange {
  NoChange,
  NoInherit,
  UpdatePseudoElements,
  IndependentInherit,
  Inherit,
  Force,
  Reattach,
  ReattachNoLayoutObject
};

// Static pseudo styles. Dynamic ones are produced on the fly.
enum PseudoId {
  // The order must be NOP ID, public IDs, and then internal IDs.
  // If you add or remove a public ID, you must update _pseudoBits in
  // ComputedStyle.
  PseudoIdNone,
  PseudoIdFirstLine,
  PseudoIdFirstLetter,
  PseudoIdBefore,
  PseudoIdAfter,
  PseudoIdBackdrop,
  PseudoIdSelection,
  PseudoIdFirstLineInherited,
  PseudoIdScrollbar,
  // Internal IDs follow:
  PseudoIdScrollbarThumb,
  PseudoIdScrollbarButton,
  PseudoIdScrollbarTrack,
  PseudoIdScrollbarTrackPiece,
  PseudoIdScrollbarCorner,
  PseudoIdResizer,
  PseudoIdInputListButton,
  // Special values follow:
  AfterLastInternalPseudoId,
  FirstPublicPseudoId = PseudoIdFirstLine,
  FirstInternalPseudoId = PseudoIdScrollbarThumb,
  PublicPseudoIdMask =
      ((1 << FirstInternalPseudoId) - 1) & ~((1 << FirstPublicPseudoId) - 1),
  ElementPseudoIdMask = (1 << (PseudoIdBefore - 1)) |
                        (1 << (PseudoIdAfter - 1)) |
                        (1 << (PseudoIdBackdrop - 1))
};

enum ColumnFill { ColumnFillBalance, ColumnFillAuto };

enum ColumnSpan { ColumnSpanNone = 0, ColumnSpanAll };

// These have been defined in the order of their precedence for
// border-collapsing. Do not change this order! This order also must match the
// order in CSSValueKeywords.in.
enum EBorderStyle {
  BorderStyleNone,
  BorderStyleHidden,
  BorderStyleInset,
  BorderStyleGroove,
  BorderStyleOutset,
  BorderStyleRidge,
  BorderStyleDotted,
  BorderStyleDashed,
  BorderStyleSolid,
  BorderStyleDouble
};

enum EBorderPrecedence {
  BorderPrecedenceOff,
  BorderPrecedenceTable,
  BorderPrecedenceColumnGroup,
  BorderPrecedenceColumn,
  BorderPrecedenceRowGroup,
  BorderPrecedenceRow,
  BorderPrecedenceCell
};

enum OutlineIsAuto { OutlineIsAutoOff = 0, OutlineIsAutoOn };

enum EPosition {
  StaticPosition = 0,
  RelativePosition = 1,
  AbsolutePosition = 2,
  StickyPosition = 3,
  // This value is required to pack our bits efficiently in LayoutObject.
  FixedPosition = 6
};

enum EMarginCollapse {
  MarginCollapseCollapse,
  MarginCollapseSeparate,
  MarginCollapseDiscard
};

// Box decoration attributes. Not inherited.

enum EBoxDecorationBreak { BoxDecorationBreakSlice, BoxDecorationBreakClone };

// Box attributes. Not inherited.

enum EBoxSizing { BoxSizingContentBox, BoxSizingBorderBox };

// Random visual rendering model attributes. Not inherited.

enum class EOverflowAnchor : unsigned { Visible, None, Auto };

enum class EOverflow : unsigned {
  Visible,
  Hidden,
  Scroll,
  Auto,
  Overlay,
  PagedX,
  PagedY
};

enum class EVerticalAlign : unsigned {
  Baseline,
  Middle,
  Sub,
  Super,
  TextTop,
  TextBottom,
  Top,
  Bottom,
  BaselineMiddle,
  Length
};

enum EClear { ClearNone = 0, ClearLeft = 1, ClearRight = 2, ClearBoth = 3 };

enum ETableLayout { TableLayoutAuto, TableLayoutFixed };

enum TextCombine { TextCombineNone, TextCombineAll };

enum EFillAttachment {
  ScrollBackgroundAttachment,
  LocalBackgroundAttachment,
  FixedBackgroundAttachment
};

enum EFillBox { BorderFillBox, PaddingFillBox, ContentFillBox, TextFillBox };

inline EFillBox enclosingFillBox(EFillBox boxA, EFillBox boxB) {
  if (boxA == BorderFillBox || boxB == BorderFillBox)
    return BorderFillBox;
  if (boxA == PaddingFillBox || boxB == PaddingFillBox)
    return PaddingFillBox;
  if (boxA == ContentFillBox || boxB == ContentFillBox)
    return ContentFillBox;
  return TextFillBox;
}

enum EFillRepeat { RepeatFill, NoRepeatFill, RoundFill, SpaceFill };

enum EFillLayerType { BackgroundFillLayer, MaskFillLayer };

// CSS3 Background Values
enum EFillSizeType { Contain, Cover, SizeLength, SizeNone };

// CSS3 Background Position
enum BackgroundEdgeOrigin { TopEdge, RightEdge, BottomEdge, LeftEdge };

// CSS Mask Source Types
enum EMaskSourceType { MaskAlpha, MaskLuminance };

// Deprecated Flexible Box Properties

enum EBoxPack { BoxPackStart, BoxPackCenter, BoxPackEnd, BoxPackJustify };
enum EBoxAlignment { BSTRETCH, BSTART, BCENTER, BEND, BBASELINE };
enum EBoxOrient { HORIZONTAL, VERTICAL };
enum EBoxLines { SINGLE, MULTIPLE };

// CSS3 Flexbox Properties

enum EFlexDirection { FlowRow, FlowRowReverse, FlowColumn, FlowColumnReverse };
enum EFlexWrap { FlexNoWrap, FlexWrap, FlexWrapReverse };

enum ETextSecurity { TSNONE, TSDISC, TSCIRCLE, TSSQUARE };

// CSS3 User Modify Properties

enum EUserModify { READ_ONLY, READ_WRITE, READ_WRITE_PLAINTEXT_ONLY };

// CSS3 User Drag Values

enum EUserDrag { DRAG_AUTO, DRAG_NONE, DRAG_ELEMENT };

// CSS3 User Select Values

enum EUserSelect { SELECT_NONE, SELECT_TEXT, SELECT_ALL };

// CSS3 Image Values
enum ObjectFit {
  ObjectFitFill,
  ObjectFitContain,
  ObjectFitCover,
  ObjectFitNone,
  ObjectFitScaleDown
};

// Word Break Values. Matches WinIE and CSS3

enum EWordBreak {
  NormalWordBreak,
  BreakAllWordBreak,
  KeepAllWordBreak,
  BreakWordBreak
};

enum EOverflowWrap { NormalOverflowWrap, BreakOverflowWrap };

enum LineBreak {
  LineBreakAuto,
  LineBreakLoose,
  LineBreakNormal,
  LineBreakStrict,
  LineBreakAfterWhiteSpace
};

enum EResize { RESIZE_NONE, RESIZE_BOTH, RESIZE_HORIZONTAL, RESIZE_VERTICAL };

enum QuoteType { OPEN_QUOTE, CLOSE_QUOTE, NO_OPEN_QUOTE, NO_CLOSE_QUOTE };

enum EAnimPlayState { AnimPlayStatePlaying, AnimPlayStatePaused };

static const size_t TextDecorationBits = 4;
enum TextDecoration {
  TextDecorationNone = 0x0,
  TextDecorationUnderline = 0x1,
  TextDecorationOverline = 0x2,
  TextDecorationLineThrough = 0x4,
  TextDecorationBlink = 0x8
};
inline TextDecoration operator|(TextDecoration a, TextDecoration b) {
  return TextDecoration(int(a) | int(b));
}
inline TextDecoration& operator|=(TextDecoration& a, TextDecoration b) {
  return a = a | b;
}

enum TextDecorationStyle {
  TextDecorationStyleSolid,
  TextDecorationStyleDouble,
  TextDecorationStyleDotted,
  TextDecorationStyleDashed,
  TextDecorationStyleWavy
};

static const size_t TextDecorationSkipBits = 3;
enum TextDecorationSkip {
  TextDecorationSkipNone = 0x0,
  TextDecorationSkipObjects = 0x1,
  TextDecorationSkipInk = 0x2
};
inline TextDecorationSkip operator|(TextDecorationSkip a,
                                    TextDecorationSkip b) {
  return TextDecorationSkip(static_cast<unsigned>(a) |
                            static_cast<unsigned>(b));
}
inline TextDecorationSkip& operator|=(TextDecorationSkip& a,
                                      TextDecorationSkip b) {
  return a = a | b;
}

enum TextAlignLast {
  TextAlignLastAuto,
  TextAlignLastStart,
  TextAlignLastEnd,
  TextAlignLastLeft,
  TextAlignLastRight,
  TextAlignLastCenter,
  TextAlignLastJustify
};

enum TextUnderlinePosition {
  // FIXME: Implement support for 'under left' and 'under right' values.
  TextUnderlinePositionAuto,
  TextUnderlinePositionUnder
};

enum EBreak {
  BreakAuto,
  BreakAvoid,
  BreakAvoidColumn,
  BreakAvoidPage,
  // Values below are only allowed for break-after and break-before. Values
  // above are also allowed for break-inside (in addition to break-after and
  // break-before).
  BreakValueLastAllowedForBreakInside = BreakAvoidPage,
  BreakColumn,
  BreakLeft,
  BreakPage,
  BreakRecto,
  BreakRight,
  BreakVerso,
  BreakValueLastAllowedForBreakAfterAndBefore = BreakVerso,
  BreakAlways  // Only needed by {page,-webkit-column}-break-{after,before}
               // shorthands.
};

enum class ECursor : unsigned {
  Auto,
  Cross,
  Default,
  Pointer,
  Move,
  VerticalText,
  Cell,
  ContextMenu,
  Alias,
  Progress,
  NoDrop,
  NotAllowed,
  ZoomIn,
  ZoomOut,
  EResize,
  NeResize,
  NwResize,
  NResize,
  SeResize,
  SwResize,
  SResize,
  WResize,
  EwResize,
  NsResize,
  NeswResize,
  NwseResize,
  ColResize,
  RowResize,
  Text,
  Wait,
  Help,
  AllScroll,
  WebkitGrab,
  WebkitGrabbing,
  Copy,
  None
};

enum class EDisplay : unsigned {
  Inline,
  Block,
  ListItem,
  InlineBlock,
  Table,
  InlineTable,
  TableRowGroup,
  TableHeaderGroup,
  TableFooterGroup,
  TableRow,
  TableColumnGroup,
  TableColumn,
  TableCell,
  TableCaption,
  WebkitBox,
  WebkitInlineBox,
  Flex,
  InlineFlex,
  Grid,
  InlineGrid,
  Contents,
  None
};

enum class EInsideLink : unsigned {
  kNotInsideLink,
  kInsideUnvisitedLink,
  kInsideVisitedLink
};

enum ETransformStyle3D { TransformStyle3DFlat, TransformStyle3DPreserve3D };

enum OffsetRotationType { OffsetRotationAuto, OffsetRotationFixed };

enum EBackfaceVisibility {
  BackfaceVisibilityVisible,
  BackfaceVisibilityHidden
};

enum ELineClampType { LineClampLineCount, LineClampPercentage };

enum Hyphens { HyphensNone, HyphensManual, HyphensAuto };

enum ESpeak {
  SpeakNone,
  SpeakNormal,
  SpeakSpellOut,
  SpeakDigits,
  SpeakLiteralPunctuation,
  SpeakNoPunctuation
};

enum TextEmphasisFill { TextEmphasisFillFilled, TextEmphasisFillOpen };

enum TextEmphasisMark {
  TextEmphasisMarkNone,
  TextEmphasisMarkAuto,
  TextEmphasisMarkDot,
  TextEmphasisMarkCircle,
  TextEmphasisMarkDoubleCircle,
  TextEmphasisMarkTriangle,
  TextEmphasisMarkSesame,
  TextEmphasisMarkCustom
};

enum TextEmphasisPosition {
  TextEmphasisPositionOver,
  TextEmphasisPositionUnder
};

enum TextOrientation {
  TextOrientationMixed,
  TextOrientationUpright,
  TextOrientationSideways
};

enum TextOverflow { TextOverflowClip = 0, TextOverflowEllipsis };

enum EImageRendering {
  ImageRenderingAuto,
  ImageRenderingOptimizeSpeed,
  ImageRenderingOptimizeQuality,
  ImageRenderingOptimizeContrast,
  ImageRenderingPixelated
};

enum RubyPosition { RubyPositionBefore, RubyPositionAfter };

static const size_t GridAutoFlowBits = 4;
enum InternalGridAutoFlowAlgorithm {
  InternalAutoFlowAlgorithmSparse = 0x1,
  InternalAutoFlowAlgorithmDense = 0x2
};

enum InternalGridAutoFlowDirection {
  InternalAutoFlowDirectionRow = 0x4,
  InternalAutoFlowDirectionColumn = 0x8
};

enum GridAutoFlow {
  AutoFlowRow = InternalAutoFlowAlgorithmSparse | InternalAutoFlowDirectionRow,
  AutoFlowColumn =
      InternalAutoFlowAlgorithmSparse | InternalAutoFlowDirectionColumn,
  AutoFlowRowDense =
      InternalAutoFlowAlgorithmDense | InternalAutoFlowDirectionRow,
  AutoFlowColumnDense =
      InternalAutoFlowAlgorithmDense | InternalAutoFlowDirectionColumn
};

enum DraggableRegionMode {
  DraggableRegionNone,
  DraggableRegionDrag,
  DraggableRegionNoDrag
};

static const size_t TouchActionBits = 6;
enum TouchAction {
  TouchActionNone = 0x0,
  TouchActionPanLeft = 0x1,
  TouchActionPanRight = 0x2,
  TouchActionPanX = TouchActionPanLeft | TouchActionPanRight,
  TouchActionPanUp = 0x4,
  TouchActionPanDown = 0x8,
  TouchActionPanY = TouchActionPanUp | TouchActionPanDown,
  TouchActionPan = TouchActionPanX | TouchActionPanY,
  TouchActionPinchZoom = 0x10,
  TouchActionManipulation = TouchActionPan | TouchActionPinchZoom,
  TouchActionDoubleTapZoom = 0x20,
  TouchActionAuto = TouchActionManipulation | TouchActionDoubleTapZoom
};
inline TouchAction operator|(TouchAction a, TouchAction b) {
  return static_cast<TouchAction>(int(a) | int(b));
}
inline TouchAction& operator|=(TouchAction& a, TouchAction b) {
  return a = a | b;
}
inline TouchAction operator&(TouchAction a, TouchAction b) {
  return static_cast<TouchAction>(int(a) & int(b));
}
inline TouchAction& operator&=(TouchAction& a, TouchAction b) {
  return a = a & b;
}

enum EIsolation { IsolationAuto, IsolationIsolate };

static const size_t ContainmentBits = 4;
enum Containment {
  ContainsNone = 0x0,
  ContainsLayout = 0x1,
  ContainsStyle = 0x2,
  ContainsPaint = 0x4,
  ContainsSize = 0x8,
  ContainsStrict =
      ContainsLayout | ContainsStyle | ContainsPaint | ContainsSize,
  ContainsContent = ContainsLayout | ContainsStyle | ContainsPaint,
};
inline Containment operator|(Containment a, Containment b) {
  return Containment(int(a) | int(b));
}
inline Containment& operator|=(Containment& a, Containment b) {
  return a = a | b;
}

enum ItemPosition {
  ItemPositionAuto,  // It will mean 'normal' after running the StyleAdjuster to
                     // avoid resolving the initial values.
  ItemPositionNormal,
  ItemPositionStretch,
  ItemPositionBaseline,
  ItemPositionLastBaseline,
  ItemPositionCenter,
  ItemPositionStart,
  ItemPositionEnd,
  ItemPositionSelfStart,
  ItemPositionSelfEnd,
  ItemPositionFlexStart,
  ItemPositionFlexEnd,
  ItemPositionLeft,
  ItemPositionRight
};

enum OverflowAlignment {
  OverflowAlignmentDefault,
  OverflowAlignmentUnsafe,
  OverflowAlignmentSafe
};

enum ItemPositionType { NonLegacyPosition, LegacyPosition };

enum ContentPosition {
  ContentPositionNormal,
  ContentPositionBaseline,
  ContentPositionLastBaseline,
  ContentPositionCenter,
  ContentPositionStart,
  ContentPositionEnd,
  ContentPositionFlexStart,
  ContentPositionFlexEnd,
  ContentPositionLeft,
  ContentPositionRight
};

enum ContentDistributionType {
  ContentDistributionDefault,
  ContentDistributionSpaceBetween,
  ContentDistributionSpaceAround,
  ContentDistributionSpaceEvenly,
  ContentDistributionStretch
};

// Reasonable maximum to prevent insane font sizes from causing crashes on some
// platforms (such as Windows).
static const float maximumAllowedFontSize = 10000.0f;

enum TextIndentLine { TextIndentFirstLine, TextIndentEachLine };
enum TextIndentType { TextIndentNormal, TextIndentHanging };

enum CSSBoxType {
  BoxMissing = 0,
  MarginBox,
  BorderBox,
  PaddingBox,
  ContentBox
};

enum ScrollSnapType {
  ScrollSnapTypeNone,
  ScrollSnapTypeMandatory,
  ScrollSnapTypeProximity
};

enum AutoRepeatType { NoAutoRepeat, AutoFill, AutoFit };

}  // namespace blink

#endif  // ComputedStyleConstants_h
