// This may look like C code, but it is really -*- C++ -*-

//<copyright>
// 
// Copyright (c) 1994
// Institute for Information Processing and Computer Supported New Media (IICM),
// Graz University of Technology, Austria.
// 
//</copyright>

//<file>
//
// Name:        glyphutil.h
//
// Purpose:     interface to glyph utilities
//
// Created:     24 Mar 94   Michael Pichler
//
// Changed:     12 Oct 94   Michael Pichler
//
//
//</file>



#ifndef harmony_widgets_glyphutil_h
#define harmony_widgets_glyphutil_h


#include <InterViews/monoglyph.h>
#include <InterViews/telltale.h>
class Action;
class Adjustable;
class Button;
class Color;
class Display;
class Font;
class PolyGlyph;
class Style;
class WidgetKit;



// multiLineLabel ()
// splits a string of several lines
// returns a hbox of centered labels

Glyph* multiLineLabel (const char*);
Glyph* multiLineLabel (const char*, const Font*, const Color*);



// clearPolyGlyph
// removes all components of a PolyGlyph

void clearPolyGlyph (PolyGlyph*);



// strcpy_new: create new char array, copy string src onto it, return address
// null pointer creates a new emty string ("")
// note: strlen (0) or strcpy (..., 0) may cause a seg'fault

char* strcpy_new (const char* src);



// lookupColor
// lookup for a colour under different (up to 4) names
// tries names in order, returns nil if no colour can be found
// oops, "name2" etc. defined in sgmls/generic.h

const Color* lookupColor (
  const Style* style,  // usually kit.style (), non nil
  Display* dis,        // usually Session::instance ()->default_display ()
  const char* name, const char* n1 = 0,
  const char* n2 = 0, const char* n3 = 0
);



// glyphWithScrollbars
// adds scrollbars to an adjustable glyph (horicontal and vertical)

Glyph* glyphWithScrollbars (Glyph* g, Adjustable* xadj, Adjustable* yadj);



// class TransparentTarget
// if body is interested in hit, return its hit,
// otherwise report a hit when inside allocation

class TransparentTarget: public MonoGlyph
{
  public:
    TransparentTarget (Glyph* body)
    : MonoGlyph (body)  { }

    void pick (Canvas*, const Allocation&, int depth, Hit&);
};


// class ShapeOfMaster
// a monoglyph that does request always on some "master" glyph
// so the body always has the shape of the "master"

class ShapeOfMaster: public MonoGlyph
{
  public:
    ShapeOfMaster (Glyph* master = nil, Glyph* body = nil);
    ~ShapeOfMaster ();

    void master (Glyph*);               // change master glyph

    void request (Requisition&) const;

  private:
    Glyph* master_;
};


// class WWidgetKit - slight modifications of WidgetKit


class WWidgetKit
{
  public:
    static Button* push_button (        // push button with sharable telltale state
      Glyph*,                           //   button glyph
      Action*,                          //   action
      TelltaleState*                    //   e.g.: new TelltaleStale (TelltaleState::is_enabled)
    );

    static Button* push_button (        // push button (as above) with label
      const char*,                      //   button label
      Action*,
      TelltaleState*
    );

    static Button* palette_button (     // palette button with sharable telltale state
      Glyph*,                           //   button glyph
      Action*,                          //   action
      TelltaleState*                    //   set flag is_toggle for a toggle button or
    );                                  //     is_choosable for radio button behaviour

    static Button* palette_button (     // palette button (as above) with label
      const char*,                      //   button label
      Action*,
      TelltaleState*
    );

    static void enable (TelltaleState* s)    // set enabled flag of a telltale state (non nil)
    { s->set (TelltaleState::is_enabled, 1); }

    static void disable (TelltaleState* s)   // clear enabled flag of a telltale state (non nil)
    { s->set (TelltaleState::is_enabled, 0); }

    static void enable (Button* button);     // enable a button (non nil)
    static Button* disable (Button*);        // disable a button (non nil)

  private:
    static Button* makePaletteButton (WidgetKit&, Glyph*, Action*, TelltaleState*);

};  // WWidgetKit



// class WLayoutKit - slight modifications of LayoutKit
//
//
// WLayoutKit::fhbox ()
// ~~~~~~~~~~~~~~~~~~~~
// flexible hbox, whith choosable alignment strategy; currently
// AlignOrdinary and AlignFlexible are supported, but the interface
// is open for other alignments
//
// AlignFlexible:
//
// space demand is computed as usual;
// but components are told to use no more and no less than available vertical space
// regardless of their minimum and maximum size (useful for labels - they are
// able to stretch although they do not tell this in request)
//
//
// WLayoutKit::phbox ()
// ~~~~~~~~~~~~~~~~~~~~
// "proportional hbox"
//
// space is proportional divided among the glyphs; for proportionality
// constants the alignment is used (weak method, but how to specify
// otherwise?). 0.0 as alignment means to use the glyph's natural size,
// all other alignment values are added (need not sum up to 1.0) and the
// remaining space is divided among the glyphs according to their
// alignment value - the natural size of those glyph is NOT taken into
// account, it is assumed that they can stretch freely;
//
// the current implementation is only able to divide space flexible
// among the first ten components; further components are given their
// natural size.
//


class WLayoutKit
{
  public:
    enum AlignStrategy {                // how to align (in one dimension)
      AlignOrdinary,                    // IV default
      AlignFlexible                     // align flexible (see remarks above)
    };

    static PolyGlyph* fhbox(            // flexible hbox, empty
      AlignStrategy ya,                 //   how to align
      GlyphIndex size                   //   predicted no. of components
    );

    static PolyGlyph* fhbox(            // fhbox with initial components
      AlignStrategy ya,                 //   how to align
      Glyph* = nil, Glyph* = nil, Glyph* = nil, Glyph* = nil, Glyph* = nil,
      Glyph* = nil, Glyph* = nil, Glyph* = nil, Glyph* = nil, Glyph* = nil
    );

    static PolyGlyph* phbox(            // proportional box with initial components
      AlignStrategy ya,                 //   how to align
      Glyph* = nil, float = 0, Glyph* = nil, float = 0,
      Glyph* = nil, float = 0, Glyph* = nil, float = 0,
      Glyph* = nil, float = 0, Glyph* = nil, float = 0,
      Glyph* = nil, float = 0, Glyph* = nil, float = 0,
      Glyph* = nil, float = 0, Glyph* = nil, float = 0
    );

    static PolyGlyph* phbox(            // array of glyphs for phbox
      AlignStrategy ya,                 //   how to align
      unsigned numcomp,                 //   no. of glyphs
      const float* prop                 //   array of prop. constants
    );                                  //   glyphs to be set (e.g.) with append

};  // WLayoutKit


#endif
