grammar org.openhab.core.model.sitemap.Sitemap with org.eclipse.xtext.common.Terminals

import "http://www.eclipse.org/emf/2002/Ecore" as ecore
generate sitemap "https://openhab.org/model/Sitemap"

SitemapModel:
    'sitemap' Sitemap;

Sitemap:
    name=ID ('label=' label=STRING)? ('icon=' icon=STRING)? '{'
    (children+=Widget)+
    '}';

Widget:
    (LinkableWidget | NonLinkableWidget);

NonLinkableWidget:
    Switch | Selection | Slider | Setpoint | Video | Chart | Webview | Colorpicker | Colortemperaturepicker | Mapview | Input | Button | Default;

LinkableWidget:
    (Text | Group | Image | Frame | Buttongrid)
    ('{'
    (children+=Widget)+
    '}')?;

Frame:
    {Frame} 'Frame' (('item=' item=ItemRef)? & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Text:
    {Text} 'Text' (('item=' item=ItemRef)? & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Group:
    'Group' (('item=' item=GroupItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Image:
    'Image' (('item=' item=ItemRef)? & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('url=' url=STRING)? & ('refresh=' refresh=INT)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Video:
    'Video' (('item=' item=ItemRef)? & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('url=' url=STRING) & ('encoding=' encoding=STRING)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Chart:
    'Chart' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('service=' service=STRING)? & ('refresh=' refresh=INT)? & ('period=' period=Period) &
    ('legend=' legend=BOOLEAN_OBJECT)? & ('forceasitem=' forceAsItem=BOOLEAN_OBJECT)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')? &
    ('yAxisDecimalPattern=' yAxisDecimalPattern=(STRING))? &
    ('interpolation=' interpolation=(STRING))?);

Webview:
    'Webview' (('item=' item=ItemRef)? & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('height=' height=INT)? & ('url=' url=STRING) &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Switch:
    'Switch' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('mappings=[' mappings+=Mapping (',' mappings+=Mapping)* ']')? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Mapview:
    'Mapview' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('height=' height=INT)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Slider:
    'Slider' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    (switchEnabled?='switchSupport')? & (releaseOnly?='releaseOnly')? &
    ('minValue=' minValue=Number)? & ('maxValue=' maxValue=Number)? & ('step=' step=Number)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Selection:
    'Selection' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('mappings=[' mappings+=Mapping (',' mappings+=Mapping)* ']')? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Setpoint:
    'Setpoint' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('minValue=' minValue=Number)? & ('maxValue=' maxValue=Number)? & ('step=' step=Number)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Colorpicker:
    'Colorpicker' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Colortemperaturepicker:
    'Colortemperaturepicker' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('minValue=' minValue=Number)? & ('maxValue=' maxValue=Number)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Input:
    'Input' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('inputHint=' inputHint=STRING)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Buttongrid:
    {Buttongrid} 'Buttongrid' (('item=' item=ItemRef)? & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('buttons=[' buttons+=ButtonDefinition (',' buttons+=ButtonDefinition)* ']')? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Button:
    'Button' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('row=' row=INT) & ('column=' column=INT) & (stateless?='stateless')? &
    ('click=' cmd=Command) & ('release=' releaseCmd=Command)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

Default:
    'Default' (('item=' item=ItemRef) & ('label=' label=(ID | STRING))? &
    (('icon=' icon=Icon) |
        ('icon=[' (IconRules+=IconRule (',' IconRules+=IconRule)*) ']') |
        ('staticIcon=' staticIcon=Icon))? &
    ('height=' height=INT)? &
    ('labelcolor=[' (LabelColor+=ColorArray (',' LabelColor+=ColorArray)*) ']')? &
    ('valuecolor=[' (ValueColor+=ColorArray (',' ValueColor+=ColorArray)*) ']')? &
    ('iconcolor=[' (IconColor+=ColorArray (',' IconColor+=ColorArray)*) ']')? &
    ('visibility=[' (Visibility+=VisibilityRule (',' Visibility+=VisibilityRule)*) ']')?);

ButtonDefinition:
    row=INT ':' column=INT ':' cmd=Command '=' label=(ID | STRING) ('=' icon=Icon)?;

Mapping:
    cmd=Command (':' releaseCmd=Command)? '=' label=(ID | STRING) ('=' icon=Icon)?;

VisibilityRule:
    conditions+=Condition ('AND' conditions+=Condition)*;

ItemRef:
    ID;

GroupItemRef:
    ID;

Icon returns ecore::EString:
    STRING | (ID ':' (ID ':')?)? IconName;

// Allow hyphen inside an icon name
IconName:
    (ID '-')* ID;

Period:
    (ID '-')? ID;

ColorArray:
    ((conditions+=Condition ('AND' conditions+=Condition)*) '=')? (arg=STRING);

IconRule:
    ((conditions+=Condition ('AND' conditions+=Condition)*) '=')? (arg=Icon);

Condition:
    (item=ID)? (condition=('==' | '>' | '<' | '>=' | '<=' | '!='))? (sign=('-' | '+'))? (state=XState);

Command returns ecore::EString:
    Number | ID | STRING;

Number returns ecore::EBigDecimal:
    '-'? (INT | FLOAT);

XState returns ecore::EString:
    INT | ID | STRING | FLOAT;

@Override 
terminal ID:
    ('^'? ('a'..'z' | 'A'..'Z' | '_') ('a'..'z' | 'A'..'Z' | '_' | '0'..'9')*) |
    (('0'..'9')+ ('a'..'z' | 'A'..'Z' | '_') ('0'..'9' | 'a'..'z' | 'A'..'Z' | '_')*);

terminal FLOAT returns ecore::EBigDecimal:
    INT '.' INT;

BOOLEAN_OBJECT returns ecore::EBooleanObject:
    'true' | 'false';
