#include "datawind.h"
#include "struc/diction.h"
#include "struc/starasso.h"
#include "struc/iterator.h"
#include "gui/button.h"
#include "gui/label.h"
#include "struc/llistobj.h"
#include "starappl.h"
#include "struc/starpasr.h"
#include "stardraw.h"

#define MAXDATABLOCKNAMELENGTH 40
#define NUMOFROW 30
#define GET_WIDTH(width, row) (((width)*6)+50+(((row)>NUMOFROW?1:0)*30))
#define GET_HEIGHT(row) (((row)>NUMOFROW?NUMOFROW:(row))*28+20)



@implementation WDCGUIObject (WDCGUIObject)

- getRootDataBlockObject
{
  id parent=[self getParentObject];
  return [parent isKindOfClassNamed:"WDCMenu"]?
    [self getChildObject]:[parent getRootDataBlockObject];
}

- getDataBlockObject
{
  id iter, object, parent;
  parent=[self getParentObject];
  if ([[parent getChildObject] isKindOfClassNamed:"WDCStarDataBlock"])
    {
//      printf("%s\n",[[self getChildObject] getName]);
      return [parent getChildObject];
    }  
  else return [parent getDataBlockObject];
}

- getDataBlockContentObject
{
  id iter, object, parent;
  parent=[self getParentObject];
  if ([[[[[parent getParentObject] getParentObject] getParentObject]
	getChildObject] isKindOfClassNamed:"WDCStarDataBlock"])
    {
      return [self getChildObject];
    }  
  else return [parent getDataBlockContentObject];
}

@end


@implementation WDCString (WDCGUIString)

-  buildDataWindowNamed:(char*)aName managedBy:anObject
{
  char refName[MAXDATABLOCKNAMELENGTH];
  if (!strcmp(aName, "")) aName=(char*)[self cStringValue];
  if (![self getDisplayWindow])
    [self setDisplayWindow :[[WDCPopupBox alloc] 
			     initWithName : aName managedBy : anObject]];
  aName=(char*)[self cStringValue];
  if (aName[0]!='$')
    [[WDCLabel alloc] 
     initWithName : aName managedBy : [self getDisplayWindow]];
  else
    {
      strcpy(refName, "save_");
      strcat(refName, ++aName);
      [[[[[self getDisplayWindow] 
	  getDataBlockContentObject] getItemNamed : refName] getValue]
       buildDataWindowNamed : refName managedBy :
       [[WDCToggleButton alloc]
	initWithName : --aName managedBy : [self getDisplayWindow]]];
    } 
  return self;
}

- setDisplayWindow: anWindow
{
  return [self setAppSpecObject: anWindow];
}

- getDisplayWindow
{
  return [self getAppSpecObject];
}

@end



@implementation WDCLineBuffer (WDCGUILineBuffer)

- buildDataWindowNamed:(char*)aName managedBy:anObject
{
  [anObject setChildObject:self];
  if (!aName) aName=(char*)[self name];
  if (![self getDisplayWindow])
    [self setDisplayWindow:[[WDCVariablePopupBox alloc] 
			    initWithName : aName managedBy : anObject]];
  return self;
}

- manage
{
  int numLines, width, lineWidth;
  char* string;
  id iter, window=[self getDisplayWindow];
  numLines=width=0;
  if (![window getChildren])
    {
      iter=[[WDCListIterator alloc] initFrom:self];
      while ([iter goNext])
	{
	  numLines++;
	  string=(char*)[[iter getCurrentObject] cStringValue];
	  lineWidth=strlen(string);
	  if (lineWidth>width) width=lineWidth;
	  [[WDCLabel alloc] initWithName : string managedBy : window];
	}
      [[window setArg:"width" to:(char*)GET_WIDTH(width, numLines)]
       setArg : "height" to:(char*)GET_HEIGHT(numLines)];
      [iter free];
    }
  [window manage];
  return self;
}

- unManage
{
  [[self getDisplayWindow] unManage];
  return self;
}

- setDisplayWindow: anWindow
{
  return [self setAppSpecObject: anWindow];
}

- getDisplayWindow
{
  return [self getAppSpecObject];
}

@end


@implementation WDCLListOfObject (WDCGUILListOfObject)

- buildDataWindowNamed:(char*)aName managedBy:anObject
{
  [anObject setChildObject:self];
  if (!aName) aName=(char*)[self name];
  if (![self getDisplayWindow])
    [self setDisplayWindow:[[WDCVariablePopupBox alloc] 
			    initWithName : aName managedBy : anObject]];
  return self;
}

- manage
{
  int numValues=0;
  id iter, tempId, window=[self getDisplayWindow];
  if (![window getChildren])
    {
      iter=[[WDCListIterator alloc] initFrom:self];
      while ([iter goNext])
	{
	  numValues++;
	  tempId=[[WDCToggleButton alloc] 
		  initWithName : "Value" managedBy : window];
	  [[[iter getCurrentObject] getContent] 
	   buildDataWindowNamed : ""
	   managedBy : tempId];
	}
      [[window setArg:"width" to:(char*)GET_WIDTH(5, numValues)]
       setArg :"height" to:(char*)GET_HEIGHT(numValues)];
      [iter free];
    }
  [window manage];
  return self;
}

- unManage
{
  [[self getDisplayWindow] unManage];
  return self;
}

- setDisplayWindow: anWindow
{
  return [self setAppSpecObject: anWindow];
}

- getDisplayWindow
{
  return [self getAppSpecObject];
}

@end


@implementation WDCStarItemAssocValue (WDCGUIStarItemAssocValue)

- buildDataWindowNamed:(char*)aName managedBy:anObject
{
  [anObject setChildObject:self];
  if (!aName) aName=(char*)[self name];
  if (![self getDisplayWindow])
    [self setDisplayWindow:[[WDCStarDrawBox alloc] 
			    initWithName : aName 
			    managedBy : anObject]];
  return self;
}

- manage
{
  char * aName;
  char blockName[MAXDATABLOCKNAMELENGTH];
  id iter, PopupId, currentId, dictionaries, 
  window=[self getDisplayWindow], drawArea;
  if (![window getChildren]){
    drawArea=[window getDrawArea];
    dictionaries=[[[window getApplicationObject] 
		   getSTARParser] getDictionaryList];
    iter=[[WDCListIterator alloc] initFrom:self];
    while ([iter goNext]){
      currentId=[iter getCurrentObject];
      strcpy(blockName, "data");
      aName=(char*)[currentId getName];
      if (aName[0]!='\'')
	strcat(blockName, aName);
      else
	strncat(blockName, &aName[1], strlen(aName)-2);
      [currentId 
       setItem : [dictionaries getDefinitionBlockAtKey:blockName]];
      PopupId=[[[currentId getItem] getValue] 
	       buildDataWindowNamed : blockName
	       managedBy : window];
      [drawArea addDrawObject:[currentId getNameString]
       with :PopupId];
      if ([[currentId getValue] isKindOfClassNamed:"WDCString"]){
	aName=(char*)[[currentId getValue] cStringValue];
	if (aName[0]!='$')
	  PopupId=0;
	else {
	  strcpy(blockName, "save_");
	  strcat(blockName, ++aName);
	  PopupId=[[[[[self getDisplayWindow] 
		      getDataBlockContentObject] getItemNamed : blockName] 
		    getValue] buildDataWindowNamed : blockName 
		   managedBy : window];
	} 
	[drawArea addDrawObject:[currentId getValue] with :PopupId];
      }
      else
	[drawArea addDrawObject:[[WDCString alloc] initFromCString:"table"]
	 with :[[currentId getValue] 
		buildDataWindowNamed : blockName
		managedBy : window]];	
    }
    [iter free];
    [window setDimension];
    [window draw]; // not display yet, so we don't need a real window yet.
    if (![window getChildObject])  // to stop this action from next invokation.
      [window setChildObject:self];
  }
  [window manage];
  return self;
}

- (BOOL)isManaged
{
  return [[self getDisplayWindow] isManaged];
}

- unManage
{
  [[self getDisplayWindow] unManage];
  return self;
}

- setDisplayWindow: anWindow
{
  return [self setAppSpecObject: anWindow];
}

- getDisplayWindow
{
  return [self getAppSpecObject];
}

@end


@implementation WDCStarDataBlock (WDCGUIStarDataBlock)


- buildDataWindowNamed:(char*)aName managedBy:anObject
{
  [anObject setChildObject:self];
  if (!aName) aName=(char*)[self name];
  if (![self getDisplayWindow])
    [self setDisplayWindow:[[WDCVariablePopupBox alloc] 
			    initWithName : aName 
			    managedBy : anObject]];
  return self;
}

- manage
{
  char * aName;
  int nameLength, width, numButton;
  id iter, tempId, currentId, window=[self getDisplayWindow];
  width=numButton=0;
  if (![window getChildren])
    {
      iter=[[WDCListIterator alloc] initFrom:self];
      while ([iter goNext])
	{
	  numButton++;
	  currentId=[iter getCurrentObject];
	  aName=(char*)[currentId getName];
	  nameLength=strlen(aName);
	  if (nameLength>width) width=nameLength;
	  tempId=[[WDCToggleButton alloc] 
		  initWithName :  aName 
		  managedBy : window];
	  [[currentId getValue]  
	   buildDataWindowNamed : aName
	   managedBy : tempId];
	}
      [iter free];
      [[window setArg:"width" to:(char*)GET_WIDTH(width, numButton)]
       setArg : "height" to:(char*)GET_HEIGHT(numButton)];
    }
  [window manage];
  return self;
}

- setDisplayWindow: anWindow
{
  return [self setAppSpecObject: anWindow];
}

- getDisplayWindow
{
  return [self getAppSpecObject];
}

@end


@implementation WDCDictionary (WDCGUIDictionary)

- buildDataWindowNamed:(char*)aName managedBy:anObject
{
  [anObject setChildObject:self];
  if (!aName) aName=(char*)[self name];
  if (![self getDisplayWindow])
    [self setDisplayWindow:[[WDCVariablePopupBox alloc] 
			    initWithName : aName 
			    managedBy : anObject]];
  return self;
}

- manage
{
  char* aName;
  int nameLength, width, numButton;
  id iter, tempId, currentId, window=[self getDisplayWindow];
  width=numButton=0;
  if (![window getChildren])
    {
      iter=[[WDCListIterator alloc] initFrom:self];
      while ([iter goNext])
	{
	  numButton++;
	  currentId=[iter getCurrentObject];
	  aName=(char*)[currentId getName];
	  nameLength=strlen(aName);
	  if (nameLength>width) width=nameLength;
	  tempId=[[WDCToggleButton alloc] 
		  initWithName :  aName 
		  managedBy : window];
	  [[currentId getValue]  
	   buildDataWindowNamed : aName
	   managedBy : tempId];
	}	
      [iter free];
      [[window setArg:"width" to:(char*)GET_WIDTH(width, numButton)]
       setArg : "height" to:(char*)GET_HEIGHT(numButton)];
    }
  [[self getDisplayWindow] manage];
  return self;
}

- unManage
{
  [[self getDisplayWindow] unManage];
  return self;
}

- setDisplayWindow: anWindow
{
  return [self setAppSpecObject: anWindow];
}

- getDisplayWindow
{
  return [self getAppSpecObject];
}

@end


