(*~\Глагол\Отделы\Обмен\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                            ОТДЕЛ Окно;
(*============================================================================*)
(* НАЗНАЧЕНИЕ: ввод и вывод текста на графическое или консольное окно         *)
(*============================================================================*)

ИСПОЛЬЗУЕТ 
  ЦвЗнак,
  Ввод,
  ГОС,
  КОС;
                             (* ссылка на соответствующие задачи из ГОС и КОС *)
ПЕР
  ПисатьЦвет-        :ЗАДАЧА(с,к:ЦЕЛ; цвет:ЗНАК);
  ПисатьЗнак-        :ЗАДАЧА(с,к:ЦЕЛ; цвет:ЗНАК);
  ЧитатьЦвет-        :ЗАДАЧА(с,к:ЦЕЛ):ЗНАК;
  ЧитатьЗнак-        :ЗАДАЧА(с,к:ЦЕЛ):ЗНАК;
  Вверх-             :ЗАДАЧА(вс,лк,нс,пк:ЦЕЛ; новЗнак-:ЦвЗнак.Вид);
  Вниз-              :ЗАДАЧА(вс,лк,нс,пк:ЦЕЛ; новЗнак-:ЦвЗнак.Вид);
  ПисатьСтроку-      :ЗАДАЧА(цвСтрока-:ЦвЗнак.РядСтрока; с,к,длина:ЦЕЛ);
  ПереместитьУказку- :ЗАДАЧА(с,к:ЦЕЛ);
  РазмерУказки-      :ЗАДАЧА(размер:ЦЕЛ);
  Опрос-             :ЗАДАЧА(отКлавиш+:Ввод.нОтКлавиш; отМышки+:Ввод.нОтМышки):ЦЕЛ;
  РазмерЭкрана-      :ЗАДАЧА(строк+,колонок+:ЦЕЛ);
  ИзменитьРазмер-    :ЗАДАЧА(строк,колонок:ЦЕЛ);
  СоздатьЧасы-       :ЗАДАЧА(номер,время:ЦЕЛ):ЦЕЛ;
  УдалитьЧасы-       :ЗАДАЧА(номерУд:ЦЕЛ);
  Показать-          :ЗАДАЧА;
  Отработать-        :ЗАДАЧА;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Графическое-(
                     имяПриложения-,
                         имяШрифта-:ЦЕПЬ;
                      размерШрифта :ЦЕЛ;
                        задачаЧасы :ГОС.зЧасы (*ВидЗадачиЧасы*)
                   );
(*
 * Цель:  подготовка к работе графического окна
 *)
УКАЗ
  ПисатьЦвет       :=ГОС.ПисатьЦвет;
  ПисатьЗнак       :=ГОС.ПисатьЗнак;
  ЧитатьЦвет       :=ГОС.ЧитатьЦвет;
  ЧитатьЗнак       :=ГОС.ЧитатьЗнак;
  Вверх            :=ГОС.Вверх;
  Вниз             :=ГОС.Вниз;
  ПисатьСтроку     :=ГОС.ПисатьСтроку;
  ПереместитьУказку:=ГОС.ПереместитьУказку;
  РазмерУказки     :=ГОС.РазмерУказки;
  Опрос            :=ГОС.Опрос;
  РазмерЭкрана     :=ГОС.РазмерЭкрана;
  ИзменитьРазмер   :=ГОС.ИзменитьРазмерОкна;
  СоздатьЧасы      :=ГОС.СоздатьЧасы;
  УдалитьЧасы      :=ГОС.УдалитьЧасы; 
  Показать         :=ГОС.ПоказатьОкно; 
  Отработать       :=ГОС.Отработать; 

  ГОС.Подготовить(имяПриложения,имяШрифта,размерШрифта,задачаЧасы)

КОН Графическое;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Текстовое-(
                        задачаЧасы :КОС.зЧасы (*ВидЗадачиЧасы*)
                 );
(*
 * Цель:  подготовка к работе консольного окна
 *)
УКАЗ
  ПисатьЦвет       :=КОС.ПисатьЦвет;
  ПисатьЗнак       :=КОС.ПисатьЗнак;
  ЧитатьЦвет       :=КОС.ЧитатьЦвет;
  ЧитатьЗнак       :=КОС.ЧитатьЗнак;
  Вверх            :=КОС.Вверх;
  Вниз             :=КОС.Вниз;
  ПисатьСтроку     :=КОС.ПисатьСтроку;
  ПереместитьУказку:=КОС.ПереместитьУказку;
  РазмерУказки     :=КОС.РазмерУказки;
  Опрос            :=КОС.Опрос;
  РазмерЭкрана     :=КОС.РазмерЭкрана;
  ИзменитьРазмер   :=КОС.ИзменитьРазмерОкна;
  СоздатьЧасы      :=КОС.СоздатьЧасы;
  УдалитьЧасы      :=КОС.УдалитьЧасы; 
  Показать         :=КОС.ПоказатьОкно; 
  Отработать       :=КОС.Отработать; 

  КОС.Подготовить(задачаЧасы)

КОН Текстовое;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Пробел-(
                вс,
                лк,
                нс,
                пк :ЦЕЛ
              );                          (* Заполняет прямоугольник пробелом *)

(*----------------------------------- Вывод.Пробел() -------------------------
ЗАДАЧА Пробел-(x0,y0,x1,y1:ЦЕЛ);
                                          (* Заполняет прямоугольник пробелом *)
ПЕР
  x,y:ЦЕЛ;
УКАЗ
  y:=y0;
  ПОКА y <= y1 ВЫП
    x:=x0;
    ПОКА x <= x1 ВЫП
      ОС.ПисатьЗнак(x,y,' ');
      УВЕЛИЧИТЬ(x)
    КОН;
    УВЕЛИЧИТЬ(y)
  КОН
КОН Пробел;
*)
ПЕР
     с,к:ЦЕЛ;
УКАЗ
  ОТ с:=вс ДО нс ВЫП
    ОТ к:=лк ДО пк ВЫП
      Окно.ПисатьЗнак(с,к,' ')
    КОН
  КОН
КОН Пробел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Цвет-(
                вс,
                лк,
                нс,
                пк :ЦЕЛ;
              цвет :ЗНАК
            );                           (* Устанавливает цвет прямоугольника *)

(*----------------------------------- Вывод.Цвет() --------------------------
ЗАДАЧА Цвет-(x0,y0,x1,y1,цвет:ЦЕЛ);
                                         (* Устанавливает цвет прямоугольника *)
ПЕР
  x,y:ЦЕЛ;
УКАЗ
  y:=y0;
  ПОКА y <= y1 ВЫП
    x:=x0;
    ПОКА x <= x1 ВЫП
      ОС.ПисатьЦвет(x,y,цвет);
      УВЕЛИЧИТЬ(x)
    КОН;
    УВЕЛИЧИТЬ(y)
  КОН
КОН Цвет;
*)
ПЕР
     с,к:ЦЕЛ;
УКАЗ
  ОТ с:=вс ДО нс ВЫП
    ОТ к:=лк ДО пк ВЫП
      Окно.ПисатьЦвет(с,к,цвет)
    КОН
  КОН
КОН Цвет;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЦветнойПробел-(
               вс,
               лк,
               нс,
               пк :ЦЕЛ;
             цвет :ЗНАК); (* Заполняет прямоугольник пробелом заданного цвета *)
ПЕР
  строка:ЦвЗнак.РядСтрока;
  пробел:ЦвЗнак.Вид; 
  с,к,пко:ЦЕЛ;
УКАЗ
  пробел.знак:=" ";
  пробел.цвет:=цвет;
  пко:=пк-лк;

  ОТ к:=0 ДО пко ВЫП
    строка[к]:=пробел
  КОН;
  ОТ с:=вс ДО нс ВЫП
    Окно.ПисатьСтроку(строка,с,лк,пко+1)
  КОН
КОН ЦветнойПробел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Тень-(
               вс,
               лк,
               нс,
               пк:ЦЕЛ
            );                          (* Снаружи прямоугольника рисует тень *)
ПЕР
  с,к:ЦЕЛ;

 (*........................подЗадача..*)
  ЗАДАЧА Потушить(с,к:ЦЕЛ);
  УКАЗ
    ПисатьЦвет(с,к,ВЗНАК(ВЦЕЛ(ЧитатьЦвет(с,к)) ОСТАТОК 8))
  КОН Потушить;
   
УКАЗ
  УВЕЛИЧИТЬ(пк);
  УВЕЛИЧИТЬ(нс);

  ОТ с:=вс+1 ДО нс ВЫП
    Потушить(с,пк)
  КОН;
  ОТ к:=лк+1 ДО пк ВЫП
    Потушить(нс,к)
  КОН
КОН Тень;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Рамка1-(
               вс,
               лк,
               нс,
               пк:ЦЕЛ
              );                  (* Обрамляет прямоугольник одинарной линией *)
ПЕР
  с,к:ЦЕЛ;
УКАЗ
    Окно.ПисатьЗнак(вс,лк,250CX);
    Окно.ПисатьЗнак(нс,лк,2514X);
    Окно.ПисатьЗнак(вс,пк,2510X);
    Окно.ПисатьЗнак(нс,пк,2518X);

  ОТ к:=лк+1 ДО пк-1 ВЫП
    Окно.ПисатьЗнак(вс,к,2500X);
    Окно.ПисатьЗнак(нс,к,2500X)
  КОН;
  ОТ с:=вс+1 ДО нс-1 ВЫП
    Окно.ПисатьЗнак(с,лк,2502X);
    Окно.ПисатьЗнак(с,пк,2502X)
  КОН
КОН Рамка1;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Рамка2-(
               вс,
               лк,
               нс,
               пк:ЦЕЛ
              );                    (* Обрамляет прямоугольник двойной линией *)

(*----------------------------------- Вывод.Рамка() --------------------------
ЗАДАЧА Рамка-(x0,y0,x1,y1:ЦЕЛ);
                                    (* Обрамляет прямоугольник двойной линией *)
ПЕР
  x,y:ЦЕЛ;
УКАЗ
    ОС.ПисатьЗнак(x0,y0,0C9X);
    ОС.ПисатьЗнак(x0,y1,0C8X);
    ОС.ПисатьЗнак(x1,y0,0BBX);
    ОС.ПисатьЗнак(x1,y1,0BCX);
       x:=x0+1;
  ПОКА x < x1 ВЫП
    ОС.ПисатьЗнак(x,y0,0CDX);
    ОС.ПисатьЗнак(x,y1,0CDX);
    УВЕЛИЧИТЬ(x)
  КОН;
  y:=y0+1;
  ПОКА y < y1 ВЫП
    ОС.ПисатьЗнак(x0,y,0BAX);
    ОС.ПисатьЗнак(x1,y,0BAX);
    УВЕЛИЧИТЬ(y)
  КОН
КОН Рамка;
*)
ПЕР
  с,к:ЦЕЛ;
УКАЗ
  Окно.ПисатьЗнак(вс,лк,2554X);
  Окно.ПисатьЗнак(нс,лк,255AX);
  Окно.ПисатьЗнак(вс,пк,2557X);
  Окно.ПисатьЗнак(нс,пк,255DX);

  ОТ к:=лк+1 ДО пк-1 ВЫП
    Окно.ПисатьЗнак(вс,к,2550X);
    Окно.ПисатьЗнак(нс,к,2550X)
  КОН;
  ОТ с:=вс+1 ДО нс-1 ВЫП
    Окно.ПисатьЗнак(с,лк,2551X);
    Окно.ПисатьЗнак(с,пк,2551X)
  КОН
КОН Рамка2;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Чёрточка-(
               вс,
               лк,
               нс,
               пк:ЦЕЛ
                );            (* Рисует горизонтальную или вертикальную черту,
                                                         учитывая пересечения *)

(*----------------------------------- Вывод.Черта() --------------------------
ЗАДАЧА Черта-(x0,y0,x1,y1:ЦЕЛ);
(* Рисует горизонтальную или вертикальную черту, учитывая пересечения. *)
ПЕР
  x,y:ЦЕЛ;
  зн:ЗНАК;
УКАЗ
  ЕСЛИ
       y0 = y1
  ТО                            (* горизонтальная черта *)
    зн:=ОС.ЧитатьЗнак(x0,y0);
    ЕСЛИ  зн = 0B3X ТО 
      зн:=0C3X
    АЕСЛИ зн = 0BAX ТО 
      зн:=0C7X
    ИНАЧЕ
      зн:=0C4X
    КОН;
    ОС.ПисатьЗнак(x0,y0,зн);
    x:=x0+1;
    ПОКА x < x1 ВЫП
      зн:=ОС.ЧитатьЗнак(x,y0);
      ЕСЛИ  зн = 0B3X ТО 
        зн:=0C5X
      АЕСЛИ зн = 0BAX ТО 
        зн:=0D7X
      ИНАЧЕ
        зн:=0C4X
      КОН;
      ОС.ПисатьЗнак(x,y0,зн);
      УВЕЛИЧИТЬ(x)
    КОН;
    зн:=ОС.ЧитатьЗнак(x1,y1);
    ЕСЛИ  зн = 0B3X ТО 
      зн:=0B4X
    АЕСЛИ зн = 0BAX ТО 
      зн:=0B6X
    ИНАЧЕ
      зн:=0C4X
    КОН;
    ОС.ПисатьЗнак(x1,y1,зн);
  ИНАЧЕ                             (* вертикальная черта *)
    зн:=ОС.ЧитатьЗнак(x0,y0);
    ЕСЛИ  зн = 0C4X ТО 
      зн:=0C2X
    АЕСЛИ зн = 0CDX ТО 
      зн:=0D1X
    ИНАЧЕ
      зн:=0B3X
    КОН;
    ОС.ПисатьЗнак(x0,y0,зн);
    y:=y0+1;
    ПОКА y < y1 ВЫП
      зн:=ОС.ЧитатьЗнак(x0,y);
      ЕСЛИ  зн = 0C4X ТО 
        зн:=0C5X
      АЕСЛИ зн = 0CDX ТО 
        зн:=0D8X
      ИНАЧЕ
        зн:=0B3X
      КОН;
      ОС.ПисатьЗнак(x0,y,зн);
      УВЕЛИЧИТЬ(y)
    КОН;
    зн:=ОС.ЧитатьЗнак(x1,y1);
    ЕСЛИ  зн = 0C4X ТО 
      зн:=0C1X
    АЕСЛИ зн = 0CDX ТО 
      зн:=0CFX
    ИНАЧЕ
      зн:=0B3X
    КОН;
    ОС.ПисатьЗнак(x1,y1,зн);
  КОН
КОН Черта;
*)
ПЕР
  с,к:ЦЕЛ;
  зн:ЗНАК;
УКАЗ
  ЕСЛИ
       вс = нс
  ТО                            (* горизонтальная черта *)
    зн:=Окно.ЧитатьЗнак(вс,лк);
    ЕСЛИ
         зн = 2502X
    ТО 
         зн:=251CX
    АЕСЛИ
         зн = 2551X
    ТО 
         зн:=255FX
    ИНАЧЕ
         зн:=2500X
    КОН;
    Окно.ПисатьЗнак(вс,лк,зн);

    ОТ к:=лк+1 ДО пк-1 ВЫП
           зн:=ЧитатьЗнак(вс,к);
      ЕСЛИ
           зн = 2502X
      ТО 
           зн:=253CX
      АЕСЛИ
           зн = 2551X
      ТО 
           зн:=256BX
      ИНАЧЕ
           зн:=2500X
      КОН;
      Окно.ПисатьЗнак(вс,к,зн)
    КОН;
         зн:=Окно.ЧитатьЗнак(нс,пк);
    ЕСЛИ
         зн = 2502X
    ТО 
         зн:=2524X
    АЕСЛИ
         зн = 2551X
    ТО 
         зн:=2562X
    ИНАЧЕ
         зн:=2500X
    КОН;
    Окно.ПисатьЗнак(нс,пк,зн);
  ИНАЧЕ                             (* вертикальная черта *)
         зн:=Окно.ЧитатьЗнак(вс,лк);
    ЕСЛИ
         зн = 2500X
    ТО 
         зн:=252CX
    АЕСЛИ
         зн = 2550X
    ТО 
         зн:=2564X
    ИНАЧЕ
         зн:=2502X
    КОН;
    Окно.ПисатьЗнак(вс,лк,зн);
    ОТ с:=вс+1 ДО нс-1 ВЫП
           зн:=Окно.ЧитатьЗнак(с,лк);
      ЕСЛИ
           зн = 2500X
      ТО 
           зн:=253CX
      АЕСЛИ
           зн = 2550X
      ТО 
           зн:=256AX
      ИНАЧЕ
           зн:=2502X
      КОН;
      Окно.ПисатьЗнак(с,лк,зн)
    КОН;
         зн:=Окно.ЧитатьЗнак(нс,пк);
    ЕСЛИ
         зн = 2500X
    ТО 
         зн:=2534X
    АЕСЛИ
         зн = 2550X
    ТО 
         зн:=2567X
    ИНАЧЕ
         зн:=2502X
    КОН;
    Окно.ПисатьЗнак(нс,пк,зн)
  КОН
КОН Чёрточка;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ЦепьЗнаков-(
               вс,
               лк,
               нс,
               пк :ЦЕЛ;
             цепь-:ЦЕПЬ
                  );     (* Записывает цепочку знаков в прямоугольную область *)

(*----------------------------------- Вывод.ВПрямоуг() -----------------------
ЗАДАЧА ВПрямоуг-(x0,y0,x1,y1:ЦЕЛ;
                       цепь-:ЦЕПЬ);
(* Записывает цепочку знаков в прямоугольную область. *)
ПЕР
  поз:ЦЕЛ;
  x,y:ЦЕЛ;
УКАЗ
  поз:=0;
  y:=y0;
  ПОКА y <= y1 ВЫП
    x:=x0;
    ПОКА x <= x1 ВЫП
      ЕСЛИ
           (поз >= РАЗМЕР(цепь))
          ИЛИ
           (цепь[поз] = 0X)
      ТО
        ВОЗВРАТ
      КОН;
      ОС.ПисатьЗнак(x,y,Знак.ВДос(цепь[поз]));
      УВЕЛИЧИТЬ(поз);
      УВЕЛИЧИТЬ(x)
    КОН;
    УВЕЛИЧИТЬ(y)
  КОН
КОН ВПрямоуг;
*)
ПЕР
  поз:ЦЕЛ;
  с,к:ЦЕЛ;
  знак:ЗНАК;
  длина:ЦЕЛ;
  былаВолна:КЛЮЧ;
УКАЗ
  былаВолна:=ОТКЛ;
  поз:=0;
       с:=вс;
                  длина:=ДЛИНА(цепь);
  ПОКА
       с <= нс
  ВЫП
         к:=лк;
    ПОКА к <= пк ВЫП
      ЕСЛИ
           поз >= длина
      ТО
        ВОЗВРАТ
      КОН;
                            знак:=цепь[поз];
      ЕСЛИ
           былаВолна
      ТО
        Окно.ПисатьЗнак(с,к,знак);
        былаВолна:=ОТКЛ
      ИНАЧЕ
        ЕСЛИ
             знак = '^'
        ТО
                            к:=пк
        АЕСЛИ
             знак = '~'
        ТО
          былаВолна:=ВКЛ
        ИНАЧЕ
          Окно.ПисатьЗнак(с,к,знак)
        КОН
      КОН;
      УВЕЛИЧИТЬ(поз);
      УВЕЛИЧИТЬ(к)
    КОН;
    УВЕЛИЧИТЬ(с)
  КОН
КОН ЦепьЗнаков;

КОН Окно.
