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

ИСПОЛЬЗУЕТ 
  Рамка,
  Надел,
  Поле,
  Холст,
        (*  \Глагол\               *)
  ОС      ИЗ "..\..\Отделы\Обмен\",
  ЦвЗнак  ИЗ "..\..\Отделы\Обмен\",
  Окно    ИЗ "..\..\Отделы\Обмен\",
  Файл    ИЗ "..\..\Отделы\Обмен\",
  Ввод    ИЗ "..\..\Отделы\Обмен\";


ПОСТ
                     (* всего может быть закладок *)
  цЗакладок = 30;
                      (* цвет *)
  цветРамка    = 1BX;
  цветОткрытая = 1FX;
  цветЗакрытая = 17X;
  цветРКнопка  = 1FX;
  цветНКнопка  = 17X;

ВИД
  Доступ- = ДОСТУП К Вид;  (* Закладки.Доступ <- Надел.Доступ <- Рамка.Доступ *)

                     Вид- =(* Закладки.Вид    <- Надел.Вид    <- Рамка.Вид    *)
  НАБОР (Надел.Вид)
    закладок:ЦЕЛ;                          (* используется закладок   *)
    открытая:ЦЕЛ;                          (* номер открытой закладки *)
    первая:ЦЕЛ;                            (* первая видимая закладка *)
    холстД-:Холст.Доступ;                  (* открытый холст *)
    рДкХолсту:РЯД цЗакладок ИЗ Холст.Доступ;
    естьПраваяКнопка,
    естьЛеваяКнопка:КЛЮЧ; 
    былаОшибка:КЛЮЧ;      (* в нижней строке отображается сообщение об ошибке *)
  КОН;

ПЕР
                               (* составная ПЕРеменная - ряд цв.знаков *)
  рЧерта         :ЦвЗнак.РядСтрока;
                               (* составные ПЕРеменные - наборы ЦвЗнак.Вид *)
  нОткрытыйПробел:ЦвЗнак.Вид; 
  нЗакрытыйПробел:ЦвЗнак.Вид; 
  нВертЧерта     :ЦвЗнак.Вид; 
  нГорЧерта      :ЦвЗнак.Вид; 
  нПНУгол        :ЦвЗнак.Вид; 
  нЛНУгол        :ЦвЗнак.Вид; 
  нНУглы         :ЦвЗнак.Вид; 

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ПодготовитьПостоянные;
ПЕР
  поз:ЦЕЛ;
УКАЗ
  ЦвЗнак.ИзЗнакаИЦвета(" ",цветЗакрытая,нЗакрытыйПробел);
  ЦвЗнак.ИзЗнакаИЦвета(" ",цветОткрытая,нОткрытыйПробел);
  ЦвЗнак.ИзЗнакаИЦвета(2502X, цветРамка,нВертЧерта);
  ЦвЗнак.ИзЗнакаИЦвета(2500X, цветРамка,нГорЧерта);
  ЦвЗнак.ИзЗнакаИЦвета(2518X, цветРамка,нПНУгол);
  ЦвЗнак.ИзЗнакаИЦвета(2514X, цветРамка,нЛНУгол);
  ЦвЗнак.ИзЗнакаИЦвета(2534X, цветРамка,нНУглы);

  ОТ поз:=0 ДО РАЗМЕР(рЧерта)-1 ВЫП
    рЧерта[поз]:=нГорЧерта
  КОН
КОН ПодготовитьПостоянные;

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

УКАЗ
  лк:=закладкиД.лк;
  пк:=закладкиД.пк;
  вс:=закладкиД.вс;
  нс:=вс+1;
  послк:=пк-лк-2;
  низ:=рЧерта;
                                          (* место под кнопки *)
  верх[0]:=нВертЧерта;
   низ[0]:=нНУглы;
  верх[послк]:=нВертЧерта;
   низ[послк]:=нНУглы;
                                          (* существование кнопок *)
          закладкиД.естьЛеваяКнопка:=ОТКЛ;
          закладкиД.естьПраваяКнопка:=ОТКЛ;
  ЕСЛИ
          закладкиД.первая > 0
  ТО
          закладкиД.естьЛеваяКнопка:=ВКЛ
  КОН;
                                          (* для всех видимых закладок *)
  к:=0;     
          закладка:=закладкиД.первая;
  КОЛЬЦО
    ЕСЛИ
         (закладка >= закладкиД.закладок)
        ИЛИ
         (к >= послк)
    ТО
      ВЫХОД
    КОН;
                                          (* передний разделитель *)
       верх[к]:=нВертЧерта;
    ЕСЛИ
          закладка = закладкиД.открытая
    ТО
        низ[к]:=нПНУгол
    ИНАЧЕ
      ЕСЛИ
          закладка-1 = закладкиД.открытая
     ТО
        низ[к]:=нЛНУгол
      ИНАЧЕ
        низ[к]:=нНУглы
      КОН
    КОН;
    УВЕЛИЧИТЬ(к);
                                          (* текст *)
           поз:=0;
    КОЛЬЦО
      ЕСЛИ
           поз >= ДЛИНА(закладкиД.рДкХолсту[закладка].имя)
      ТО 
        ВЫХОД 
      КОН;
      ЕСЛИ
           к >= послк
      ТО 
          закладкиД.естьПраваяКнопка:=ВКЛ;
        ВЫХОД 
      КОН;
                знак:=закладкиД.рДкХолсту[закладка].имя[поз];
      ЕСЛИ
          закладка = закладкиД.открытая
      ТО
        ЦвЗнак.ИзЗнакаИЦвета(знак,цветОткрытая,верх[к]);
        низ[к]:=нОткрытыйПробел
      ИНАЧЕ
        ЦвЗнак.ИзЗнакаИЦвета(знак,цветЗакрытая,верх[к])
      КОН;
      УВЕЛИЧИТЬ(к);
      УВЕЛИЧИТЬ(поз)
    КОН;
    УВЕЛИЧИТЬ(закладка)
  КОН;
                                  (* задний разделитель *)
       верх[к]:=нВертЧерта;
  ЕСЛИ
       закладка-1 = закладкиД.открытая
  ТО
    низ[к]:=нЛНУгол
  ИНАЧЕ
    низ[к]:=нНУглы
  КОН;
  УВЕЛИЧИТЬ(к);
                                  (* свободное место *)
  ПОКА к < послк ВЫП
    верх[к]:=нЗакрытыйПробел;
    УВЕЛИЧИТЬ(к)
  КОН;
                                  (* кнопки *)
  ЕСЛИ
       закладкиД.естьЛеваяКнопка
  ТО
    цвет:=цветРКнопка
  ИНАЧЕ
    цвет:=цветНКнопка
  КОН;

  Окно.ПисатьЦвет(вс,лк,цвет);
  Окно.ПисатьЗнак(вс,лк,25C4X);
  Окно.ПисатьЦвет(нс,лк,цветРамка);
  Окно.ПисатьЗнак(нс,лк,2500X);

  ЕСЛИ
       закладкиД.естьПраваяКнопка
  ТО
    цвет:=цветРКнопка
  ИНАЧЕ
    цвет:=цветНКнопка
  КОН;

  Окно.ПисатьЦвет(вс,пк,цвет);
  Окно.ПисатьЗнак(вс,пк,25BAX);
  Окно.ПисатьЦвет(нс,пк,цветРамка);
  Окно.ПисатьЗнак(нс,пк,2500X);
                                          (* вывод *)
  Окно.ПисатьСтроку(верх,вс,лк+1,послк+1);
  Окно.ПисатьСтроку(низ,нс,лк+1,послк+1)
КОН ОтрисовкаЗаголовка;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                        (*(Закладки.Вид)*)
       ОтрисовкаОткрытой(закладкиД:Закладки.Доступ);
ПЕР
  отрисовка:Поле.нОтрисовка;
  холстД:Холст.Доступ;
УКАЗ
  ЕСЛИ
       закладкиД.закладок = 0
  ТО 
    Окно.РазмерУказки(0);
    закладкиД.холстД:=ПУСТО;

    Окно.ЦветнойПробел(закладкиД.вс+2,
                       закладкиД.лк,
                       закладкиД.нс,
                       закладкиД.пк,
                       Надел.цветХолста
                      )
  ИНАЧЕ
    холстД:=закладкиД.рДкХолсту[закладкиД.открытая];

    Рамка.Выставить(холстД,закладкиД.полеД);

    холстД.Приём(холстД,отрисовка);
    закладкиД.холстД:=холстД
  КОН
КОН ОтрисовкаОткрытой;

(*----------------------------------------------------------------------------*)
ЗАДАЧА                                                        (*(Закладки.Вид)*)
       ВыровнятьПервую(закладкиД:Закладки.Доступ);
ПЕР
  длина:ЦЕЛ;
  первая:ЦЕЛ;
УКАЗ
  ЕСЛИ
       закладкиД.закладок = 0
  ТО
    ВОЗВРАТ
  КОН;
  ЕСЛИ
       закладкиД.первая > закладкиД.открытая
  ТО
       закладкиД.первая:=закладкиД.открытая
  ИНАЧЕ
    длина:=закладкиД.пк-закладкиД.лк-4;
    первая:=закладкиД.открытая;
    ПОКА
         длина > 0
    ВЫП
      ЕСЛИ
           первая = закладкиД.первая
      ТО
        ВОЗВРАТ
      КОН;
      УМЕНЬШИТЬ(длина,ДЛИНА(закладкиД.рДкХолсту[первая].имя)+1);
      УМЕНЬШИТЬ(первая)
    КОН;
    закладкиД.первая:=первая+1
  КОН
КОН ВыровнятьПервую;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                                        (*(Закладки.Вид)*)
       НажатаМышка(закладкиД:Закладки.Доступ;
                          км:ЦЕЛ);
ПЕР
  к,пк,закладка:ЦЕЛ;
УКАЗ
    пк:=закладкиД.пк-закладкиД.лк;
  ЕСЛИ
       км <= 1
  ТО
    ЕСЛИ закладкиД.естьЛеваяКнопка ТО
      УМЕНЬШИТЬ(закладкиД.первая)
    КОН
  АЕСЛИ
       км >= пк-1
  ТО
    ЕСЛИ закладкиД.естьПраваяКнопка ТО
      УВЕЛИЧИТЬ(закладкиД.первая)
    КОН
  ИНАЧЕ
    закладка:=закладкиД.первая;
    к:=1;
    КОЛЬЦО
      ЕСЛИ
           (закладка >= закладкиД.закладок)
          ИЛИ
           (к >= пк-1)
      ТО
        ВЫХОД
      КОН;
      УВЕЛИЧИТЬ(к,ДЛИНА(закладкиД.рДкХолсту[закладка].имя)+1);
      ЕСЛИ
           км <= к
      ТО
        закладкиД.открытая:=закладка;
        ОтрисовкаОткрытой(закладкиД);
        ВЫХОД
      КОН;
      УВЕЛИЧИТЬ(закладка)
    КОН
  КОН;
  ОтрисовкаЗаголовка(закладкиД)
КОН НажатаМышка;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА                                          (* (Закладки.Вид <- Надел.Вид)*)(* приём посылок из вне (снаружи) *)
       Приём(наделД:Надел.Доступ;
           посылка+:Ввод.нПосылка); (* = Пустой.Вид; - абстрактный опорный набор *)
ПЕР
  закладкиД:Закладки.Доступ;

 (*..............................подЗадача...*)
  ЗАДАЧА ПриёмУХолста;
  ПЕР
         холстД:Холст.Доступ;
  УКАЗ
         холстД:=закладкиД.холстД;
    ЕСЛИ
         холстД # ПУСТО
    ТО
         холстД.Приём(холстД,посылка)
    КОН
  КОН ПриёмУХолста;

УКАЗ                                                         (* преобразование
                  наделД                  из Надел.Доступ в
                         Закладки.Доступ  <- Надел.Доступ <- Рамка.Доступ *)
       закладкиД:=наделД(Закладки.Доступ);
  ЕСЛИ
       закладкиД.былаОшибка
  ТО
    ОтрисовкаОткрытой(закладкиД);
       закладкиД.былаОшибка:=ОТКЛ
  КОН;
                             (* анализ многоформия (полиморфизма) у <посылка> *)
  ДЛЯ      посылка ВИДА
  | Поле.нОтрисовка:
      ОтрисовкаЗаголовка(закладкиД);
      ОтрисовкаОткрытой(закладкиД)
  | Ввод.нОтМышки:
      ЕСЛИ
           посылка.с < 2
      ТО
        ЕСЛИ
           посылка.события = {}
        ТО
          НажатаМышка(закладкиД,посылка.к)
        КОН
      ИНАЧЕ
        УМЕНЬШИТЬ(посылка.с,2);
        ПриёмУХолста                                           (* подЗадача *)
      КОН
  ИНАЧЕ
    ПриёмУХолста                                               (* подЗадача *)
  КОН
КОН Приём;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                        (*(Закладки.Вид)*)
       Открыть-(закладкиД:Закладки.Доступ;
                   оИмяФ-:Файл.ВПолного);
(*
 * открывает закладку на холст с заданным именем файла
 *)
ПЕР
                    имяФ :Файл.ВПолного;
  холстД:Холст.Доступ;
  закладка:ЦЕЛ;
УКАЗ
    ОС.МестоФ(оИмяФ,имяФ);
                      (* а может закладка с таким именем файла уже существует *)
  ОТ закладка:=0 ДО закладкиД.закладок-1 ВЫП
    ЕСЛИ
         закладкиД.рДкХолсту[закладка].имяФ = имяФ
    ТО
         закладкиД.открытая:=закладка;

      ОтрисовкаЗаголовка(закладкиД);                      (* локальная задача *)
      ОтрисовкаОткрытой(закладкиД);                       (* локальная задача *)
      ВОЗВРАТ
    КОН
  КОН;
                                                    (* создаём новую закладку *)
  ЕСЛИ закладкиД.закладок >= цЗакладок ТО
    ВОЗВРАТ
  КОН;
  холстД:=Холст.СоздатьИзФайла(2,0,-1,0,имяФ);
                                                 (* сажаем холст на наше поле *)
  холстД.полеД:=закладкиД.полеД;
  холстД.состояние:=Надел.состВыбран; 
                                                (* добавляем холст в закладки *)
 закладкиД.рДкХолсту[закладкиД.закладок]:=холстД;
 закладкиД.открытая:=закладкиД.закладок;

           УВЕЛИЧИТЬ(закладкиД.закладок);
   ОтрисовкаОткрытой(закладкиД);                          (* локальная задача *)
     ВыровнятьПервую(закладкиД);                          (* локальная задача *)
  ОтрисовкаЗаголовка(закладкиД)                           (* локальная задача *)
КОН Открыть;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                        (*(Закладки.Вид)*)
       Удалить-(закладкиД:Закладки.Доступ);
(*
 * удаляет открытую закладку
 *)
ПЕР
  закладка,открытая:ЦЕЛ;
УКАЗ
  ЕСЛИ
                закладкиД.закладок = 0
  ТО
    ВОЗВРАТ
  КОН;
      УМЕНЬШИТЬ(закладкиД.закладок);
      открытая:=закладкиД.открытая;

  ОТ закладка:=открытая ДО закладкиД.закладок-1 ВЫП
    закладкиД.рДкХолсту[закладка]:=закладкиД.рДкХолсту[закладка+1]
  КОН;
  ЕСЛИ
     открытая = закладкиД.закладок
  ТО
      УМЕНЬШИТЬ(закладкиД.открытая)
  КОН;
   ОтрисовкаОткрытой(закладкиД);                          (* локальная задача *)
     ВыровнятьПервую(закладкиД);                          (* локальная задача *)
  ОтрисовкаЗаголовка(закладкиД)                           (* локальная задача *)
КОН Удалить;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                        (*(Закладки.Вид)*)
       Следующая-(закладкиД:Закладки.Доступ);  
(*
 * выбор следующей закладки
 *)
УКАЗ
  ЕСЛИ
                  закладкиД.закладок = 0
  ТО
    ВОЗВРАТ
  КОН;
        УВЕЛИЧИТЬ(закладкиД.открытая);
  ЕСЛИ
                  закладкиД.открытая >= закладкиД.закладок
  ТО
                  закладкиД.открытая:=0
  КОН;
    ВыровнятьПервую(закладкиД);                           (* локальная задача *)
 ОтрисовкаЗаголовка(закладкиД);                           (* локальная задача *)
  ОтрисовкаОткрытой(закладкиД)                            (* локальная задача *)
КОН Следующая;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                        (*(Закладки.Вид)*)
       СИзменениями-(закладкиД:Закладки.Доступ):КЛЮЧ;
(*
 * Есть изменённые холсты ?
 *)
ПЕР
     закладка:ЦЕЛ;
УКАЗ
  ОТ закладка:=0 ДО закладкиД.закладок-1 ВЫП
    ЕСЛИ
         закладкиД.рДкХолсту[закладка].изменён = "*"
    ТО
      ВОЗВРАТ ВКЛ
    КОН
  КОН;
  ВОЗВРАТ ОТКЛ
КОН СИзменениями;

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

         холстД:=закладкиД.рДкХолсту[закладка];
    ЕСЛИ
         холстД.изменён = "*"
    ТО
      ЕСЛИ
           Холст.СохранитьВФайл(холстД)
      ТО
      КОН
    КОН
  КОН
КОН СохранитьИзменённые;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                        (*(Закладки.Вид)*)
       Создать-(верх,лево,строк,колонок:ЦЕЛ):Закладки.Доступ;
ПЕР
                    закладкиД:Закладки.Доступ;
УКАЗ
            СОЗДАТЬ(закладкиД);
  Надел.Подготовить(закладкиД,
                         верх,
                         лево,
                        строк,
                      колонок,
    {Надел.признакВыбираемый},
                        Приём   (* посылок для <наделД> *)
                   );
            ВОЗВРАТ закладкиД
КОН Создать;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА                                                        (*(Закладки.Вид)*)
       ВыводОшибки-(закладкиД:Закладки.Доступ; имяФ-:Файл.ВПолного;
                                                 с,к:ЦЕЛ;
                                              текст-:ЦЕПЬ);
ПЕР
  нс,лк,пк:ЦЕЛ;
УКАЗ
  Закладки.Открыть(закладкиД,имяФ);
  ЕСЛИ
                   закладкиД.закладок = 0
  ТО
    ВОЗВРАТ
  КОН;
  Холст.ВыставитьУказку(закладкиД.холстД,с-1,к-1);

  нс:=закладкиД.нс;
  лк:=закладкиД.лк;
  пк:=закладкиД.пк;

  Окно.ЦветнойПробел(нс,
                     лк,
                     нс,
                     пк,
                     Надел.цветПредупреждения);
  Окно.ЦепьЗнаков(нс,
                  лк,
                  нс,
                  пк,
                  текст);

  закладкиД.былаОшибка:=ВКЛ
КОН ВыводОшибки;

(*-ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss-*)
УКАЗ
  ПодготовитьПостоянные
КОН Закладки.
