/*
 * Copyright © 2013 Intel Corporation
 * Copyright © 2014 Jaguar Landrover
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

images {
   image: "icon-backspace.png" COMP;
   image: "icon-enter.png" COMP;
   image: "icon-language.png" COMP;
   image: "icon-shift-active.png" COMP;
   image: "icon-shift.png" COMP;
   image: "icon-space.png" COMP;

   image: "key-default.png" COMP;
   image: "key-default-pressed.png" COMP;
   image: "key-hint.png" COMP;
   image: "key-hint-bg.png" COMP;
   image: "key-special.png" COMP;
   image: "key-special-pressed.png" COMP;
}

fonts {
   font: "SourceSansPro-Regular.ttf" "Regular";
   font: "SourceSansPro-Semibold.ttf" "Semibold";
}

data {
   file: "ignore-keys" "ignorekeys.txt";
}

collections {
   group {
      name: "main";

      min: MIN_WIDTH MIN_HEIGHT;
      max: MAX_WIDTH MAX_HEIGHT;

      parts {
         part {
            name: "rect_bg";
            mouse_events: 0;
            type: RECT;
            description {
               state: "default" 0.0;
               color: 255 255 255 0;
               rel1 {
                  relative: 0.0 0.0;
                  offset: 0 0;
               }
               rel2 {
                  relative: 1.0 1.0;
                  offset: -1 -1;
               }
            }
         }

         part {
            name: "background";
            mouse_events: 1;
            pointer_mode: NOGRAB;
            type: RECT;
            description {
               state: "default" 0.0;
               color: 214 215 218 255;
               rel1 {
                  relative: 0.0 0.0;
                  offset: 0 (150*SCALE);
               }
               rel2 {
                  relative: 1.0 1.0;
                  offset: -1 -1;
               }
            }
         }
      }

#define KEY_GROUP(_name)                                               \
      parts {                                                          \
         part {                                                        \
            name: _name"_clip";                                        \
            type: RECT;                                                \
            description {                                              \
               state: "default" 0.0;                                   \
               rel1 {                                                  \
                  relative: 0.0 0.0;                                   \
                  offset: 0 0;                                         \
               }                                                       \
               rel2 {                                                  \
                  relative: 1.0 1.0;                                   \
                  offset: -1 -1;                                       \
               }                                                       \
            }                                                          \
            description {                                              \
               state: "hidden" 0.0;                                    \
               inherit: "default" 0.0;                                 \
               visible: 0;                                             \
            }                                                          \
         }                                                             \
         part {                                                        \
            name: _name;                                               \
            type: GROUP;                                               \
            source: _name;                                             \
            clip_to: _name"_clip";                                     \
            description {                                              \
               state: "default" 0.0;                                   \
               rel1 {                                                  \
                  to: "background";                                    \
                  relative: 0.0 0.0;                                   \
                  offset: (5*SCALE) (10*SCALE);                        \
               }                                                       \
               rel2 {                                                  \
                  to: "background";                                    \
                  relative: 1.0 1.0;                                   \
                  offset: -1 -1;                                       \
               }                                                       \
            }                                                          \
         }                                                             \
      }                                                                \
      programs {                                                       \
         program {                                                     \
            name: "show-"_name;                                        \
            action: STATE_SET "default" 0.0;                           \
            target: _name"_clip";                                      \
         }                                                             \
         program {                                                     \
            name: "hide-"_name;                                        \
            action: STATE_SET "hidden" 0.0;                            \
            target: _name"_clip";                                      \
         }                                                             \
      }

      KEY_GROUP("alphanum")
      KEY_GROUP("numeric")
      KEY_GROUP("special-1")
      KEY_GROUP("special-2")
      KEY_GROUP("fixed")

      programs {
         program {
            name: "alphanum_show";
            signal: "show,alphanumeric";
            after: "show-alphanum";
            after: "hide-numeric";
            after: "hide-special-1";
            after: "hide-special-2";
            after: "show-fixed";
         }

         program {
            name: "numeric_show";
            signal: "show,numeric";
            after: "show-numeric";
            after: "hide-alphanum";
            after: "hide-special-1";
            after: "hide-special-2";
            after: "hide-fixed";
         }

         program {
            name: "special-1_show";
            signal: "show,special,1";
            after: "show-special-1";
            after: "hide-numeric";
            after: "hide-alphanum";
            after: "hide-special-2";
            after: "show-fixed";
         }

         program {
            name: "special-2_show";
            signal: "show,special,2";
            after: "show-special-2";
            after: "hide-numeric";
            after: "hide-alphanum";
            after: "hide-special-1";
            after: "show-fixed";
         }

         program {
            name: "?123_clicked";
            signal: "key_down";
            source: "alphanum:?123";
            after: "special-1_show";
         }
         program {
            name: "special-1_abc_clicked";
            signal: "key_down";
            source: "special-1:abc";
            after: "alphanum_show";
         }
         program {
            name: "special-2_abc_clicked";
            signal: "key_down";
            source: "special-2:abc";
            after: "alphanum_show";
         }
         program {
            name: "1/2_clicked";
            signal: "key_down";
            source: "special-1:1/2";
            after: "special-2_show";
         }
         program {
            name: "2/2_clicked";
            signal: "key_down";
            source: "special-2:2/2";
            after: "special-1_show";
         }
         program {
            name: "init";
            signal: "show";
            after: "alphanum_show";
         }
      }
   }

   group {
      name: "alphanum";

#define MOUSE_DOWN_UP_SCRIPTS                                          \
          public shift_pressed = 0;                                    \
          public mouse_down = 0;                                       \
          public long_press_timer = 0;                                 \
          public long_press = 0;                                       \
          public pressed_key;                                          \
                                                                       \
          public _set_long_press(val) {                                \
             new _cur[20];                                             \
             new _timer;                                               \
             _timer = get_int(long_press_timer);                       \
             if (_timer) {                                             \
                cancel_timer(_timer);                                  \
                set_int(long_press_timer, 0);                          \
             }                                                         \
             set_int(long_press, val);                                 \
             if (!val)                                                 \
                return;                                                \
             get_str(pressed_key, _cur, 20);                           \
             if (strlen(_cur) > 0) {                                   \
                emit("long_press", _cur);                              \
             }                                                         \
          }                                                            \
                                                                       \
          _set_key_pressed(_key[]) {                                   \
             new _cur[20];                                             \
             new _prg[30];                                             \
             new _timer;                                               \
             get_str(pressed_key, _cur, 20);                           \
             if (strlen(_cur) > 0) {                                   \
                _set_key_released(_cur);                               \
             }                                                         \
             set_str(pressed_key, _key);                               \
             _timer = timer(0.5, "_set_long_press", 1);                \
             set_int(long_press_timer, _timer);                        \
             snprintf(_prg, 30, "key-press-%s", _key);                 \
             run_program(get_program_id(_prg));                        \
          }                                                            \
                                                                       \
          _set_key_released(_key[]) {                                  \
             new _prg[30];                                             \
             _set_long_press(0);                                       \
             set_str(pressed_key, "");                                 \
             snprintf(_prg, 30, "key-release-%s", _key);               \
             run_program(get_program_id(_prg));                        \
          }                                                            \

#define MOUSE_DOWN_UP_PROGRAMS                                         \
         program {                                                     \
            name: "mouse-down";                                        \
            signal: "mouse,down,1";                                    \
            source: "*";                                               \
            script {                                                   \
               set_int(mouse_down, 1);                                 \
            }                                                          \
         }                                                             \
         program {                                                     \
            name: "mouse-up";                                          \
            signal: "mouse,up,1";                                      \
            source: "*";                                               \
            script {                                                   \
               set_int(mouse_down, 0);                                 \
            }                                                          \
         }

      script {
         MOUSE_DOWN_UP_SCRIPTS
      }
      programs {
         MOUSE_DOWN_UP_PROGRAMS
      }
      parts {
#undef INIT_HSPACE
#define INIT_HSPACE 5
#define KEY_WIDTH (65*SCALE)
#define KEY_HEIGHT (90*SCALE)
#define COL_SPACE 5
#define KEY_OFFSET(index) ((COL_SPACE+KEY_WIDTH)*index)+INIT_HSPACE

#define FIRST_ROW 0
#define ROW_SPACE (20*SCALE)

#define SKEY_FULL(key_low, key_up, key_name, key_alt, x, y)            \
         part {                                                        \
            name: "key-img-"key_name;                                  \
            type: IMAGE;                                               \
            mouse_events: 0;                                           \
            description {                                              \
               state: "default" 0.0;                                   \
               min: KEY_WIDTH KEY_HEIGHT;                              \
               max: KEY_WIDTH KEY_HEIGHT;                              \
               fixed: 1 1;                                             \
               rel1 {                                                  \
                  relative: 0.0 0.0;                                   \
                  offset: (x) (y);                                     \
               }                                                       \
               rel2 {                                                  \
                  relative: 0.0 0.0;                                   \
                  offset: (x+KEY_WIDTH-1) (y+KEY_HEIGHT-1);            \
               }                                                       \
               image {                                                 \
                  normal: "key-default.png";                           \
                  border: 8 8 10 10;                                   \
               }                                                       \
            }                                                          \
            description {                                              \
               state: "down" 0.0;                                      \
               inherit: "default" 0.0;                                 \
               rel1.offset: (x+1) (y+1);                               \
               rel2.offset: (x+1+KEY_WIDTH-1) (y+1+KEY_HEIGHT-1);      \
               image.normal: "key-default-pressed.png";                \
            }                                                          \
         }                                                             \
         part {                                                        \
            name: "key-bg-"key_name;                                   \
            type: RECT;                                                \
            pointer_mode: NOGRAB;                                      \
            description {                                              \
               state: "default" 0.0;                                   \
               color: 0 0 0 0;                                         \
               rel1 {                                                  \
                  to: "key-img-"key_name;                              \
                  relative: 0.0 0.0;                                   \
                  offset: 3 2;                                         \
               }                                                       \
               rel2 {                                                  \
                  to: "key-img-"key_name;                              \
                  relative: 1.0 1.0;                                   \
                  offset: -4 -6;                                       \
               }                                                       \
            }                                                          \
         }                                                             \
         part {                                                        \
           name: "key-lbl-"key_name;                                   \
           type: TEXT;                                                 \
           mouse_events: 0;                                            \
           effect: SHADOW BOTTOM;                                      \
           description {                                               \
              state: "default" 0.0;                                    \
              color: 63 67 72 255;                                     \
              color2: 240 240 240 255;                                 \
              color3: 240 240 240 255;                                 \
              rel1 {                                                   \
                 to: "key-bg-"key_name;                                \
                 relative: 0.0 0.4;                                    \
              }                                                        \
              rel2 {                                                   \
                 to: "key-bg-"key_name;                                \
                 relative: 1.0 0.9;                                    \
              }                                                        \
              text {                                                   \
                 font: "Regular";                                      \
                 size: (44*SCALE);                                     \
                 text: key_low;                                        \
              }                                                        \
            }                                                          \
         }                                                             \
         part {                                                        \
           name: "key-lbl-alt-"key_name;                               \
           type: TEXT;                                                 \
           mouse_events: 0;                                            \
           effect: SHADOW BOTTOM;                                      \
           description {                                               \
              state: "default" 0.0;                                    \
              color: 63 67 72 255;                                     \
              color2: 240 240 240 255;                                 \
              color3: 240 240 240 255;                                 \
              rel1 {                                                   \
                 to: "key-bg-"key_name;                                \
                 relative: 0.0 0.1;                                    \
              }                                                        \
              rel2 {                                                   \
                 to: "key-bg-"key_name;                                \
                 relative: 1.0 0.4;                                    \
              }                                                        \
              text {                                                   \
                 font: "Regular";                                      \
                 size: (22*SCALE);                                     \
                 align: 0.8 0.0;                                       \
                 text: key_alt;                                        \
              }                                                        \
            }                                                          \
         }                                                             \
         part {                                                        \
            name: "key-img-hint-"key_name;                             \
            type: IMAGE;                                               \
            mouse_events: 0;                                           \
            description {                                              \
               state: "default" 0.0;                                   \
               min: KEY_WIDTH KEY_HEIGHT;                              \
               max: KEY_WIDTH KEY_HEIGHT;                              \
               fixed: 1 1;                                             \
               rel1 {                                                  \
                  to: "key-img-"key_name;                              \
                  relative: 0.0 0.0;                                   \
                  offset: 0 ((-20*SCALE)-KEY_HEIGHT);                  \
               }                                                       \
               rel2 {                                                  \
                  to: "key-img-"key_name;                              \
                  relative: 1.0 0.0;                                   \
                  offset: 0 (-20*SCALE);                               \
               }                                                       \
               image {                                                 \
                  normal: "key-hint.png";                              \
                  border: 8 8 10 10;                                   \
               }                                                       \
               visible: 0;                                             \
            }                                                          \
            description {                                              \
               state: "down" 0.0;                                      \
               inherit: "default" 0.0;                                 \
               visible: 1;                                             \
            }                                                          \
         }                                                             \
         part {                                                        \
            name: "key-lbl-hint-"key_name;                             \
            type: TEXT;                                                \
            mouse_events: 0;                                           \
            effect: SHADOW BOTTOM;                                     \
            description {                                              \
               state: "default" 0.0;                                   \
               color: 63 67 72 255;                                    \
               color2: 240 240 240 255;                                \
               color3: 240 240 240 255;                                \
               rel1 {                                                  \
                  to: "key-img-hint-"key_name;                         \
                  relative: 0.0 0.0;                                   \
               }                                                       \
               rel2 {                                                  \
                  to: "key-img-hint-"key_name;                         \
                  relative: 1.0 1.0;                                   \
               }                                                       \
               text {                                                  \
                  font: "Regular";                                     \
                  size: (48*SCALE);                                    \
                  text: key_low;                                       \
               }                                                       \
               visible: 0;                                             \
            }                                                          \
            description {                                              \
               state: "down" 0.0;                                      \
               inherit: "default" 0.0;                                 \
               visible: 1;                                             \
            }                                                          \
         }                                                             \
         programs {                                                    \
            program {                                                  \
               name: "key-mouse-in-"key_name;                          \
               signal: "mouse,in";                                     \
               source: "key-bg-"key_name;                              \
               script {                                                \
                  if (get_int(mouse_down) == 0)                        \
                     return;                                           \
                  _set_key_pressed(key_name);                          \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "key-mouse-out-"key_name;                         \
               signal: "mouse,out";                                    \
               source: "key-bg-"key_name;                              \
               script {                                                \
                  if (get_int(mouse_down) == 0)                        \
                     return;                                           \
                  _set_key_released(key_name);                         \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "key-mouse-down-"key_name;                        \
               signal: "mouse,down,1";                                 \
               source: "key-bg-"key_name;                              \
               script {                                                \
                  _set_key_pressed(key_name);                          \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "key-mouse-up-"key_name;                          \
               signal: "mouse,up,1";                                   \
               source: "key-bg-"key_name;                              \
               script {                                                \
                  if (get_int(long_press) == 0) {                      \
                     if (get_int(shift_pressed) == 0)                  \
                        emit("key_down", key_low);                     \
                     else                                              \
                        emit("key_down", key_up);                      \
                  } else {                                             \
                     if (strcmp(key_alt, " "))                         \
                        emit("key_down", key_alt);                     \
                     else if (get_int(shift_pressed) == 0)             \
                        emit("key_down", key_low);                     \
                     else                                              \
                        emit("key_down", key_up);                      \
                  }                                                    \
                  _set_key_released(key_name);                         \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "key-press-"key_name;                             \
               action: STATE_SET "down" 0.0;                           \
               target: "key-img-"key_name;                             \
               target: "key-img-hint-"key_name;                        \
               target: "key-lbl-hint-"key_name;                        \
            }                                                          \
            program {                                                  \
               name: "key-release-"key_name;                           \
               action: STATE_SET "default" 0.0;                        \
               transition: LINEAR 0.2;                                 \
               target: "key-img-"key_name;                             \
               target: "key-img-hint-"key_name;                        \
               target: "key-lbl-hint-"key_name;                        \
               after: "shift-pressed-"key_name;                        \
            }                                                          \
            program {                                                  \
               name: "long-press-"key_name;                            \
               signal: "long_press";                                   \
               source: key_name;                                       \
               script {                                                \
                  if (strcmp(key_alt, " "))                            \
                     set_text(PART:"key-lbl-hint-"key_name, key_alt);  \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "shift-pressed-"key_name;                         \
               signal: "key_down";                                     \
               source: "shift";                                        \
               script {                                                \
                  if (get_int(shift_pressed) == 0) {                   \
                     set_text(PART:"key-lbl-"key_name, key_low);       \
                     set_text(PART:"key-lbl-hint-"key_name, key_low);  \
                  } else {                                             \
                     set_text(PART:"key-lbl-"key_name, key_up);        \
                     set_text(PART:"key-lbl-hint-"key_name, key_up);   \
                  }                                                    \
               }                                                       \
            }                                                          \
         }
#define KEY_FULL(low, up, alt, x, y) SKEY_FULL(low, up, low, alt, x, y)
#define SKEY(name, text, alt, x, y) SKEY_FULL(name, name, text, alt, x, y)
#define KEY(v, alt, x, y) SKEY(v, v, alt, x, y)

         KEY_FULL("q", "Q", "1", KEY_OFFSET(0), FIRST_ROW)
         KEY_FULL("w", "W", "2", KEY_OFFSET(1), FIRST_ROW)
         KEY_FULL("e", "E", "3", KEY_OFFSET(2), FIRST_ROW)
         KEY_FULL("r", "R", "4", KEY_OFFSET(3), FIRST_ROW)
         KEY_FULL("t", "T", "5", KEY_OFFSET(4), FIRST_ROW)
         KEY_FULL("y", "Y", "6", KEY_OFFSET(5), FIRST_ROW)
         KEY_FULL("u", "U", "7", KEY_OFFSET(6), FIRST_ROW)
         KEY_FULL("i", "I", "8", KEY_OFFSET(7), FIRST_ROW)
         KEY_FULL("o", "O", "9", KEY_OFFSET(8), FIRST_ROW)
         KEY_FULL("p", "P", "0", KEY_OFFSET(9), FIRST_ROW)

#undef INIT_HSPACE
#define INIT_HSPACE (45*SCALE)
#define SECOND_ROW FIRST_ROW+KEY_HEIGHT+ROW_SPACE

         KEY_FULL("a", "A", "-", KEY_OFFSET(0), SECOND_ROW)
         KEY_FULL("s", "S", "@", KEY_OFFSET(1), SECOND_ROW)
         KEY_FULL("d", "D", "*", KEY_OFFSET(2), SECOND_ROW)
         KEY_FULL("f", "F", "^", KEY_OFFSET(3), SECOND_ROW)
         KEY_FULL("g", "G", ":", KEY_OFFSET(4), SECOND_ROW)
         KEY_FULL("h", "H", ";", KEY_OFFSET(5), SECOND_ROW)
         KEY_FULL("j", "J", "(", KEY_OFFSET(6), SECOND_ROW)
         KEY_FULL("k", "K", ")", KEY_OFFSET(7), SECOND_ROW)
         KEY_FULL("l", "L", "~", KEY_OFFSET(8), SECOND_ROW)

#undef INIT_HSPACE
#define INIT_HSPACE (110*SCALE)
#define THIRD_ROW SECOND_ROW+KEY_HEIGHT+ROW_SPACE

         KEY_FULL("z", "Z", "/",  KEY_OFFSET(0), THIRD_ROW)
         KEY_FULL("x", "X", "'",  KEY_OFFSET(1), THIRD_ROW)
         KEY_FULL("c", "C", "\"", KEY_OFFSET(2), THIRD_ROW)
         KEY_FULL("v", "V", ".",  KEY_OFFSET(3), THIRD_ROW)
         KEY_FULL("b", "B", ",",  KEY_OFFSET(4), THIRD_ROW)
         KEY_FULL("n", "N", "?",  KEY_OFFSET(5), THIRD_ROW)
         KEY_FULL("m", "M", "!",  KEY_OFFSET(6), THIRD_ROW)

#define KEY_SPECIAL(val, x, y, w)                                      \
         part {                                                        \
            name: "key-img-"val;                                       \
            type: IMAGE;                                               \
            mouse_events: 0;                                           \
            description {                                              \
               state: "default" 0.0;                                   \
               min: w KEY_HEIGHT;                                      \
               max: w KEY_HEIGHT;                                      \
               fixed: 1 1;                                             \
               rel1 {                                                  \
                  relative: 0.0 0.0;                                   \
                  offset: (x) (y);                                     \
               }                                                       \
               rel2 {                                                  \
                  relative: 0.0 0.0;                                   \
                  offset: (x+w-1) (y+KEY_HEIGHT-1);                    \
               }                                                       \
               image {                                                 \
                  normal: "key-special.png";                           \
                  border: 8 8 10 10;                                   \
               }                                                       \
            }                                                          \
            description {                                              \
               state: "down" 0.0;                                      \
               inherit: "default" 0.0;                                 \
               rel1.offset: (x+1) (y+1);                               \
               rel2.offset: (x+1+w-1) (y+1+KEY_HEIGHT-1);              \
               image.normal: "key-special-pressed.png";                \
            }                                                          \
         }                                                             \
         part {                                                        \
            name: "key-bg-"val;                                        \
            type: RECT;                                                \
            pointer_mode: NOGRAB;                                      \
            description {                                              \
               state: "default" 0.0;                                   \
               rel1 {                                                  \
                  to: "key-img-"val;                                   \
                  relative: 0.0 0.0;                                   \
                  offset: 3 2;                                         \
               }                                                       \
               rel2 {                                                  \
                  to: "key-img-"val;                                   \
                  relative: 1.0 1.0;                                   \
                  offset: -4 -6;                                       \
               }                                                       \
               color: 0 0 0 0;                                         \
            }                                                          \
         }                                                             \
         programs {                                                    \
            program {                                                  \
               name: "key-mouse-up-"val;                               \
               signal: "mouse,up,1";                                   \
               source: "key-bg-"val;                                   \
               script {                                                \
                  emit("key_down", val);                               \
                  _set_key_released(val);                              \
                  emit("key_up", val);                                 \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "key-mouse-in-"val;                               \
               signal: "mouse,in";                                     \
               source: "key-bg-"val;                                   \
               script {                                                \
                  if (get_int(mouse_down) == 0)                        \
                     return;                                           \
                  _set_key_pressed(val);                               \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "key-mouse-out-"val;                              \
               signal: "mouse,out";                                    \
               source: "key-bg-"val;                                   \
               script {                                                \
                  if (get_int(mouse_down) == 0)                        \
                     return;                                           \
                  _set_key_released(val);                              \
                  emit("key_up", val);                                 \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "key-mouse-down-"val;                             \
               signal: "mouse,down,1";                                 \
               source: "key-bg-"val;                                   \
               script {                                                \
                  _set_key_pressed(val);                               \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "key-press-"val;                                  \
               action: STATE_SET "down" 0.0;                           \
               target: "key-img-"val;                                  \
               target: "key-lbl-"val;                                  \
            }                                                          \
            program {                                                  \
               name: "key-release-"val;                                \
               action: STATE_SET "default" 0.0;                        \
               transition: LINEAR 0.2;                                 \
               target: "key-img-"val;                                  \
               target: "key-lbl-"val;                                  \
            }                                                          \
         }

#define KEY_SPECIAL_TEXT(val, x, y, w)                                 \
         KEY_SPECIAL(val, x, y, w)                                     \
         part {                                                        \
            name: "key-lbl-"val;                                       \
            type: TEXT;                                                \
            mouse_events: 0;                                           \
            effect: SHADOW BOTTOM;                                     \
            description {                                              \
               state: "default" 0.0;                                   \
               color: 63 67 72 255;                                    \
               color2: 240 240 240 255;                                \
               color3: 240 240 240 255;                                \
               rel1 {                                                  \
                  to: "key-bg-"val;                                    \
                  relative: 0.0 0.4;                                   \
               }                                                       \
               rel2 {                                                  \
                  to: "key-bg-"val;                                    \
                  relative: 1.0 1.0;                                   \
               }                                                       \
               text {                                                  \
                  font: "Semibold";                                    \
                  size: (34*SCALE);                                    \
                  text: val;                                           \
               }                                                       \
            }                                                          \
         }

#define KEY_SPECIAL_ICON(val, x, y, w, icon_size)                      \
         KEY_SPECIAL(val, x, y, w)                                     \
         part {                                                        \
           name: "key-lbl-"val;                                        \
           type: IMAGE;                                                \
           mouse_events: 0;                                            \
           description {                                               \
              state: "default" 0.0;                                    \
              min: icon_size icon_size;                                \
              max: icon_size icon_size;                                \
              fixed: 1 1;                                              \
              rel1 {                                                   \
                 to: "key-bg-"val;                                     \
                 relative: 0.5 0.4;                                    \
              }                                                        \
              rel2 {                                                   \
                 to: "key-bg-"val;                                     \
                 relative: 0.5 0.8;                                    \
              }                                                        \
              image.normal: "icon-"val".png";                          \
            }                                                          \
         }                                                             \

#define FOURTH_ROW THIRD_ROW+KEY_HEIGHT+ROW_SPACE
         KEY_SPECIAL_TEXT("?123", (5*SCALE), FOURTH_ROW, (95*SCALE))

         part {
            name: "key-img-shift";
            type: IMAGE;
            mouse_events: 0;
            description {
               state: "default" 0.0;
               min: (85*SCALE) KEY_HEIGHT;
               max: (85*SCALE) KEY_HEIGHT;
               fixed: 1 1;
               rel1 {
                  relative: 0.0 0.0;
                  offset: (5*SCALE) (THIRD_ROW);
               }
               rel2 {
                  relative: 0.0 0.0;
                  offset: (((5+85)*SCALE)-1) (THIRD_ROW+KEY_HEIGHT-1);
               }
               image {
                  normal: "key-special.png";
                  border: 8 8 10 10;
               }
            }
            description {
               state: "down" 0.0;
               inherit: "default" 0.0;
               rel1.offset: ((5*SCALE)+2) (THIRD_ROW+2);
               rel2.offset: ((((5+85)*SCALE)+2)-1) (THIRD_ROW+2+KEY_HEIGHT-1);
               image.normal: "key-special-pressed.png";
            }
         }
         part {
            name: "key-bg-shift";
            type: RECT;
            pointer_mode: NOGRAB;
            description {
               state: "default" 0.0;
               rel1 {
                  to: "key-img-shift";
                  relative: 0.0 0.0;
                  offset: 3 2;
               }
               rel2 {
                  to: "key-img-shift";
                  relative: 1.0 1.0;
                  offset: -4 -6;
               }
               color: 0 0 0 0;
            }
         }
         part {
           name: "key-lbl-shift";
           type: IMAGE;
           mouse_events: 0;
           description {
              state: "default" 0.0;
              max: (50*SCALE) (50*SCALE);
              min: (50*SCALE) (50*SCALE);
              fixed: 1 1;
              rel1 {
                 to: "key-bg-shift";
                 relative: 0.5 0.4;
              }
              rel2 {
                 to: "key-bg-shift";
                 relative: 0.5 0.8;
              }
              image.normal: "icon-shift.png";
            }
            description {
               state: "down" 0.0;
               inherit: "default" 0.0;
               image.normal: "icon-shift-active.png";
            }
         }
         programs {
            program {
               name: "key-press-shift";
               signal: "mouse,down,1";
               source: "key-bg-shift";
               action: STATE_SET "down" 0.0;
               target: "key-img-shift";
               target: "key-lbl-shift";
            }
            program {
               name: "key-release-shift";
               action: STATE_SET "default" 0.0;
               transition: LINEAR 0.2;
               target: "key-img-shift";
               target: "key-lbl-shift";
            }
            program {
               name: "key-mouse-in-shift";
               signal: "mouse,in";
               source: "key-bg-shift";
               script {
                  if (get_int(mouse_down) == 0)
                     return;
                  run_program(PROGRAM:"key-press-shift");
               }
            }
            program {
               name: "key-mouse-out-shift";
               signal: "mouse,out";
               source: "key-bg-shift";
               script {
                  if (get_int(mouse_down) == 0)
                     return;
                  run_program(PROGRAM:"key-release-shift");
               }
            }
            program {
               name: "key-down-shift";
               signal: "mouse,up,1";
               source: "key-bg-shift";
               script {
                  emit("key_down", "shift");
                  if (get_int(shift_pressed) == 0) {
                     run_program(PROGRAM:"key-press-shift");
                     set_int(shift_pressed, 1);
                  } else {
                     run_program(PROGRAM:"key-release-shift");
                     set_int(shift_pressed, 0);
                  }
               }
            }
         }
      }
   }

   group {
      name: "special-1";

      script {
         MOUSE_DOWN_UP_SCRIPTS
      }
      programs {
         MOUSE_DOWN_UP_PROGRAMS
      }
      parts {
#undef INIT_HSPACE
#define INIT_HSPACE 5

         KEY("1", "#",  KEY_OFFSET(0), FIRST_ROW)
         KEY("2", "&",  KEY_OFFSET(1), FIRST_ROW)
         KEY("3", "%",  KEY_OFFSET(2), FIRST_ROW)
         KEY("4", "+",  KEY_OFFSET(3), FIRST_ROW)
         KEY("5", "=",  KEY_OFFSET(4), FIRST_ROW)
         KEY("6", "_",  KEY_OFFSET(5), FIRST_ROW)
         KEY("7", "\\", KEY_OFFSET(6), FIRST_ROW)
         KEY("8", "|",  KEY_OFFSET(7), FIRST_ROW)
         KEY("9", "<",  KEY_OFFSET(8), FIRST_ROW)
         KEY("0", ">",  KEY_OFFSET(9), FIRST_ROW)

#undef INIT_HSPACE
#define INIT_HSPACE (45*SCALE)

         SKEY("-", "dash",       "{", KEY_OFFSET(0), SECOND_ROW)
         SKEY("@", "at",         "}", KEY_OFFSET(1), SECOND_ROW)
         SKEY("*", "star",       "[", KEY_OFFSET(2), SECOND_ROW)
         SKEY("^", "circumflex", "]", KEY_OFFSET(3), SECOND_ROW)
         SKEY(":", "colon",      "$", KEY_OFFSET(4), SECOND_ROW)
         SKEY(";", "semi_colon", "£", KEY_OFFSET(5), SECOND_ROW)
         SKEY("(", "open_par",   "¥", KEY_OFFSET(6), SECOND_ROW)
         SKEY(")", "close_par",  "€", KEY_OFFSET(7), SECOND_ROW)
         SKEY("~", "tilde",      "₩", KEY_OFFSET(8), SECOND_ROW)

#undef INIT_HSPACE
#define INIT_HSPACE (110*SCALE)

         SKEY("/",  "slash",        "¢", KEY_OFFSET(0), THIRD_ROW)
         SKEY("'",  "single_quote", "`", KEY_OFFSET(1), THIRD_ROW)
         SKEY("\"", "double_quote", "°", KEY_OFFSET(2), THIRD_ROW)
         SKEY(".",  "dot",          "˙", KEY_OFFSET(3), THIRD_ROW)
         SKEY(",",  "comma",        "®", KEY_OFFSET(4), THIRD_ROW)
         SKEY("?",  "question",     "©", KEY_OFFSET(5), THIRD_ROW)
         SKEY("!",  "exclamation",  "¿", KEY_OFFSET(6), THIRD_ROW)

         KEY_SPECIAL_TEXT("1/2", (5*SCALE), THIRD_ROW, (85*SCALE))
         KEY_SPECIAL_TEXT("abc", (5*SCALE), FOURTH_ROW, (95*SCALE))
      }
   }

   group {
      name: "special-2";

      script {
         MOUSE_DOWN_UP_SCRIPTS
      }
      programs {
         MOUSE_DOWN_UP_PROGRAMS
      }
      parts {
#undef INIT_HSPACE
#define INIT_HSPACE 5

         SKEY("#",  "hash",      "1", KEY_OFFSET(0), FIRST_ROW)
         SKEY("&",  "amp",       "2", KEY_OFFSET(1), FIRST_ROW)
         SKEY("%",  "percent",   "3", KEY_OFFSET(2), FIRST_ROW)
         SKEY("+",  "plus",      "4", KEY_OFFSET(3), FIRST_ROW)
         SKEY("=",  "equal",     "5", KEY_OFFSET(4), FIRST_ROW)
         SKEY("_",  "underline", "6", KEY_OFFSET(5), FIRST_ROW)
         SKEY("\\", "backslash", "7", KEY_OFFSET(6), FIRST_ROW)
         SKEY("|",  "vert_bar",  "8", KEY_OFFSET(7), FIRST_ROW)
         SKEY("<",  "less",      "9", KEY_OFFSET(8), FIRST_ROW)
         SKEY(">",  "greater",   "0", KEY_OFFSET(9), FIRST_ROW)

#undef INIT_HSPACE
#define INIT_HSPACE (45*SCALE)

         SKEY("{", "open_brace",    "-", KEY_OFFSET(0), SECOND_ROW)
         SKEY("}", "close_brace",   "@", KEY_OFFSET(1), SECOND_ROW)
         SKEY("[", "open_bracket",  "*", KEY_OFFSET(2), SECOND_ROW)
         SKEY("]", "close_bracket", "^", KEY_OFFSET(3), SECOND_ROW)
         SKEY("$", "dollar",        ":", KEY_OFFSET(4), SECOND_ROW)
         SKEY("£", "sterling",      ";", KEY_OFFSET(5), SECOND_ROW)
         SKEY("¥", "yen",           "(", KEY_OFFSET(6), SECOND_ROW)
         SKEY("€", "euro",          ")", KEY_OFFSET(7), SECOND_ROW)
         SKEY("₩", "won",           "~", KEY_OFFSET(8), SECOND_ROW)

#undef INIT_HSPACE
#define INIT_HSPACE (110*SCALE)

         SKEY("¢", "cent" ,        "/",  KEY_OFFSET(0), THIRD_ROW)
         SKEY("`", "back_quote",   "'",  KEY_OFFSET(1), THIRD_ROW)
         SKEY("°", "ring",         "\"", KEY_OFFSET(2), THIRD_ROW)
         SKEY("˙", "dot",          ".",  KEY_OFFSET(3), THIRD_ROW)
         SKEY("®", "registered",   ",",  KEY_OFFSET(4), THIRD_ROW)
         SKEY("©", "copyright",    "?",  KEY_OFFSET(5), THIRD_ROW)
         SKEY("¿", "inv_question", "!",  KEY_OFFSET(6), THIRD_ROW)

         KEY_SPECIAL_TEXT("2/2", (5*SCALE), THIRD_ROW, (85*SCALE))
         KEY_SPECIAL_TEXT("abc", (5*SCALE), FOURTH_ROW, (95*SCALE))
      }
   }

   group {
      name: "fixed";

#define REPEAT_KEY_SCRIPTS                                             \
         public repeat_timer;                                          \
         public repeat_key;                                            \
                                                                       \
         public _repeat_key(val) {                                     \
            new _cur[20];                                              \
            new _timer;                                                \
            get_str(repeat_key, _cur, 20);                             \
            emit("key_down", _cur);                                    \
            _timer = get_int(repeat_timer);                            \
            if (_timer) {                                              \
               cancel_timer(_timer);                                   \
            }                                                          \
            _timer = timer(0.1, "_repeat_key", 1);                     \
            set_int(repeat_timer, _timer);                             \
         }                                                             \
                                                                       \
         public _repeat_key_pressed(_key[]) {                          \
            new _cur[20];                                              \
            get_str(repeat_key, _cur, 20);                             \
            if (strlen(_cur) > 0) {                                    \
               _repeat_key_released(_cur);                             \
            }                                                          \
            set_str(repeat_key, _key);                                 \
            _repeat_key(1);                                            \
         }                                                             \
                                                                       \
         public _repeat_key_released(_key[]) {                         \
            new _timer;                                                \
            set_str(repeat_key, "");                                   \
            _timer = get_int(repeat_timer);                            \
            if (_timer) {                                              \
               cancel_timer(_timer);                                   \
               set_int(repeat_timer, 0);                               \
            }                                                          \
         }

      script {
         MOUSE_DOWN_UP_SCRIPTS
         REPEAT_KEY_SCRIPTS
      }
      programs {
         MOUSE_DOWN_UP_PROGRAMS
      }

#define KEY_SPECIAL_ICON_REPEAT(val, x, y, w, icon_size)               \
         KEY_SPECIAL_ICON(val, x, y, w, icon_size)                     \
         programs {                                                    \
            program {                                                  \
               name: "long-press-"val;                                 \
               signal: "long_press";                                   \
               source: val;                                            \
               script {                                                \
                  _repeat_key_pressed(val);                            \
               }                                                       \
            }                                                          \
            program {                                                  \
               name: "key-up-"val;                                     \
               signal: "key_up";                                       \
               source: val;                                            \
               script {                                                \
                  _repeat_key_released(val);                           \
               }                                                       \
            }                                                          \
         }

      parts {
         KEY_SPECIAL_ICON_REPEAT("backspace", (620*SCALE), THIRD_ROW, (85*SCALE), (60*SCALE))
         KEY_SPECIAL_ICON("enter", (610*SCALE), FOURTH_ROW, (95*SCALE), (60*SCALE))

#undef INIT_HSPACE
#define INIT_HSPACE (120*SCALE)
         KEY_SPECIAL_ICON_REPEAT("space", KEY_OFFSET(0), FOURTH_ROW, KEY_OFFSET(5), (64*SCALE));
      }
   }

   group {
      name: "numeric";
      script {
         MOUSE_DOWN_UP_SCRIPTS
         REPEAT_KEY_SCRIPTS
      }
      programs {
         MOUSE_DOWN_UP_PROGRAMS
      }
      parts {
#undef KEY_WIDTH
#define KEY_WIDTH (200*SCALE)
#undef KEY_HEIGHT
#define KEY_HEIGHT NUMERIC_KEY_HEIGHT
#undef INIT_HSPACE
#define INIT_HSPACE (45*SCALE)
#undef ROW_SPACE
#define ROW_SPACE (10*SCALE)
#undef COL_SPACE
#define COL_SPACE (10*SCALE)
         KEY("1", " ", KEY_OFFSET(0), FIRST_ROW)
         KEY("2", " ", KEY_OFFSET(1), FIRST_ROW)
         KEY("3", " ", KEY_OFFSET(2), FIRST_ROW)

         KEY("4", " ", KEY_OFFSET(0), SECOND_ROW)
         KEY("5", " ", KEY_OFFSET(1), SECOND_ROW)
         KEY("6", " ", KEY_OFFSET(2), SECOND_ROW)

         KEY("7", " ", KEY_OFFSET(0), THIRD_ROW)
         KEY("8", " ", KEY_OFFSET(1), THIRD_ROW)
         KEY("9", " ", KEY_OFFSET(2), THIRD_ROW)

         KEY_SPECIAL_ICON_REPEAT("backspace", KEY_OFFSET(0), FOURTH_ROW, KEY_WIDTH, (50*SCALE))
         KEY("0", " ", KEY_OFFSET(1), FOURTH_ROW)
         KEY_SPECIAL_ICON("enter", KEY_OFFSET(2), FOURTH_ROW, KEY_WIDTH, (60*SCALE))
      }
   }
}
