
// SPDX-License-Identifier: CC-BY-NC-SA-4.0
//
// Copyright (C) 2026 Bit by Bit Signal Processing LLC (https://bxbsp.com)
//
// This work is placed under the "Creative Commons Attribution
// NonCommercial ShareAlike 4.0 International" license, known
// by the shortened acronym "CC-BY-NC-SA-4.0".
//
// This work 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.
//
// A CC-BY-NC-SA-4.0 license allows you to use this work for
// noncommercial purposes so long as attribution is made to the
// original author.  Modified versions of this work may be distributed,
// but only under the same license.  For further details, see the
// Creative Commons License "CC-BY-NC-SA-4.0".
//
// You should have received a copy of the CC-BY-NC-SA-4.0 license
// along with this work. If not, see
// <https://creativecommons.org/licenses/by-nc-sa/4.0/>.
//

#include "kiosk/window.hh"
#include "kiosk/multiwindow.hh"
#include "kiosk/hotspot.hh"
#include "kiosk/unalingua.hh"

#include "input_demo.hh"
#include "languages.hh"

class input_demo_window : public window
{
  virtual bool handle_event  (my_event& me);
  virtual void draw_dirty    ();
  virtual void draw_dynamic  ();

  const static int pointer_display_interval = 25;
  const static int text_display_interval    = 100;
  int              last_num;
  bool             last_mouse_right;
  bool             last_mouse_left;
  bool             last_mouse_middle;
  int              last_x[MAX_TOUCHES];
  int              last_y[MAX_TOUCHES];
  int              last_count;

  unalingua        last_text;
  int              last_text_count;

public:
  input_demo_window()  { last_count = 0; }
  ~input_demo_window() {}
};

window* create_input_demo_window()
{
  return new input_demo_window();
}

bool input_demo_window::handle_event(my_event& me)
{
  //printf("In input_demo_window::handle_event().  event:\n");
  //print_event(me);

  display* disp = get_display();

  static bool init = true;
  static multilingua kp;
  static multilingua kr;
  static multilingua kh;
  static multilingua kc;
  static multilingua mp;
  static multilingua mr;
  static multilingua mh;
  static multilingua left;
  static multilingua middle;
  static multilingua right;
  static multilingua wu;
  static multilingua wd;
  static multilingua tt;
  static multilingua tr;
  static multilingua th;
  static multilingua thw;
  static multilingua tf;
  
  if(init)
    {
      kp.set_text(U"Key Press", ENGLISH);
      kp.set_text(U"按键", CHINESE_SIMPLE);
      kp.set_text(U"按鍵", CHINESE);
      kp.set_text(U"कुंजी दबाएँ", HINDI);
      kp.set_text(U"Pulsación de tecla", SPANISH);
      kp.set_text(U"Touche enfoncée", FRENCH);
      kp.set_text(U"الضغط على المفتاح", ARABIC);
      kp.set_text(U"কী প্রেস", BENGALI);
      kp.set_text(U"Натискання клавіші", UKRANIAN);
      kp.set_text(U"Pressionar tecla", PORTUGUESE);
      kp.set_text(U"کلید دبائیں۔", URDU);
      kp.set_text(U"Tekan Tombol", INDONESIAN);
      kp.set_text(U"Tastendruck", GERMAN);
      kp.set_text(U"キーを押す", JAPANESE);
      kp.set_text(U"Πάτημα πλήκτρων", GREEK);
      kp.set_text(U"Pressione del tasto", ITALIAN);
      kp.set_text(U"Нажатие клавиши", RUSSIAN);
      kp.set_text(U"לחיצת מקש", HEBREW);

      kr.set_text(U"Key Release", ENGLISH);
      kr.set_text(U"按键释放", CHINESE_SIMPLE);
      kr.set_text(U"按鍵釋放", CHINESE);
      kr.set_text(U"कुंजी रिलीज़", HINDI);
      kr.set_text(U"Liberación de clave", SPANISH);
      kr.set_text(U"Déverrouillage des clés", FRENCH);
      kr.set_text(U"إصدار المفتاح", ARABIC);
      kr.set_text(U"কী রিলিজ", BENGALI);
      kr.set_text(U"Відпускання ключа", UKRANIAN);
      kr.set_text(U"Libertação de chave", PORTUGUESE);
      kr.set_text(U"کلیدی ریلیز", URDU);
      kr.set_text(U"Rilis Kunci", INDONESIAN);
      kr.set_text(U"Schlüsselfreigabe", GERMAN);
      kr.set_text(U"キーリリース", JAPANESE);
      kr.set_text(U"Απελευθέρωση κλειδιού", GREEK);
      kr.set_text(U"Rilascio chiave", ITALIAN);
      kr.set_text(U"Ключевой выпуск", RUSSIAN);
      kr.set_text(U"שחרור מפתח", HEBREW);

      kh.set_text(U"Key Hold count ", ENGLISH);
      kh.set_text(U"按键保持计数", CHINESE_SIMPLE);
      kh.set_text(U"按鍵保持計數", CHINESE);
      kh.set_text(U"कुंजी होल्ड गिनती", HINDI);
      kh.set_text(U"Recuento de retención de claves", SPANISH);
      kh.set_text(U"Nombre de touches maintenues", FRENCH);
      kh.set_text(U"عدد مرات الاحتفاظ بالمفتاح", ARABIC);
      kh.set_text(U"কী হোল্ড কাউন্ট", BENGALI);
      kh.set_text(U"Кількість утримуваних клавіш", UKRANIAN);
      kh.set_text(U"Contagem de teclas premidas", PORTUGUESE);
      kh.set_text(U"کلیدی ہولڈ کی گنتی", URDU);
      kh.set_text(U"Jumlah Penahanan Tombol", INDONESIAN);
      kh.set_text(U"Anzahl der gehaltenen Tasten", GERMAN);
      kh.set_text(U"キーホールド回数", JAPANESE);
      kh.set_text(U"Αριθμός κρατήματος πλήκτρων", GREEK);
      kh.set_text(U"Conteggio delle chiavi in ​​mano", ITALIAN);
      kh.set_text(U"Количество удержаний клавиш", RUSSIAN);
      kh.set_text(U"ספירת החזקות מקשים", HEBREW);

      kc.set_text(U"Key Code", ENGLISH);
      kc.set_text(U"密钥代码", CHINESE_SIMPLE);
      kc.set_text(U"密鑰碼", CHINESE);
      kc.set_text(U"कुंजी कोड", HINDI);
      kc.set_text(U"Código clave", SPANISH);
      kc.set_text(U"Code clé", FRENCH);
      kc.set_text(U"رمز المفتاح", ARABIC);
      kc.set_text(U"কী কোড", BENGALI);
      kc.set_text(U"Ключовий код", UKRANIAN);
      kc.set_text(U"Código-chave", PORTUGUESE);
      kc.set_text(U"کلیدی کوڈ", URDU);
      kc.set_text(U"Kode Kunci", INDONESIAN);
      kc.set_text(U"Schlüsselcode", GERMAN);
      kc.set_text(U"キーコード", JAPANESE);
      kc.set_text(U"Κωδικός κλειδιού", GREEK);
      kc.set_text(U"Codice chiave", ITALIAN);
      kc.set_text(U"Код ключа", RUSSIAN);
      kc.set_text(U"קוד מפתח", HEBREW);

      mp.set_text(U"Mouse Press", ENGLISH);
      mp.set_text(U"鼠标按下", CHINESE_SIMPLE);
      mp.set_text(U"滑鼠按下", CHINESE);
      mp.set_text(U"माउस प्रेस", HINDI);
      mp.set_text(U"Pulsar el ratón", SPANISH);
      mp.set_text(U"Appuyez sur la souris", FRENCH);
      mp.set_text(U"ماوس برس", ARABIC);
      mp.set_text(U"মাউস প্রেস", BENGALI);
      mp.set_text(U"Натисніть мишею", UKRANIAN);
      mp.set_text(U"Pressão do rato", PORTUGUESE);
      mp.set_text(U"ماؤس پریس", URDU);
      mp.set_text(U"Tekan Mouse", INDONESIAN);
      mp.set_text(U"Maus drücken", GERMAN);
      mp.set_text(U"マウスを押す", JAPANESE);
      mp.set_text(U"Πάτημα ποντικιού", GREEK);
      mp.set_text(U"Premere il mouse", ITALIAN);
      mp.set_text(U"Нажатие мыши", RUSSIAN);
      mp.set_text(U"לחיצת עכבר", HEBREW);

      mr.set_text(U"Mouse Release", ENGLISH);
      mr.set_text(U"鼠标释放", CHINESE_SIMPLE);
      mr.set_text(U"滑鼠釋放", CHINESE);
      mr.set_text(U"माउस रिलीज़", HINDI);
      mr.set_text(U"Liberación del ratón", SPANISH);
      mr.set_text(U"Libération de la souris", FRENCH);
      mr.set_text(U"إطلاق الفأرة", ARABIC);
      mr.set_text(U"মাউস রিলিজ", BENGALI);
      mr.set_text(U"Відпускання миші", UKRANIAN);
      mr.set_text(U"Liberação do rato", PORTUGUESE);
      mr.set_text(U"ماؤس کی رہائی", URDU);
      mr.set_text(U"Pelepasan Tikus", INDONESIAN);
      mr.set_text(U"Mausfreigabe", GERMAN);
      mr.set_text(U"マウスリリース", JAPANESE);
      mr.set_text(U"Απελευθέρωση ποντικιού", GREEK);
      mr.set_text(U"Rilascio del topo", ITALIAN);
      mr.set_text(U"Освобождение мыши", RUSSIAN);
      mr.set_text(U"שחרור עכבר", HEBREW);

      mh.set_text(U"Mouse Unmoving Hold", ENGLISH);
      mh.set_text(U"鼠标不动按住", CHINESE_SIMPLE);
      mh.set_text(U"滑鼠不動按住", CHINESE);
      mh.set_text(U"माउस को स्थिर रखें", HINDI);
      mh.set_text(U"Ratón sin moverlo", SPANISH);
      mh.set_text(U"Maintenir la souris immobile", FRENCH);
      mh.set_text(U"الضغط على الماوس دون تحريكه", ARABIC);
      mh.set_text(U"মাউস আনমুভিং হোল্ড", BENGALI);
      mh.set_text(U"Утримання миші нерухомо", UKRANIAN);
      mh.set_text(U"Rato imóvel", PORTUGUESE);
      mh.set_text(U"ماؤس غیر حرکت پذیر ہولڈ", URDU);
      mh.set_text(U"Tahan Mouse Tidak Bergerak", INDONESIAN);
      mh.set_text(U"Maus unbeweglich halten", GERMAN);
      mh.set_text(U"マウスを動かさない", JAPANESE);
      mh.set_text(U"Ποντίκι χωρίς κίνηση", GREEK);
      mh.set_text(U"Mouse fermo", ITALIAN);
      mh.set_text(U"Неподвижное удержание мыши", RUSSIAN);
      mh.set_text(U"הפעלה/כיבוי של עכבר", HEBREW);

      left.set_text(U" Left", ENGLISH);
      left.set_text(U" 左边", CHINESE_SIMPLE);
      left.set_text(U" 左邊", CHINESE);
      left.set_text(U" बाएं", HINDI);
      left.set_text(U" Izquierda", SPANISH);
      left.set_text(U" Gauche", FRENCH);
      left.set_text(U" غادر", ARABIC);
      left.set_text(U" বাম", BENGALI);
      left.set_text(U" Ліворуч", UKRANIAN);
      left.set_text(U" Esquerda", PORTUGUESE);
      left.set_text(U" بائیں", URDU);
      left.set_text(U" Kiri", INDONESIAN);
      left.set_text(U" Links", GERMAN);
      left.set_text(U" 左", JAPANESE);
      left.set_text(U" Αριστερά", GREEK);
      left.set_text(U" Sinistra", ITALIAN);
      left.set_text(U" Левый", RUSSIAN);
      left.set_text(U" שְׁמֹאל", HEBREW);

      middle.set_text(U" Middle", ENGLISH);
      middle.set_text(U" 中间", CHINESE_SIMPLE);
      middle.set_text(U" 中間", CHINESE);
      middle.set_text(U" मध्य", HINDI);
      middle.set_text(U" Medio", SPANISH);
      middle.set_text(U" Milieu", FRENCH);
      middle.set_text(U" وسط", ARABIC);
      middle.set_text(U" মাঝখানে", BENGALI);
      middle.set_text(U" Середній", UKRANIAN);
      middle.set_text(U" Meio", PORTUGUESE);
      middle.set_text(U" درمیانی", URDU);
      middle.set_text(U" Tengah", INDONESIAN);
      middle.set_text(U" Mitte", GERMAN);
      middle.set_text(U" 真ん中", JAPANESE);
      middle.set_text(U" Μέσο", GREEK);
      middle.set_text(U" Mezza", ITALIAN);
      middle.set_text(U" Середина", RUSSIAN);
      middle.set_text(U" אֶמצַע", HEBREW);

      right.set_text(U" Right", ENGLISH);
      right.set_text(U" 正确的", CHINESE_SIMPLE);
      right.set_text(U" 正確的", CHINESE);
      right.set_text(U" सही", HINDI);
      right.set_text(U" Derecha", SPANISH);
      right.set_text(U" Droite", FRENCH);
      right.set_text(U" يمين", ARABIC);
      right.set_text(U" ঠিক", BENGALI);
      right.set_text(U" Праворуч", UKRANIAN);
      right.set_text(U" Certa", PORTUGUESE);
      right.set_text(U" ٹھیک ہے۔", URDU);
      right.set_text(U" Benar", INDONESIAN);
      right.set_text(U" Rechts", GERMAN);
      right.set_text(U" 右", JAPANESE);
      right.set_text(U" Δικαίωμα", GREEK);
      right.set_text(U" Destra", ITALIAN);
      right.set_text(U" Верно", RUSSIAN);
      right.set_text(U" יָמִינָה", HEBREW);

      wu.set_text(U"Wheel Up", ENGLISH);
      wu.set_text(U"向上转动", CHINESE_SIMPLE);
      wu.set_text(U"向上轉動", CHINESE);
      wu.set_text(U"व्हील अप", HINDI);
      wu.set_text(U"Rueda arriba", SPANISH);
      wu.set_text(U"Roue en l'air", FRENCH);
      wu.set_text(U"ارفع العجلة", ARABIC);
      wu.set_text(U"চাকা উপরে", BENGALI);
      wu.set_text(U"Колесо вгору", UKRANIAN);
      wu.set_text(U"Roda para cima", PORTUGUESE);
      wu.set_text(U"وہیل اوپر", URDU);
      wu.set_text(U"Roda Atas", INDONESIAN);
      wu.set_text(U"Rad hoch", GERMAN);
      wu.set_text(U"ホイールアップ", JAPANESE);
      wu.set_text(U"Τροχός προς τα πάνω", GREEK);
      wu.set_text(U"Ruota su", ITALIAN);
      wu.set_text(U"Колесо вверх", RUSSIAN);
      wu.set_text(U"גלגל למעלה", HEBREW);

      wd.set_text(U"Wheel Down", ENGLISH);
      wd.set_text(U"车轮向下", CHINESE_SIMPLE);
      wd.set_text(U"車輪向下", CHINESE);
      wd.set_text(U"नीचे पहिया", HINDI);
      wd.set_text(U"Rueda abajo", SPANISH);
      wd.set_text(U"Roue en bas", FRENCH);
      wd.set_text(U"عجلة لأسفل", ARABIC);
      wd.set_text(U"হুইল ডাউন", BENGALI);
      wd.set_text(U"Колесо вниз", UKRANIAN);
      wd.set_text(U"Roda para baixo", PORTUGUESE);
      wd.set_text(U"وہیل نیچے", URDU);
      wd.set_text(U"Roda Turun", INDONESIAN);
      wd.set_text(U"Rad unten", GERMAN);
      wd.set_text(U"ホイールダウン", JAPANESE);
      wd.set_text(U"Τροχός προς τα κάτω", GREEK);
      wd.set_text(U"Ruota giù", ITALIAN);
      wd.set_text(U"Колесо вниз", RUSSIAN);
      wd.set_text(U"גלגל למטה", HEBREW);

      tt.set_text(U"Touchscreen Touch with", ENGLISH);
      tt.set_text(U"触摸屏触摸", CHINESE_SIMPLE);
      tt.set_text(U"觸控螢幕觸控", CHINESE);
      tt.set_text(U"टचस्क्रीन टच के साथ", HINDI);
      tt.set_text(U"Pantalla táctil táctil con", SPANISH);
      tt.set_text(U"Écran tactile avec", FRENCH);
      tt.set_text(U"شاشة تعمل باللمس مع", ARABIC);
      tt.set_text(U"টাচস্ক্রিন স্পর্শের সাথে", BENGALI);
      tt.set_text(U"Сенсорний екран із сенсорним керуванням", UKRANIAN);
      tt.set_text(U"Ecrã sensível ao toque com", PORTUGUESE);
      tt.set_text(U"ٹچ اسکرین ٹچ کے ساتھ", URDU);
      tt.set_text(U"Layar sentuh sentuh dengan", INDONESIAN);
      tt.set_text(U"Touchscreen-Touch mit", GERMAN);
      tt.set_text(U"タッチスクリーンタッチ", JAPANESE);
      tt.set_text(U"Οθόνη αφής με", GREEK);
      tt.set_text(U"Touchscreen con tocco", ITALIAN);
      tt.set_text(U"Сенсорный экран с сенсорным экраном", RUSSIAN);
      tt.set_text(U"מסך מגע עם", HEBREW);

      
      tr.set_text(U"Touchscreen Release with", ENGLISH);
      tr.set_text(U"触摸屏释放", CHINESE_SIMPLE);
      tr.set_text(U"觸控螢幕釋放", CHINESE);
      tr.set_text(U"टचस्क्रीन रिलीज़ के साथ", HINDI);
      tr.set_text(U"Liberación de la pantalla táctil con", SPANISH);
      tr.set_text(U"Déverrouillage de l'écran tactile avec", FRENCH);
      tr.set_text(U"إصدار شاشة تعمل باللمس مع", ARABIC);
      tr.set_text(U"টাচস্ক্রিন রিলিজ সহ", BENGALI);
      tr.set_text(U"Сенсорний екран звільнення за допомогою", UKRANIAN);
      tr.set_text(U"Libertação do ecrã sensível ao toque com", PORTUGUESE);
      tr.set_text(U"ٹچ اسکرین ریلیز کے ساتھ", URDU);
      tr.set_text(U"Rilis layar sentuh dengan", INDONESIAN);
      tr.set_text(U"Touchscreen-Auslöser mit", GERMAN);
      tr.set_text(U"タッチスクリーンリリース付き", JAPANESE);
      tr.set_text(U"Απελευθέρωση οθόνης αφής με", GREEK);
      tr.set_text(U"Rilascio touchscreen con", ITALIAN);
      tr.set_text(U"Сенсорный экран с функцией разблокировки", RUSSIAN);
      tr.set_text(U"שחרור מסך מגע עם", HEBREW);

      th.set_text(U"Touchscreen Unmoving Hold", ENGLISH);
      th.set_text(U"触摸屏不动", CHINESE_SIMPLE);
      th.set_text(U"觸控螢幕不動", CHINESE);
      th.set_text(U"टचस्क्रीन को स्थिर रखें", HINDI);
      th.set_text(U"Pantalla táctil fija", SPANISH);
      th.set_text(U"Maintien de l'écran tactile immobile", FRENCH);
      th.set_text(U"تثبيت شاشة اللمس دون تحريك", ARABIC);
      th.set_text(U"টাচস্ক্রিন আনমুভিং হোল্ড", BENGALI);
      th.set_text(U"Утримання сенсорного екрана без руху", UKRANIAN);
      th.set_text(U"Ecrã sensível ao toque, retenção imóvel", PORTUGUESE);
      th.set_text(U"ٹچ اسکرین غیر حرکت پذیر ہولڈ", URDU);
      th.set_text(U"Tahan layar sentuh yang tidak bergerak", INDONESIAN);
      th.set_text(U"Touchscreen unbeweglich halten", GERMAN);
      th.set_text(U"タッチスクリーンを動かさずに保持", JAPANESE);
      th.set_text(U"Ακίνητη οθόνη αφής", GREEK);
      th.set_text(U"Touchscreen fermo", ITALIAN);
      th.set_text(U"Неподвижное удержание сенсорного экрана", RUSSIAN);
      th.set_text(U"מסך מגע ביטול הזזה של החזקה", HEBREW);

      thw.set_text(U"with", ENGLISH);
      thw.set_text(U"和", CHINESE_SIMPLE);
      thw.set_text(U"和", CHINESE);
      thw.set_text(U"साथ", HINDI);
      thw.set_text(U"con", SPANISH);
      thw.set_text(U"avec", FRENCH);
      thw.set_text(U"مع", ARABIC);
      thw.set_text(U"সঙ্গে", BENGALI);
      thw.set_text(U"з", UKRANIAN);
      thw.set_text(U"com", PORTUGUESE);
      thw.set_text(U"کے ساتھ", URDU);
      thw.set_text(U"dengan", INDONESIAN);
      thw.set_text(U"mit", GERMAN);
      thw.set_text(U"と", JAPANESE);
      thw.set_text(U"με", GREEK);
      thw.set_text(U"con", ITALIAN);
      thw.set_text(U"с", RUSSIAN);
      thw.set_text(U"עִם", HEBREW);

      tf.set_text(U"finger", ENGLISH);
      tf.set_text(U"手指", CHINESE_SIMPLE);
      tf.set_text(U"手指", CHINESE);
      tf.set_text(U"उँगलिया", HINDI);
      tf.set_text(U"dedo", SPANISH);
      tf.set_text(U"doigt", FRENCH);
      tf.set_text(U"إصبع", ARABIC);
      tf.set_text(U"আঙুল", BENGALI);
      tf.set_text(U"палець", UKRANIAN);
      tf.set_text(U"dedo", PORTUGUESE);
      tf.set_text(U"انگلی", URDU);
      tf.set_text(U"jari", INDONESIAN);
      tf.set_text(U"Finger", GERMAN);
      tf.set_text(U"指", JAPANESE);
      tf.set_text(U"δάχτυλο", GREEK);
      tf.set_text(U"dito", ITALIAN);
      tf.set_text(U"палец", RUSSIAN);
      tf.set_text(U"אֶצבַּע", HEBREW);

      init = false;
    }

  if(me.type == EVENT_KEY_PRESS || me.type == EVENT_KEY_RELEASE || me.type == EVENT_KEY_HOLD)
    {
      if(me.type == EVENT_KEY_PRESS)
	{
	  last_text.set_text((const char32_t*)kp);
	}
      else if(me.type == EVENT_KEY_RELEASE)
	{
	  last_text.set_text((const char32_t*)kr);
	}
      else if(me.type == EVENT_KEY_HOLD)
	{
	  last_text.set_text((const char32_t*)kh);
	  char txt[100];
	  sprintf(txt, " %d", me.count);
	  last_text.append_text(txt);
	}

      char text[100];
      char c = (me.key_ascii==0) ? ' ' : me.key_ascii;
      sprintf(text, " '%c' (ASCII %d, ", c, me.key_ascii);
      last_text.append_text(text);
      last_text.append_text((const char32_t*)kc);
      sprintf(text, " %d)\n", me.key_code);
      last_text.append_text(text);
      last_text_count = text_display_interval;

      return true;
    }
    
  if(me.source_mouse)
    {
      if(me.type == EVENT_TOUCH || me.type == EVENT_RELEASE || me.type == EVENT_HOLD ||
	 me.type == EVENT_MOVE || me.type == EVENT_WHEEL)
	{
	  last_num = 1;

	  last_mouse_right  = !!(me.mouse_buttons_pressed & MOUSE_BUTTON_RIGHT);
	  last_mouse_middle = !!(me.mouse_buttons_pressed & MOUSE_BUTTON_MIDDLE);
	  last_mouse_left   = !!(me.mouse_buttons_pressed & MOUSE_BUTTON_LEFT);

	  last_x[0] = me.c[0].x;
	  last_y[0] = me.c[0].y;

	  window* p = this;
	  while(p)
	    {
	      last_x[0] -= p->offset.x;
	      last_y[0] -= p->offset.y;
	      p = p->parent;
	    }
	  last_count = pointer_display_interval;
	}
      if(me.type == EVENT_TOUCH || me.type == EVENT_RELEASE || me.type == EVENT_HOLD)
	{
	  if(me.type == EVENT_TOUCH)
	    {
	      disp->touch_recognized_beep();
	      claim_events();
	      last_text.set_text((const char32_t*)mp);
	    }
	  else if(me.type == EVENT_RELEASE)
	    {
	      disp->entry_accepted_beep();
	      release_events();
	      last_text.set_text((const char32_t*)mr);
	    }
	  else if(me.type == EVENT_HOLD)
	    {
	      last_text.set_text((const char32_t*)mh);
	      char txt[100];
	      sprintf(txt, " %d", me.count);
	      last_text.append_text(txt);	      
	    }
	  
	  if(me.mouse_buttons_pressed & MOUSE_BUTTON_LEFT)
	    {
	      last_text.append_text((const char32_t*)left);
	    }

	  if(me.mouse_buttons_pressed & MOUSE_BUTTON_MIDDLE)
	    {
	      last_text.append_text((const char32_t*)middle);
	    }
	  
	  if(me.mouse_buttons_pressed & MOUSE_BUTTON_RIGHT)
	    {
	      last_text.append_text((const char32_t*)right);
	    }
	  
	  last_text_count = text_display_interval;
		      
	  return true;
	}
      else if(me.type == EVENT_WHEEL)
	{
	  if(me.count>0)
	    last_text.set_text((const char32_t*)wu);
	  else
	    last_text.set_text((const char32_t*)wd);
	  last_text_count = text_display_interval;
	}
    }
  else
    {
      // Touchscreen event
      if(me.type == EVENT_TOUCH || me.type == EVENT_RELEASE || me.type == EVENT_HOLD ||
	 me.type == EVENT_MOVE || me.type == EVENT_WHEEL)
	{
	  last_num = me.num_touches;
	  last_mouse_right  = false;
	  last_mouse_middle = false;
	  last_mouse_left   = false;
	  for(int i=0; i<last_num; i++)
	    {
	      last_x[i] = me.c[i].x;
	      last_y[i] = me.c[i].y;

	      window* p = this;
	      while(p)
		{
		  last_x[i] -= p->offset.x;
		  last_y[i] -= p->offset.y;
		  p = p->parent;
		}
	    }
	  last_count = pointer_display_interval;
	}
      if(me.type == EVENT_TOUCH || me.type == EVENT_RELEASE || me.type == EVENT_HOLD)
	{
	  if(me.type == EVENT_TOUCH)
	    {
	      disp->touch_recognized_beep();
	      claim_events();
	      last_text.set_text((const char32_t*)tt);
	    }
	  else if(me.type == EVENT_RELEASE)
	    {
	      disp->entry_accepted_beep();
	      release_events();
	      last_text.set_text((const char32_t*)tr);
	    }
	  else if(me.type == EVENT_HOLD)
	    {
	      last_text.set_text((const char32_t*)th);
	      char tmp[100];
	      sprintf(tmp, " %d ", me.count);
	      last_text.append_text(tmp);
	      last_text.append_text((const char32_t*)thw);
	    }
	  
	  char txt[4];
	  txt[0]=' ';
	  txt[1] = '0'+ me.num_touches;
	  txt[2]=' ';
	  txt[3]=0;
	  last_text.append_text(txt);

	  last_text.append_text((const char32_t*)tf);

	  last_text_count = text_display_interval;
	  return true;
	}
    }
  
  return true;  // Event handled
}

void input_demo_window::draw_dynamic()
{
  if(last_text_count)
    {
      last_text_count--;

      color c = scale(WHITE, BLACK, last_text_count / (float) text_display_interval);
      
      set_text_size(height/25);
      draw_text(last_text,
		c,
		width/2,
		height*19/20,
		DRAW_TEXT_X_CENTER|DRAW_TEXT_Y_BOTTOM|DRAW_TEXT_ROTATE_0);
    }
  
  if(last_count)
    {
      last_count--;

      color colors[]   = { WHITE, RED, GREEN, BLUE, ORANGE, BLUEGREEN, PURPLE, YELLOW, GREY };
      int   num_colors = sizeof(colors) / sizeof(colors[0]);
      
      point p0, p1;

      for(int i=0; i<last_num; i++)
	{
	  color c = BLACK;

	  if(last_mouse_left||last_mouse_middle||last_mouse_right)
	    {
	      int red   = last_mouse_left   ? 255 : 0;
	      int green = last_mouse_middle ? 255 : 0;
	      int blue  = last_mouse_right  ? 255 : 0;
	      c = RGB(red, green, blue);
	    }
	  else
	    {
	      c = colors[i%num_colors];
	    }
	  
	  p0.x = 0;
	  p1.x = width;
	  p0.y = last_y[i];
	  p1.y = last_y[i];
	  
	  draw_line_horizontal(p0, p1, c);
	  
	  p0.x = last_x[i];
	  p1.x = last_x[i];
	  p0.y = 0;
	  p1.y = height;
	  draw_line_vertical(p0, p1, c);
	}
    }
}

void input_demo_window::draw_dirty()
{
  last_text_count = 0;
  last_count = 0;

  clear(GREY0);
  
  point p0(0,0);
  point p1(width-1, 0);
  point p2(width-1, height-1);
  point p3(0, height-1);

  draw_line_vertical(p1, p2, GREY7);
  draw_line_vertical(p0, p3, GREY7);
  draw_line_horizontal(p0, p1, GREY7);
  draw_line_horizontal(p2, p3, GREY7);
  
  set_text_size(height/25);

  static bool init = true;

  static multilingua input_demo_window;
  if(init)
    {
      input_demo_window.set_text("Input Demo Window", ENGLISH);
      input_demo_window.set_text(U"输入演示窗口", CHINESE_SIMPLE);
      input_demo_window.set_text(U"輸入演示視窗", CHINESE);
      input_demo_window.set_text(U"इनपुट डेमो विंडो", HINDI);
      input_demo_window.set_text(U"Ventana de demostración de entrada", SPANISH);
      input_demo_window.set_text(U"Fenêtre de démonstration d'entrée", FRENCH);
      input_demo_window.set_text(U"نافذة العرض التوضيحي للإدخال", ARABIC);
      input_demo_window.set_text(U"ইনপুট ডেমো উইন্ডো", BENGALI);
      input_demo_window.set_text(U"Демонстраційне вікно введення", UKRANIAN);
      input_demo_window.set_text(U"Janela de demonstração de entrada", PORTUGUESE);
      input_demo_window.set_text(U"ان پٹ ڈیمو ونڈو", URDU);
      input_demo_window.set_text(U"Jendela Demo Input", INDONESIAN);
      input_demo_window.set_text(U"Eingabe-Demofenster", GERMAN);
      input_demo_window.set_text(U"入力デモウィンドウ", JAPANESE);
      input_demo_window.set_text(U"Εισαγωγή παραθύρου επίδειξης", GREEK);
      input_demo_window.set_text(U"Finestra demo di input", ITALIAN);
      input_demo_window.set_text(U"Окно демонстрации ввода", RUSSIAN);
      input_demo_window.set_text(U"חלון הדגמת קלט", HEBREW);
    }
  
  draw_text(input_demo_window,
	    WHITE,
	    width/2,
	    height*1/20,
	    DRAW_TEXT_X_CENTER|DRAW_TEXT_Y_TOP|DRAW_TEXT_ROTATE_0);

  set_text_size(height/40);

  color c = GREY5;
  static multilingua txt1;
  if(init)
    {
      txt1.set_text("This window prints events from touchscreen, mouse, and keyboard.", ENGLISH);
      txt1.set_text(U"此窗口打印来自触摸屏、鼠标和键盘的事件。", CHINESE_SIMPLE);
      txt1.set_text(U"此視窗列印來自觸控螢幕、滑鼠和鍵盤的事件。", CHINESE);
      txt1.set_text(U"यह विंडो टचस्क्रीन, माउस और कीबोर्ड से घटनाओं को प्रिंट करती है।", HINDI);
      txt1.set_text(U"Esta ventana imprime eventos de la pantalla táctil, el mouse y el teclado.", SPANISH);
      txt1.set_text(U"Cette fenêtre imprime les événements provenant de l'écran tactile, de la souris et du clavier.", FRENCH);
      txt1.set_text(U"تقوم هذه النافذة بطباعة الأحداث من شاشة اللمس، والماوس، ولوحة المفاتيح.", ARABIC);
      txt1.set_text(U"এই উইন্ডোটি টাচস্ক্রিন, মাউস এবং কীবোর্ড থেকে ইভেন্ট প্রিন্ট করে।", BENGALI);
      txt1.set_text(U"Це вікно друкує події із сенсорного екрана, миші та клавіатури.", UKRANIAN);
      txt1.set_text(U"Esta janela imprime eventos do ecrã táctil, rato e teclado.", PORTUGUESE);
      txt1.set_text(U"یہ ونڈو ٹچ اسکرین، ماؤس اور کی بورڈ سے واقعات کو پرنٹ کرتی ہے۔", URDU);
      txt1.set_text(U"Jendela ini mencetak kejadian dari layar sentuh, tetikus, dan papan ketik.", INDONESIAN);
      txt1.set_text(U"Dieses Fenster druckt Ereignisse von Touchscreen, Maus und Tastatur.", GERMAN);
      txt1.set_text(U"このウィンドウは、タッチスクリーン、マウス、キーボードからのイベントを出力します。", JAPANESE);
      txt1.set_text(U"Αυτό το παράθυρο εκτυπώνει συμβάντα από την οθόνη αφής, το ποντίκι και το πληκτρολόγιο.", GREEK);
      txt1.set_text(U"Questa finestra stampa gli eventi provenienti da touchscreen, mouse e tastiera.", ITALIAN);
      txt1.set_text(U"В этом окне выводятся события с сенсорного экрана, мыши и клавиатуры.", RUSSIAN);
      txt1.set_text(U"חלון זה מדפיס אירועים ממסך מגע, עכבר ומקלדת.", HEBREW);
    }
  
  draw_text(txt1,
	    c,
	    width/2,
	    height*3/20,
	    DRAW_TEXT_X_CENTER|DRAW_TEXT_Y_TOP|DRAW_TEXT_ROTATE_0);

  static multilingua txt2;
  if(init)
    {
      txt2.set_text("Touchscreen events are n-finger touch, hold, release.", ENGLISH);
      txt2.set_text(U"触摸屏事件包括 n 指触摸、按住、释放。", CHINESE_SIMPLE);
      txt2.set_text(U"觸控螢幕事件包括 n 指觸控、按住、釋放。", CHINESE);
      txt2.set_text(U"टचस्क्रीन इवेंट एन-फिंगर टच, होल्ड, रिलीज हैं।", HINDI);
      txt2.set_text(U"Los eventos de la pantalla táctil son tocar, mantener y soltar con n dedos.", SPANISH);
      txt2.set_text(U"Les événements de l'écran tactile sont les suivants : toucher, maintenir et relâcher avec n doigts.", FRENCH);
      txt2.set_text(U"أحداث شاشة اللمس هي اللمس باستخدام n إصبع، ثم الضغط باستمرار، ثم الإطلاق.", ARABIC);
      txt2.set_text(U"টাচস্ক্রিন ইভেন্টগুলি হল n-আঙুল দিয়ে স্পর্শ করা, ধরে রাখা, ছেড়ে দেওয়া।", BENGALI);
      txt2.set_text(U"Події сенсорного екрана – це дотик, утримання, відпускання n пальцями.", UKRANIAN);
      txt2.set_text(U"Os eventos do ecrã táctil são tocar com n dedos, segurar e largar.", PORTUGUESE);
      txt2.set_text(U"ٹچ اسکرین ایونٹس این فنگر ٹچ، ہولڈ، ریلیز ہیں۔", URDU);
      txt2.set_text(U"Peristiwa layar sentuh adalah menyentuh, menahan, dan melepaskan dengan n jari.", INDONESIAN);
      txt2.set_text(U"Touchscreen-Ereignisse sind Berühren, Halten und Loslassen mit 2 Fingern.", GERMAN);
      txt2.set_text(U"タッチスクリーン イベントは、n 本指のタッチ、ホールド、リリースです。", JAPANESE);
      txt2.set_text(U"Τα συμβάντα της οθόνης αφής είναι άγγιγμα, κράτημα και απελευθέρωση με n δάχτυλα.", GREEK);
      txt2.set_text(U"Gli eventi del touchscreen sono tocco, pressione, rilascio con n dita.", ITALIAN);
      txt2.set_text(U"События сенсорного экрана — касание несколькими пальцами, удержание и отпускание.", RUSSIAN);
      txt2.set_text(U"אירועי מסך מגע הם נגיעה, החזקה ושחרור עם n אצבעות.", HEBREW);
    }
  draw_text(txt2,
	    c,
	    width/2,
	    height*32/80,
	    DRAW_TEXT_X_CENTER|DRAW_TEXT_Y_TOP|DRAW_TEXT_ROTATE_0);

  static multilingua txt3;
  if(init)
    {
      txt3.set_text("Changes in the number of fingers terminates the event.", ENGLISH);
      txt3.set_text(U"手指数量的变化会终止事件。", CHINESE_SIMPLE);
      txt3.set_text(U"手指數量的變化會終止事件。", CHINESE);
      txt3.set_text(U"उंगलियों की संख्या में परिवर्तन से घटना समाप्त हो जाती है।", HINDI);
      txt3.set_text(U"Los cambios en el número de dedos finalizan el evento.", SPANISH);
      txt3.set_text(U"Les changements dans le nombre de doigts mettent fin à l'événement.", FRENCH);
      txt3.set_text(U"يؤدي تغيير عدد الأصابع إلى إنهاء الحدث.", ARABIC);
      txt3.set_text(U"আঙুলের সংখ্যা পরিবর্তন করলে ঘটনাটি শেষ হয়ে যায়।", BENGALI);
      txt3.set_text(U"Зміна кількості пальців завершує подію.", UKRANIAN);
      txt3.set_text(U"As alterações no número de dedos terminam o evento.", PORTUGUESE);
      txt3.set_text(U"انگلیوں کی تعداد میں تبدیلی واقعہ کو ختم کر دیتی ہے۔", URDU);
      txt3.set_text(U"Perubahan pada jumlah jari akan mengakhiri acara.", INDONESIAN);
      txt3.set_text(U"Eine Änderung der Fingeranzahl beendet die Veranstaltung.", GERMAN);
      txt3.set_text(U"指の数が変わるとイベントは終了します。", JAPANESE);
      txt3.set_text(U"Οι αλλαγές στον αριθμό των δακτύλων τερματίζουν το συμβάν.", GREEK);
      txt3.set_text(U"Le modifiche nel numero di dita interrompono l'evento.", ITALIAN);
      txt3.set_text(U"Изменение количества пальцев прекращает событие.", RUSSIAN);
      txt3.set_text(U"שינויים במספר האצבעות מסיימים את האירוע.", HEBREW);
    }
  draw_text(txt3,
	    c,
	    width/2,
	    height*35/80,
	    DRAW_TEXT_X_CENTER|DRAW_TEXT_Y_TOP|DRAW_TEXT_ROTATE_0);

  static multilingua txt4;
  if(init)
    {
      txt4.set_text("Mouse events are button down, hold, release, move, and wheel.", ENGLISH);
      txt4.set_text(U"鼠标事件包括按下、按住、释放、移动和滚轮。", CHINESE_SIMPLE);
      txt4.set_text(U"滑鼠事件包括按下、按住、釋放、移動和滾輪。", CHINESE);
      txt4.set_text(U"माउस इवेंट हैं बटन डाउन, होल्ड, रिलीज, मूव और व्हील।", HINDI);
      txt4.set_text(U"Los eventos del mouse son presionar un botón, mantener presionado, soltar, mover y rueda.", SPANISH);
      txt4.set_text(U"Les événements de la souris sont les suivants : bouton enfoncé, maintenir, relâcher, déplacer et molette.", FRENCH);
      txt4.set_text(U"أحداث الماوس هي الضغط على الزر، والضغط باستمرار، والإفراج، والتحريك، والعجلة.", ARABIC);
      txt4.set_text(U"মাউস ইভেন্টগুলি হল বোতাম ডাউন, ধরে রাখা, ছেড়ে দেওয়া, সরানো এবং চাকা।", BENGALI);
      txt4.set_text(U"Події миші – це натискання кнопки, утримання, відпускання, переміщення та обертання колеса.", UKRANIAN);
      txt4.set_text(U"Os eventos do rato são: botão premido, segurar, largar, mover e roda.", PORTUGUESE);
      txt4.set_text(U"ماؤس کے واقعات بٹن ڈاون، ہولڈ، ریلیز، حرکت، اور وہیل ہیں۔", URDU);
      txt4.set_text(U"Peristiwa yang terjadi pada mouse adalah menekan tombol, menahan, melepas, menggerakkan, dan memutar.", INDONESIAN);
      txt4.set_text(U"Mausereignisse sind Taste drücken, gedrückt halten, loslassen, bewegen und Rad.", GERMAN);
      txt4.set_text(U"マウス イベントは、ボタンの押下、押したままにする、放す、移動、ホイールです。", JAPANESE);
      txt4.set_text(U"Τα συμβάντα του ποντικιού είναι το πάτημα ενός κουμπιού, το κράτημα, η απελευθέρωση, η μετακίνηση και ο τροχός.", GREEK);
      txt4.set_text(U"Gli eventi del mouse sono: pressione del pulsante, pressione prolungata, rilascio, spostamento e rotellina.", ITALIAN);
      txt4.set_text(U"События мыши — нажатие кнопки, удержание, отпускание, перемещение и прокрутка колеса.", RUSSIAN);
      txt4.set_text(U"אירועי עכבר הם לחיצה על כפתור (button-down), לחיצה על העכבר (hold), שחרור (release), לחיצה על הזזה (move) ולחיצה על גלגל (wheel).", HEBREW);
    }
  draw_text(txt4,
	    c,
	    width/2,
	    height*43/80,
	    DRAW_TEXT_X_CENTER|DRAW_TEXT_Y_TOP|DRAW_TEXT_ROTATE_0);

  static multilingua txt5;
  if(init)
    {
      txt5.set_text("Keyboard events are press, release, and hold.", ENGLISH);
      txt5.set_text(U"键盘事件包括按下、释放和按住。", CHINESE_SIMPLE);
      txt5.set_text(U"鍵盤事件包括按下、釋放和按住。", CHINESE);
      txt5.set_text(U"कीबोर्ड इवेंट हैं प्रेस, रिलीज़ और होल्ड।", HINDI);
      txt5.set_text(U"Los eventos del teclado son presionar, soltar y mantener presionado.", SPANISH);
      txt5.set_text(U"Les événements du clavier sont appuyer, relâcher et maintenir.", FRENCH);
      txt5.set_text(U"أحداث لوحة المفاتيح هي الضغط والإفراج والاستمرار.", ARABIC);
      txt5.set_text(U"কীবোর্ড ইভেন্টগুলি হল প্রেস, রিলিজ এবং হোল্ড।", BENGALI);
      txt5.set_text(U"Події клавіатури - це натискання, відпускання та утримання.", UKRANIAN);
      txt5.set_text(U"Os eventos do teclado são pressionar, soltar e segurar.", PORTUGUESE);
      txt5.set_text(U"کی بورڈ ایونٹس پریس، ریلیز اور ہولڈ ہیں۔", URDU);
      txt5.set_text(U"Peristiwa pada keyboard adalah menekan, melepas, dan menahan.", INDONESIAN);
      txt5.set_text(U"Tastaturereignisse sind Drücken, Loslassen und Halten.", GERMAN);
      txt5.set_text(U"キーボード イベントは、押す、離す、保持するです。", JAPANESE);
      txt5.set_text(U"Τα συμβάντα πληκτρολογίου είναι το πάτημα, η απελευθέρωση και η παρατεταμένη απελευθέρωση.", GREEK);
      txt5.set_text(U"Gli eventi della tastiera sono premere, rilasciare e tenere premuto.", ITALIAN);
      txt5.set_text(U"События клавиатуры — нажатие, отпускание и удержание.", RUSSIAN);
      txt5.set_text(U"אירועי מקלדת הם לחיצה, שחרור והחזקה.", HEBREW);
    }
  draw_text(txt5,
	    c,
	    width/2,
	    height*51/80,
	    DRAW_TEXT_X_CENTER|DRAW_TEXT_Y_TOP|DRAW_TEXT_ROTATE_0);


  static multilingua txt6;
  if(init)
    {
      txt6.set_text("The web interface doesn't support hold events.", ENGLISH);
      txt6.set_text(U"网络界面不支持保持事件。", CHINESE_SIMPLE);
      txt6.set_text(U"網路介面不支援保持事件。", CHINESE);
      txt6.set_text(U"वेब इंटरफ़ेस होल्ड इवेंट का समर्थन नहीं करता है।", HINDI);
      txt6.set_text(U"La interfaz web no admite eventos de retención.", SPANISH);
      txt6.set_text(U"L'interface Web ne prend pas en charge les événements de mise en attente.", FRENCH);
      txt6.set_text(U"لا تدعم واجهة الويب أحداث التعليق.", ARABIC);
      txt6.set_text(U"ওয়েব ইন্টারফেস ইভেন্ট হোল্ড সমর্থন করে না।", BENGALI);
      txt6.set_text(U"Веб-інтерфейс не підтримує події утримання.", UKRANIAN);
      txt6.set_text(U"A interface web não suporta eventos de espera.", PORTUGUESE);
      txt6.set_text(U"ویب انٹرفیس انعقاد کے واقعات کی حمایت نہیں کرتا ہے۔", URDU);
      txt6.set_text(U"Antarmuka web tidak mendukung acara penahanan.", INDONESIAN);
      txt6.set_text(U"Die Weboberfläche unterstützt keine Halteereignisse.", GERMAN);
      txt6.set_text(U"Web インターフェースは保留イベントをサポートしていません。", JAPANESE);
      txt6.set_text(U"Η διεπαφή ιστού δεν υποστηρίζει συμβάντα διατήρησης.", GREEK);
      txt6.set_text(U"L'interfaccia web non supporta gli eventi di attesa.", ITALIAN);
      txt6.set_text(U"Веб-интерфейс не поддерживает события удержания.", RUSSIAN);
      txt6.set_text(U"ממשק האינטרנט אינו תומך באירועי עצירה.", HEBREW);
    }
  draw_text(txt6,
	    c,
	    width/2,
	    height*59/80,
	    DRAW_TEXT_X_CENTER|DRAW_TEXT_Y_TOP|DRAW_TEXT_ROTATE_0);

  init = false;
}

