//
// The Fusion Library Interface for DOS
// Version 1.06c
// Copyright (C) 1990, 1991, 1992
// Software Dimensions
//
// FusionWindow
//

#include "fliwin.h"

#ifdef __BCPLUSPLUS__
#pragma hdrstop
#endif

#include <alloc.h>
#include <bios.h>

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// EngageFusion()
//
// Enganges the Fusion Windows system
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

int FusionWindow::EngageFusion()
{
  register int i;

  BlazeClass Blaze;

  long VirtualLapseTime=biostime(0,0);

  if (!NumberOfMenus)
    return NoAvailableMenus;

  if (CurrentLevel)
  {
    free(SubMenuTrack);
    CurrentLevel=0;
    SubMenuTrack=0;
  }

  Blaze.FreshWorkSpace();

  SetMenuBar(0,0,Blaze.WhatWidth());

  if (NumberOfWindows)
    RefreshWindows();

  int Event;
  MouseInControl=1;

  HelpId=DefaultHelp;

  EventHandler(EngageEvent);

  for (;;)
  {

TopLoop:

    if (!CurrentLevel &&
      (!NumberOfWindows ||
      (NumberOfWindows && !Windows[0]->CurrentLevel)))
    {
      if (!NumberOfWindows)
        RefreshPromptLine();
      else
      {
        if (!Windows[0]->RefreshPromptLine())
          RefreshPromptLine();
      }
      HelpId=DefaultHelp;
      if (NumberOfWindows)
        Windows[0]->Cursor();
    }

    //--------------------------------------------------------------
    //
    // Get event, if none - process virtual windows
    //
    //--------------------------------------------------------------

    if (!CheckVirtuals())
      Event=GetEvent();
    else
    {
      while(!(Event=GetEvent(1)))
      {
        if (biostime(0,0)>(VirtualLapseTime+VirtualizeInterval))
        {
          VirtualizeFresh();
          VirtualLapseTime=biostime(0,0);
        }
      }
    }

    //--------------------------------------------------------------
    //
    // A help event occured
    //
    //--------------------------------------------------------------

ComeBack:

    if (Event==HelpEvent)
    {
      if (CurrentLevel)
        MouseInControl=0;
      else if (NumberOfWindows && Windows[0]->CurrentLevel)
        Windows[0]->MouseInControl=0;
      continue;
    }

    //--------------------------------------------------------------
    //
    // Check for a shift event
    //
    //--------------------------------------------------------------

    if (Event==ShiftEvent)
    {
      if (!CurrentLevel &&
        (!NumberOfWindows ||
        (NumberOfWindows && !Windows[0]->CurrentLevel)))
      {
        if (!NumberOfWindows)
          RefreshPromptLine();
        else
        {
          if (!Windows[0]->RefreshPromptLine())
            RefreshPromptLine();
        }
        HelpId=DefaultHelp;
      }
      continue;
    }

    //--------------------------------------------------------------
    //
    // Check the global menus
    //
    //--------------------------------------------------------------

    if (!NumberOfWindows ||
       (NumberOfWindows &&
       (!Windows[0]->CurrentLevel ||
        (Windows[0]->CurrentLevel && Event!=MousedEvent))))
    {
      int Save;
      switch(Save=Manager(Event,0,NumberOfWindows,*Windows[0],*this))
      {
        case NothingEvent:
          RefreshMenus();
          break;

        case MenuEvent:
          RefreshMenus();
          if (CurrentLevel && Event!=MousedEvent)
            break;
          goto TopLoop;

        case MenusRemoved:
          RefreshMenus();
          RefreshPromptLine();
          goto ComeBack;

        default:
          MouseInControl=0;
          RefreshMenus();
          switch(EventHandler(Save))
          {
            case CompleteEvent:
              RefreshMenus();
              continue;

            case StopEvent:
              RefreshMenus();
              EventHandler(DisEngageEvent);
              return StopEvent;

            case RefreshEvent:
              RefreshMenus();
              RefreshWindows();
              continue;

            default:
              if (NumberOfWindows)
              {
                switch(Windows[0]->EventHandler(Save))
                {
                  case CompleteEvent:
                    RefreshMenus();
                    continue;

                  case StopEvent:
                    EventHandler(DisEngageEvent);
                    return StopEvent;

                  case RefreshEvent:
                    RefreshMenus();
                    RefreshWindows();
                    continue;

                  default:
                    RefreshMenus();
                    goto TopLoop;
                }
              }
              goto TopLoop;
          }
      }
    }

    //--------------------------------------------------------------
    //
    // Check the window menus
    //
    //--------------------------------------------------------------

    if (NumberOfWindows && Windows[0]->NumberOfMenus)
    {
      if (CurrentLevel && Event==MousedEvent)
        goto TopLoop;

      int Save;
      switch(Save=Windows[0]->Manager(Event,1,NumberOfWindows,*Windows[0],*this))
      {
        case NothingEvent:
          Windows[0]->RefreshMenus();
          break;

        case MenuEvent:
          Windows[0]->RefreshMenus();
          HelpId=Windows[0]->HelpId;
          goto TopLoop;

        case MenusRemoved:
          Windows[0]->RefreshMenus();
          RefreshPromptLine();
          goto ComeBack;

        default:
          Windows[0]->MouseInControl=0;
          Windows[0]->RefreshMenus();
          switch(Windows[0]->EventHandler(Save))
          {
            case CompleteEvent:
              Windows[0]->RefreshMenus();
              continue;

            case StopEvent:
              EventHandler(DisEngageEvent);
              return StopEvent;

            case RefreshEvent:
              Windows[0]->RefreshMenus();
              RefreshWindows();
              continue;

            case CloseEvent:
              CloseWindow();
              continue;

            default:
              goto TopLoop;
          }
      }
    }

    //--------------------------------------------------------------
    //
    // Check the prompt line
    //
    //--------------------------------------------------------------

    if (Event==MousedEvent &&
       !CurrentLevel &&
       (!NumberOfWindows ||
       (NumberOfWindows && !Windows[0]->CurrentLevel)))
    {
      int Save;

      if (!NumberOfWindows)
        Save=CheckPromptLine();
      else
      {
        Save=Windows[0]->CheckPromptLine();
        if (Save && Save!=1)
          Save=EventHandler(Save);
        else if (!Save)
          Save=CheckPromptLine();
      }

      switch(Save)
      {
        case 0:
        case 1:
          break;

        case CompleteEvent:
          goto TopLoop;

        case StopEvent:
          EventHandler(DisEngageEvent);
          return StopEvent;

        case RefreshEvent:
          RefreshWindows();
          goto TopLoop;

        default:
          if (NumberOfWindows)
          {
            switch(Windows[0]->EventHandler(Save))
            {
              case CompleteEvent:
                continue;

              case StopEvent:
                EventHandler(DisEngageEvent);
                return StopEvent;

              case RefreshEvent:
                RefreshWindows();
                continue;

              default:
                goto TopLoop;
            }
          }
      }
    }

    //--------------------------------------------------------------
    //
    // Check to see if a size corner or move handle was grabbed
    //
    //--------------------------------------------------------------

    if (Event==MousedEvent && MouseEvent&MouseLeftButtonPress &&
       !CurrentLevel &&
       (!NumberOfWindows ||
       (NumberOfWindows && !Windows[0]->CurrentLevel)))
    {
      if (CheckMoveOrSize())
        continue;
    }

    //--------------------------------------------------------------
    //
    // Check to see if a scroll bar was grabbed or scroll arrow was
    // depressed
    //
    //--------------------------------------------------------------

    if (Event==MousedEvent &&
       (MouseEvent&MouseLeftButtonPress || MouseEvent&MouseHeldDown || MouseEvent&MouseLeftButtonRelease) &&
        !CurrentLevel &&
       (!NumberOfWindows ||
       (NumberOfWindows && !Windows[0]->CurrentLevel)))
    {
      if (!CurrentLevel &&
        (NumberOfWindows && !Windows[0]->CurrentLevel))
      {
        if (Windows[0]->CheckScrollBar())
          goto TopLoop;
      }
    }

    //--------------------------------------------------------------
    //
    // Check to see where and how to respond to a button release
    //
    //--------------------------------------------------------------

    int BackSaveEvent;

    if (Event==MousedEvent &&
        (MouseEvent&MouseLeftButtonRelease || MouseEvent&MouseLeftButtonPress) &&
        !CurrentLevel &&
       (!NumberOfWindows ||
       (NumberOfWindows && !Windows[0]->CurrentLevel)))
    {
      WindowElement &Window=*Windows[0];

      if ((MouseHorizontal>=Window.X+Window.Width
        || MouseHorizontal<Window.X
        || MouseVertical>=Window.Y+Window.Height
        || MouseVertical<Window.Y)
        && NumberOfWindows>1)
      {
        for (i=1;i<NumberOfWindows;i++)
        {
          if (MouseHorizontal<Windows[i]->X+Windows[i]->Width
            && MouseHorizontal>=Windows[i]->X
            && MouseVertical<Windows[i]->Y+Windows[i]->Height
            && MouseVertical>=Windows[i]->Y)
          {
            CallWindow(i);
            BackSaveEvent=Event;
            Event=SwitchEvent;
            goto RawEvent;
          }
        }
      }

      //--------------------------------------------------------------
      //
      // Check to see if the zoom icon was clicked and zoom or unzoom
      // the window
      //
      //--------------------------------------------------------------

      if (Event==MousedEvent && MouseEvent&MouseLeftButtonRelease &&
        !CurrentLevel &&
       (!NumberOfWindows ||
       (NumberOfWindows && !Windows[0]->CurrentLevel)))
      {
        if (Window.ZoomIcon
          && MouseHorizontal<Window.X+Window.Width-1
          && MouseHorizontal>=Window.X+Window.Width-3
          && MouseVertical==Window.Y)
        {
          ZoomWindow();
          goto TopLoop;
        }

        if (Window.CloseIcon
          && MouseHorizontal<=Window.X+3
          && MouseHorizontal>Window.X
          && MouseVertical==Window.Y)
        {
          CloseWindow();
          Event=CloseEvent;
          goto RawEvent;
        }
      }
    }

    //--------------------------------------------------------------
    //
    // Check to see if within and a window and validate the event
    //
    //--------------------------------------------------------------

    if (Event==MousedEvent &&
       !CurrentLevel &&
      (!NumberOfWindows ||
      (NumberOfWindows && !Windows[0]->CurrentLevel)))
    {
      if (NumberOfWindows)
      {
        WindowElement &Window=*Windows[0];

        if (MouseHorizontal<Window.X+Window.Width-1
          && MouseHorizontal>Window.X
          && MouseVertical<Window.Y+Window.Height-1
          && MouseVertical>Window.Y+((Window.NumberOfMenus)?1:0))
        {
          MouseHorizontal-=(Window.X+1);
          MouseVertical-=(Window.Y+1);

          if (Window.NumberOfMenus)
            MouseVertical--;

          switch(Windows[0]->EventHandler(ValidatedMousedEvent))
          {
            case CompleteEvent:
              continue;

            case StopEvent:
              EventHandler(DisEngageEvent);
              return StopEvent;

            case RefreshEvent:
              RefreshWindows();
              continue;
          }
        }
      }
    }

    //------------------------------------------------------------
    //
    // Check to see if one of the windows was called up using a
    // quick window key (Alt+1 - Alt+9)
    //
    // Starting with FLI 1.06, the Alt+0 combination has been
    // left open for the programmer to define.
    //
    //------------------------------------------------------------

    if (Event!=MousedEvent && NumberOfWindows && Event>=kbAlt1 && Event<=kbAlt9 &&
        !CurrentLevel &&
       (!NumberOfWindows ||
       (NumberOfWindows && !Windows[0]->CurrentLevel)))
    {
      Event=(Event-kbAlt1)+1;
      for (i=0;i<NumberOfWindows;i++)
      {
        if (Event==Windows[i]->WindowNumber)
        {
          CallWindow(i);
          Event=SwitchEvent;
          goto RawEvent;
        }
      }
      goto TopLoop;
    }

    //------------------------------------------------------------
    //
    // Pass event along to the assessment queue for processing.
    //
    //------------------------------------------------------------

    if (!CurrentLevel &&
       (!NumberOfWindows ||
       (NumberOfWindows && !Windows[0]->CurrentLevel)))
    {
      int Save;

      if (NumberOfWindows)
      {
        if (!Windows[0]->CheckEvent(Event) && !CheckEvent(Event))
          goto RawEvent;
        if (!(Save=Windows[0]->CheckEvent(Event)))
          Save=CheckEvent(Event);
      }
      else if (!(Save=CheckEvent(Event),Save))
        goto RawEvent;

      switch(EventHandler(Save))
      {
        case CompleteEvent:
          continue;

        case StopEvent:
          EventHandler(DisEngageEvent);
          return StopEvent;

        case RefreshEvent:
          RefreshWindows();
          continue;

        default:
          if (NumberOfWindows)
          {
            switch(Windows[0]->EventHandler(Save))
            {
              case CompleteEvent:
                continue;

              case StopEvent:
                EventHandler(DisEngageEvent);
                return StopEvent;

              case RefreshEvent:
                RefreshWindows();
                continue;
            }
          }
      }

      //------------------------------------------------------------
      //
      // Just pass the raw event though to the global
      // event handler and see what happens.
      //
      //------------------------------------------------------------

RawEvent:

      switch(EventHandler(Event))
      {
        case CompleteEvent:
          continue;

        case StopEvent:
          EventHandler(DisEngageEvent);
          return StopEvent;

        case RefreshEvent:
          RefreshWindows();
          continue;
      }

      if (Event==CloseEvent)
        continue;

      if (Event==SwitchEvent)
      {
        Event=BackSaveEvent;
        goto ComeBack;
      }

      //------------------------------------------------------------
      //
      // Pass event along to the current window and see if it is a
      // key that the window can use.  If it cannot be used at this
      // phase, it is thrown out
      //
      //------------------------------------------------------------

      if (NumberOfWindows)
      {
        switch(Windows[0]->EventHandler(Event))
        {
          case CompleteEvent:
            continue;

          case StopEvent:
            EventHandler(DisEngageEvent);
            return StopEvent;

          case RefreshEvent:
            RefreshWindows();
            continue;
        }
      }
    }
  }
}

