

// ##########################################################################
// #                                                                        #
// #                             ChildGenerator                             #
// #                                                                        #
// #                            - Definitionen -                            #
// #                                                                        #
// ##########################################################################


#include"gui/childgen.h"
#include"gui/newtypes.h"
#include"gui/numlabel.h"
#include"gui/txtlabel.h"
#include"gui/sellabel.h"
#include"gui/extnumed.h"
#include"gui/btnnumed.h"
#include"gui/tblview.h"
#include"gui/lnksisel.h"
#include"gui/lnkmusel.h"
#include"gui/lnkcombo.h"
#include"gui/group.h"
#include"gui/chart.h"

#include"ui/composit.h"
#include"ui/cntroler.h"
#include"ui/pushbtn.h"
#include"ui/combobox.h"
#include"ui/toglbtn.h"
#include"ui/xrtglbtn.h"
#include"ui/stred.h"
#include"ui/dialog.h"
#include"ui/font.h"
#include"ui/label.h"
#include"ui/strview.h"
#include"ui/textedit.h"
#include"ui/scrolbar.h"
#include"ui/menu.h"
#include"ui/orbtngrp.h"
#include"ui/xrbtngrp.h"
#include"ui/3dlabel.h"
#include"ui/bmtglbtn.h"
#include"ui/bmpushbn.h"
#include"ui/pswdedit.h"
#include"ui/dateedit.h"
#include"ui/numedit.h"


ChildGenerator ChildGen;


// Generation for VObjCollection:


bool ChildGenerator :: generate    (UI_VObjCollection*      client,
												const UI_ViewDescriptor* items)
{
  bool res = FALSE;
  if (client && items)
	{
	  res = TRUE;
	  unsigned i = 0;
	  while (items[i].type != View_None)
	  {
		 if (!createChild(client,items[i]))
			  res = FALSE;
		 i++;
	  };
	};
  return res;
};


bool ChildGenerator :: generate    (UI_VObjCollection* client,
												UI_ViewDescriptor* * multi)
{
  bool res = FALSE;
  if (multi)
	{
	  unsigned i = 0;
	  while (multi[i])
			{
			  res *= generate(client,multi[i]);
			  i++;
			};
	};
  return res;
};


bool ChildGenerator :: operator () (UI_VObjCollection*     client,
												const UI_ViewDescriptor* items)
{
  return generate(client,items);
};


bool ChildGenerator :: operator () (UI_VObjCollection* client,
												UI_ViewDescriptor*   *multi)
{
  return generate(client,multi);
};


// Generation for Composite:


bool ChildGenerator :: generate    (UI_CompositeVObject*     client,
												const UI_ViewDescriptor* items)
{
  bool res = FALSE;
  if (client && items)
	{
	  res = TRUE;
	  unsigned i = 0;
	  while (items[i].type != View_None)
	  {
		 if (!createChild(client,items[i]))
			  res = FALSE;
		 i++;
	  };
	};
  return res;
};


bool ChildGenerator :: generate    (UI_CompositeVObject* client,
												UI_ViewDescriptor* * multi)
{
  bool res = FALSE;
  if (multi)
	{
	  unsigned i = 0;
	  while (multi[i])
			{
			  res *= generate(client,multi[i]);
			  i++;
			};
	};
  return res;
};


bool ChildGenerator :: operator () (UI_CompositeVObject*     client,
												const UI_ViewDescriptor* items)
{
  return generate(client,items);
};


bool ChildGenerator :: operator () (UI_CompositeVObject* client,
												UI_ViewDescriptor*   *multi)
{
  return generate(client,multi);
};


////////////////////


bool ChildGenerator :: createChild (UI_VObjCollection*       client,
												const UI_ViewDescriptor& vd)
{
  UI_VisualObject* p = create(client,vd);
  if (p)
		 return TRUE;
  else return FALSE;
};


bool ChildGenerator :: createChild (UI_CompositeVObject*     client,
												const UI_ViewDescriptor& vd)
{
  UI_VisualObject* p = create(client,vd);
  if (p)
	{
	  UI_ViewID id = p->ViewID();
	  if (id > 0 && id <= 32767  && vd.type != View_Composite)
		{
		  CL_IntPtrMap& map = (CL_IntPtrMap&)client->UI_CompositeVObject::Model();
		  map.Add(id,&(p->Model()));
		  p ->TabStop (vd.tab_stop);
		};
	  return TRUE;
	}
  else return FALSE;
};


UI_VisualObject* ChildGenerator :: create(UI_VObjCollection*     client,
														const UI_ViewDescriptor& vd)
{
  if (client->Contains(vd.id))
	{
	  CL_Error::Warning ("YACL: Duplicate child id %ld for composite",vd.id);
	  return NULL;
	};
  UI_VisualObject* p = NULL;
  UI_Rectangle shape (vd.shape.x, vd.shape.y, vd.shape.w, vd.shape.h);
  switch (vd.type)
  {
	 case View_OrButtonGroup:
		  p = new UI_OrButtonGroup (client, shape, vd.id, vd.enclosed);
		  p->Title () = vd.title;
		  break;

	 case View_ExOrButtonGroup:
		  p = new UI_ExOrButtonGroup (client, shape, vd.id, vd.enclosed);
		  p->Title () = vd.title;
		  break;

	 case View_PushButton:
		  p = new UI_PushButton (client, shape, vd.id);
		  p->Title()= vd.title;
		  break;

	 case View_ToggleButton:
		  p = new UI_ToggleButton (client, shape, vd.id);
		  p->Title() = vd.title;
		  break;

	 case View_ExOrToggleButton:
		  p = new UI_ExOrToggleButton (client, shape, vd.id);
		  p->Title() = vd.title;
		  break;

	 case View_Label:
		  p = new UI_Label (client, shape, vd.id);
		  ((UI_Label*) p)->Title () = vd.title;
		  break;

	 case View_StringEditor:
		  p = new UI_StringEditor (client, shape, vd.id);
		  ((CL_String&) (((UI_SimpleVObject*) p)->Model ())) = vd.title;
		  break;

	 case View_TextView:
		  p = new UI_TextEditor (client, shape, vd.id);
		  ((CL_String&) (((UI_SimpleVObject*) p)->Model ())) = vd.title;
        break;

	 case View_StringViewSingle:
		  p = new UI_StringViewSingleSel (client, shape, vd.id);
		  break;

	 case View_HScrollBar:
		  p = new UI_HScrollBar (client, shape, vd.id);
		  break;

	 case View_VScrollBar:
		  p = new UI_VScrollBar (client, shape, vd.id);
		  break;

	 case View_StringViewMulti:
		  p = new UI_StringViewMultiSel (client, shape, vd.id);
		  break;

	 case View_ComboBox:
		  p = new UI_ComboBox (client, shape, vd.id, shape.Height());
		  break;

	 case View_Composite:
		  p = new UI_CompositeVObject ((UI_CompositeVObject*)client, vd.enclosed,
												 TRUE, shape, vd.id);
		  break;

	 case View_3DLabel:
		  p = new UI_3DLabel (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_NumberLabel:
		  p = new NumberLabel (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_TextLabel:
		  p = new TextLabel (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_SelectableLabel:
		  p = new SelectableLabel (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_NumberEditor:
		  p = new UI_NumberEditor (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_ExtNumberEditor:
		  p = new ExtNumberEditor (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_BtnNumberEditor:
		  p = new BtnNumberEditor (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_DateEditor:
		  p = new UI_DateEditor (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_PasswordEditor:
		  p = new UI_PasswordEditor (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_BitmapPushButton:
		  p = new UI_BitmapPushButton (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_BitmapToggleButton:
		  p = new UI_BitmapToggleButton (client, shape, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_Table:
		  p = new TableView (client, shape, 20, vd.id);
		  p->Title () = vd.title;
		  break;

	 case View_LinkedSingleSel:
		  p = new LinkedSingleSel (client, shape, vd.id);
		  break;

	 case View_LinkedMultiSel:
		  p = new LinkedMultiSel (client, shape, vd.id);
		  break;

	 case View_LinkedCombo:
		  p = new LinkedCombo (client, shape, vd.id, shape.Height());
		  break;

	 case View_Group:
		  p = new Group (client,shape,vd.id,vd.enclosed,vd.title);
		  break;

	 case View_Chart:
		  p = new Chart (client,shape,vd.id,vd.title);
		  break;
	};
	return p;
};


// ******************
// mit Positionierung
// ******************



bool ChildGenerator :: appendRight (UI_CompositeVObject* client,
												UI_ViewDescriptor*   children)
{
  bool res = FALSE;
  if (client && children)
	{
	  long Correction = client->Shape().Width();
	  if (Correction)
			shiftNew(&UI_RectangleStruct::x,children,Correction);
	  generate(client,children);
	  if (Correction)
			shiftNew(&UI_RectangleStruct::x,children,Correction*(-1));
	  reshape(client);
	  res = TRUE;
	};
  return res;
};


bool ChildGenerator :: appendLeft  (UI_CompositeVObject* client,
												UI_ViewDescriptor*   children)
{
  bool res = FALSE;
  if (client && children)
	{
	  unsigned Correction = maxPos( children,
											  &UI_RectangleStruct::x,
											  &UI_RectangleStruct::w
											);
	  if (Correction)
		{
		  shiftOld(client,&UI_RectangleStruct::x,Correction);
		  generate(client,children);
		  reshape(client);
		  res = TRUE;
		};
	};
  return res;
};


bool ChildGenerator :: appendBottom(UI_CompositeVObject* client,
												UI_ViewDescriptor* children)
{
  bool res = FALSE;
  if (client && children)
	{
	  long Correction = client->Shape().Height();
	  if (Correction)
			shiftNew(&UI_RectangleStruct::y,children,Correction);
	  generate(client,children);
	  if (Correction)
			shiftNew(&UI_RectangleStruct::y,children,Correction*(-1));
	  reshape(client);
	  res = TRUE;
	};
  return res;
};


bool ChildGenerator :: appendTop   (UI_CompositeVObject* client,
												UI_ViewDescriptor* children)
{
  bool res = FALSE;
  if (client && children)
	{
	  long Correction = maxPos( children,
										 &UI_RectangleStruct::y,
										 &UI_RectangleStruct::h
									  );
	  if (Correction)
		{
		  shiftOld(client,&UI_RectangleStruct::y,Correction);
		  generate(client,children);
		  reshape(client);
		  res = TRUE;
		};
	};
  return res;
};


long     ChildGenerator :: maxPos(UI_ViewDescriptor*         children,
											 long UI_RectangleStruct:: * pos1,
											 long UI_RectangleStruct:: * pos2
											 )
{
  long max = 0;
  if (children && pos1 && pos2)
	{
	  unsigned i = 0;
	  int      p;
	  while (children[i].type != View_None)
			{
			  p = children[i].shape.*pos1 + children[i].shape.*pos2;
			  if (p > max)
					max = p;
			  i++;
			};
	};
  return max;
};


void ChildGenerator :: shiftNew  (long UI_RectangleStruct:: * pos,
											 UI_ViewDescriptor*         children,
											 long corr
											 )
{
  if (children && pos)
	{
	  unsigned i = 0;
	  while (children[i].type != View_None)
			{
			  children[i].shape.*pos += corr;
			  i++;
			};
	};
  return;
};


void ChildGenerator :: shiftOld  (UI_CompositeVObject* client,
											 long UI_RectangleStruct:: * pos,
											 long corr
											 )
{
  if (client && pos)
	{
	  UI_RectangleStruct tmp;
	  UI_VObjCollIterator Iter(*client);
	  UI_VisualObject* chld = Iter.Next();
	  while (chld)
			{
			  tmp.x = chld->Shape().Left();
			  tmp.y = chld->Shape().Top();
			  tmp.w = chld->Shape().Width();
			  tmp.h = chld->Shape().Height();
			  tmp.*pos += corr;
			  chld->Shape() = tmp;
			  chld->Invalidate();
			  chld = Iter.Next();
			};
	};
  return;
};


void ChildGenerator :: reshape(UI_CompositeVObject* client)
{
  if (client)
	{
	  UI_VObjCollIterator Iter(*client);
	  UI_VisualObject* chld = Iter.Next();
	  long MaxW = 0;
	  long MaxH = 0;
	  long cmp;
	  while (chld)
		{
		  cmp = chld->Shape().Left() + chld->Shape().Width();
		  if (cmp > MaxW)
				MaxW = cmp;
		  cmp = chld->Shape().Top() + chld->Shape().Height();
		  if (cmp > MaxH)
				MaxH = cmp;
		  chld = Iter.Next();
		};
	  UI_RectangleStruct rs = { client->Shape().Left(),
										 client->Shape().Top(),
										 MaxW+10,
										 MaxH+10
									  };
	  client->Shape() = rs;
	};
  return;
};


