#define MAXCOLORTC
#include "wingraph.h"

unsigned long idA, idB, idC[4]; // идентификаторы нитей
const int cc = RGB (197, 203, 201); // разные цвета
const int ca = RGB (196, 244, 203);
const int cb = RGB (255, 248, 127);
const int cw = RGB (255, 255, 255);

void A () // нить для транспортного средства
{
  int w, d; // w - объем топлива, d - задержка движения в зависимости от
  setfillstyle (1, cc);             // объема топлива
  bar (480, 40, 499, 59);
  MSG msg;
  PeekMessage (&msg, 0, 0, 0, PM_NOREMOVE); // создаем очередь сообщений
  GetMessage (&msg, 0, 0, 0); // ждем сообщение от пункта заготовления топлива
  for (int i = 480; i >= 60; i -= 10) // перемещаем транспортное средство к
  {                                   // пункту заготовления топлива
    setfillstyle (1, cc);
    bar (i, 40, i + 19, 59);
    delay (20);
    if (i > 60)            // в месте назначения не будем стирать рисунок
    {
      setfillstyle (1, cw);
      bar (i, 40, i + 19, 59);
    }
  }
  while (1)
  {
    PostThreadMessage (idB, WM_USER + 4, 0, 0); // посылаем пункту заготовления
                                         // топлива сообщение о готовности
    GetMessage (&msg, 0, 0, 0); // ждем от пункта заготовления топлива сообщение
    w = msg.wParam;              // о том, что он загрузил топливо в транспортное средство
    int boilerNumber = msg.lParam;  // принимаем вес топлива и номер котла, в который
    d = w * 7;                        // нужно это топливо везти
    for (int i = 60; i <= 200 + 80 * boilerNumber; i += 10)
    {                           // везем топливо к котлу
      setfillstyle (1, ca);
      bar (i, 40, i + 19, 59);
      delay (d);
      if (i < 200 + 80 * boilerNumber)
      {
        setfillstyle (1, cw);
        bar (i, 40, i + 19, 59);
      }
    }

    // сообщаем котлу, что привезли топливо с весом w
    PostThreadMessage (idC[boilerNumber], WM_USER, w, 0);
    GetMessage (&msg, 0, 0, 0); // ждем окончания отгрузки топлива в котел

    for (int i = 200 + 80 * boilerNumber; i >= 60; i -= 10)
    {                        // перемещаем транспортное средство обратно
      setfillstyle (1, cc);      // к пункту заготовления топлива
      bar (i, 40, i + 19, 59);
      delay (20);
      if (i > 60)
      {
        setfillstyle (1, cw);
        bar (i, 40, i + 19, 59);
      }
    }
  }
}

void B () // нить для пункта заготовления топлива
{
  int w, x;
  MSG msg;
  PeekMessage (&msg, 0, 0, 0, PM_NOREMOVE); // создаем очередь сообщений
  randomize ();
  delay(1500);
  PostThreadMessage (idA, WM_USER, 0, 0); // начальное сообщение транспортному
  while (1)                              // средству для начала его движения
  {
    w = random (7) + 4; // 4..10 - вес топлива определяем случайным образом
    for (int i = 0; i < w; i++) // размещаем все топливо в пункте
    {                                // заготовления топлива
      setfillstyle (1, ca);
      bar (40, 85 + i * 20, 99, 85 + i * 20 + 19);
      delay (250);
    }
    GetMessage (&msg, 0, WM_USER + 4, WM_USER + 4); // ждем сообщение от одного из котлов,
    GetMessage (&msg, 0, WM_USER, WM_USER + 3);      // что он пуст
    int boilerNumber = msg.wParam;        // определяем номер котла
    for (int i = w - 1; i >= 0; i--) // заливаем топливо в транспортное средство
    {
      setfillstyle (1, cw);
      bar (40, 85 + i * 20, 99, 85 + i * 20 + 19);
      delay (100);
    }
    PostThreadMessage (idA, WM_USER, w, boilerNumber);// отправляем транспортному средству
  }                           // сообщение, что закончили заливать в него топливо
}

void C(int n) // нити для энергоблоков
{
  int w, x;
  x = 180 + n * 80;
  MSG msg;
  PeekMessage (&msg, 0, 0, 0, PM_NOREMOVE); // создаем очередь сообщений
  PostThreadMessage (idB, WM_USER + n, n, 0); // сообщаем пункту заготовления топлива,
  while (1)                                     // что котел пуст
  {
    GetMessage (&msg, 0, 0, 0); // ждем сообщение от транспортного средства,
    w = msg.wParam;                // что оно привезло топливо и определяем его вес
    for (int i = 0; i < w; i++) // заливаем топливо в энергоблок
    {
      setfillstyle (1, cb);
      bar (x, 85 + i * 20, x + 59, 85 + i * 20 + 19);
      delay (100);
    }
    PostThreadMessage (idA, WM_USER, 0, 0); // сообщаем транспортному средству,
    for (int i = w - 1; i >= 0; i--)      // что залили из него все топливо
    {                              // сжигаем топливо постепенно
      setfillstyle (1, cw);
      bar (x, 85 + i * 20, x + 59, 85 + i * 20 + 19);
      delay (2000);
    }
    PostThreadMessage (idB, WM_USER + n, n, 0); // сообщаем пункту заготовления
  }                        // топлива, что котел снова пуст
}

void mainx ()
{
  resize (520, 320);
  outtextxy(230, 10, "e-station");
  setcolor(cc);
  line(40, 70, 479, 70);
  setfillstyle (1, cc);
  bar (40, 80, 99, 83);
  for (int i = 0; i < 4; i++)
    bar(180 + i * 80, 80, 239 + i * 80, 83);

  // создаем все нити
  CreateThread (0, 0, (LPTHREAD_START_ROUTINE) A, 0, 0, &idA);
  CreateThread (0, 0, (LPTHREAD_START_ROUTINE) B, 0, 0, &idB);
  CreateThread (0, 0, (LPTHREAD_START_ROUTINE) C, (LPVOID) 0, 0, idC + 0);
  CreateThread (0, 0, (LPTHREAD_START_ROUTINE) C, (LPVOID) 1, 0, idC + 1);
  CreateThread (0, 0, (LPTHREAD_START_ROUTINE) C, (LPVOID) 2, 0, idC + 2);
  CreateThread (0, 0, (LPTHREAD_START_ROUTINE) C, (LPVOID) 3, 0, idC + 3);
}
