//
// The Fusion Library Interface for DOS
// Version 1.06c
// Copyright (C) 1990, 1991, 1992
// Software Dimensions
//
// FusionWindow -> Status -> Icons -> ScrollBars -> WindowElement
//

#include "fliwin.h"
#include "colors.h"

#ifdef __BCPLUSPLUS__
#pragma hdrstop
#endif

#include <string.h>
#include <ctype.h>

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// WindowElement()
//
// Constructor for Window Element class
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

WindowColors::WindowColors()
{
  WinBorder=Colors.WinBorder;
  WinIcons=Colors.WinIcons;
  WinTitle=Colors.WinTitle;
  WinScrollBar=Colors.WinScrollBar;
  WinSizeCorner=Colors.WinSizeCorner;
  WinInterior=Colors.WinInterior;
  WinBoldInterior=Colors.WinBoldInterior;
  WinAltInterior=Colors.WinAltInterior;
  WinDead=Colors.WinDead;
}

WindowElement::WindowElement()
{
  Title=0;
  MinimumWidth=13;
  MinimumHeight=5;
  X=0;
  Y=1;
  Width=Blaze.WhatWidth();
  Height=Blaze.WhatHeight()-2;
  Blaze.Window(X+1,Y+1,Width-2,Height-2);
  WindowNumber=0;
  Active=0;
  ZoomIcon=1;
  CloseIcon=1;
  SizeIcon=1;
  Moveable=1;
  WindowZoomed=0;
  OldX=0;
  OldY=0;
  OldWidth=0;
  OldHeight=0;
  ExistXScrollBar=0;
  ExistYScrollBar=0;
  XMaximum=0;
  XCurrent=0;
  YMaximum=0;
  YCurrent=0;
  MainHandler=0;
  VirtualUpdate=0;
  InAWindow=1;
}

WindowElement::~WindowElement()
{
  // Intentional
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// ShowWindow()
//
// Shows the window on the display
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

void WindowElement::ShowWindow()
{
  Blaze.Window(0,0,Blaze.WhatWidth(),Blaze.WhatHeight());

  MouseHide();

  int Icons=(Active)?WinIcons:WinDead;
  int Border=(Active)?WinBorder:WinDead;

  if (Width<13 || Width<MinimumWidth)
  {
    if (MinimumWidth>=13)
      Width=MinimumWidth;
    else
      Width=13;

    if (X+Width>Blaze.WhatWidth())
      X=Blaze.WhatWidth()-Width;
  }

  if (Height<5 || Height<MinimumHeight)
  {
    if (MinimumHeight>=5)
      Height=MinimumHeight;
    else
      Height=5;

    if (Height>Blaze.WhatHeight()-2)
      Y=Blaze.WhatHeight()-2-Height;
  }

  if (Active)
  {
    Blaze.UserBoxDefineQuick(2);
    Blaze.Box(X,Y,Width,Height,Border);
    Blaze.UserBoxDefineQuick(1);
  }
  else
    Blaze.Box(X,Y,Width,Height,Border);

  Blaze.EraseArea(X+1,Y+1,Width-2,Height-2,WinInterior);

  if (NumberOfMenus)
  {
    int MenuWidth=SetMenuBar(X+1,Y+1,Width-2,Blaze.WhatOutput());
    if (MinimumWidth<MenuWidth)
      MinimumWidth=MenuWidth;
  }

  if (CloseIcon)
    Blaze (X+1,Y)
      << Border
      << '['
      << Icons
      << '\x7'
      << Border
      << ']';

  if (ZoomIcon)
    Blaze (X+Width-4,Y)
      << Border
      << '['
      << Icons
      << (char)((!WindowZoomed)?'\x1e':'\x1f')
      << Border
      << ']';

  if (SizeIcon)
    Blaze (X+Width-1,Y+Height-1)
      << (int)((Active)?WinSizeCorner:WinDead)
      << '\xfe';

  if (Title &&
    strlen(Title)<(Width-((WindowNumber)?4:0)-(ZoomIcon*3)-(CloseIcon*3)-3))
    Blaze (X+((CloseIcon)?5:1),Y)
      << (int)((Active)?WinTitle:WinDead)
      << Title;

  if (WindowNumber)
    Blaze ((X+Width-8)+((!ZoomIcon)?4:0),Y)
      << Border
      << '|'
      << Icons
      << (char)('0'+WindowNumber)
      << Border
      << '|';

  if (Active)
    DisplayScrollBar();
  else
    MouseShow();

  int CalcHeight=Height-2-((NumberOfMenus)?1:0);

  if (!CalcHeight)
    CalcHeight++;

  Blaze.Window(X+1,Y+1+((NumberOfMenus)?1:0),Width-2,CalcHeight);
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// DisplayScrollBar()
//
// Displays the scroll bars
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

void WindowElement::DisplayScrollBar()
{
  Blaze.Window(0,0,Blaze.WhatWidth(),Blaze.WhatHeight());

  MouseHide();

  if (ExistXScrollBar)
  {
    Blaze.CharacterRepeater(X+2,Y+Height-1,Width-4,WinScrollBar,0xb1);
    Blaze (X+1,Y+Height-1)
      << WinScrollBar
      << '\x11';
    Blaze (X+Width-2,Y+Height-1)
      << '\x10';

    if (XMaximum && XMaximum>Width-4)
    {
      int ActualAvail=Width-4;

      int Determine=XMaximum/ActualAvail;

      int AnotherDetermine=0;
      if (XCurrent)
        AnotherDetermine=XCurrent/Determine;

      if (AnotherDetermine>=Width-4)
        AnotherDetermine=Width-5;

      Blaze (X+2+AnotherDetermine,Y+Height-1) << '\xfe';
    }
  }

  if (ExistYScrollBar)
  {
    Blaze.CharacterRepeaterDown(X+Width-1,Y+2,Height-4,WinScrollBar,0xb1);
    Blaze (X+Width-1,Y+1)
      << WinScrollBar
      << '\x1e';
    Blaze (X+Width-1,Y+Height-2)
      << '\x1f';

    if (YMaximum && YMaximum>Height-4)
    {
      int ActualAvail=Height-4;

      int Determine=YMaximum/ActualAvail;

      int AnotherDetermine=0;
      if (YCurrent)
        AnotherDetermine=YCurrent/Determine;

      if (AnotherDetermine>=Height-4)
        AnotherDetermine=Height-5;

      Blaze (X+Width-1,Y+2+AnotherDetermine) << '\xfe';
    }
  }

  int CalcHeight=Height-2-((NumberOfMenus)?1:0);

  if (!CalcHeight)
    CalcHeight++;

  MouseShow();

  Blaze.Window(X+1,Y+1+((NumberOfMenus)?1:0),Width-2,CalcHeight);
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// CheckScrollBar()
//
// Displays the scroll bars
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

int WindowElement::CheckScrollBar()
{
  if (!ExistXScrollBar && !ExistYScrollBar)
    return 0;

  if (MouseVertical<Y+Height-2 && MouseVertical>Y+1 &&
    MouseHorizontal==X+Width-1 && YMaximum>Height-4)
  {
    int Blocks=(Y+Height-2)-(Y+1)-1;

    if (Blocks<=1 || !YMaximum)
      return 0;

    YCurrent=(YMaximum/Blocks)*(MouseVertical-(Y+2));

    DisplayScrollBar();
    ShowInterior();

    return 1;
  }

  if (MouseHorizontal<X+Width-2 && MouseHorizontal>X+1 &&
    MouseVertical==Y+Height-1 && XMaximum>Width-4)
  {
    int Blocks=(X+Width-2)-(X+1)-1;

    if (Blocks<=1 || !XMaximum)
      return 0;

    XCurrent=(XMaximum/Blocks)*(MouseHorizontal-(X+2));

    DisplayScrollBar();
    ShowInterior();

    return 1;
  }

  if (ExistXScrollBar && XMaximum)
  {
    // Right Button

    if (MouseVertical==Y+Height-1 && MouseHorizontal==X+Width-2)
    {
      if (XCurrent<XMaximum)
      {
        XCurrent++;
        DisplayScrollBar();
        ShowInterior();
      }
      return 1;
    }

    // Left Button

    if (MouseVertical==Y+Height-1 && MouseHorizontal==X+1)
    {
      if (XCurrent)
      {
        XCurrent--;
        DisplayScrollBar();
        ShowInterior();
      }
      return 1;
    }
  }

  if (ExistYScrollBar && YMaximum)
  {
    // Down Button

    if (MouseVertical==Y+Height-2 && MouseHorizontal==X+Width-1)
    {
      if (YCurrent<YMaximum)
      {
        YCurrent++;
        DisplayScrollBar();
        ShowInterior();
      }
      return 1;
    }

    // Up Button

    if (MouseVertical==Y+1 && MouseHorizontal==X+Width-1)
    {
      if (YCurrent)
      {
        YCurrent--;
        DisplayScrollBar();
        ShowInterior();
      }
      return 1;
    }
  }

  return 0;
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// RemoveTheMenus()
//
// Removes both global and local menus
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

void WindowElement::RemoveTheMenus()
{
  if (!MainHandler)
    return;
  MainHandler->RemoveAllMenus();
  RemoveAllMenus();
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// Cursor()
//
// Shows the cursor
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

void WindowElement::Cursor()
{
  // Intentionally left empty
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// Echo()
//
// Echos a signal back to the caller
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

int WindowElement::Echo()
{
  return 0;
}

//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
// ReAlign()
//
// Realigns the window (resets the window boundaries)
//
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

void WindowElement::ReAlign()
{
  int CalcHeight=Height-2-((NumberOfMenus)?1:0);

  if (!CalcHeight)
    CalcHeight++;

  Blaze.Window(X+1,Y+1+((NumberOfMenus)?1:0),Width-2,CalcHeight);
  if (NumberOfMenus)
    SetMenuBar(X+1,Y+1,Width-2,Blaze.WhatOutput());
}

