/*
 *  FormatterWind.pi.c
 *  PeekIt
 *
 *  Created by C.K. Haun on 11/25/05.
 *  Copyright 2005 Ravenware Software. All rights reserved.
 *
 */



enum{
    kFormatListScroll =2000,
    kFormatBuildScroll,
    /* these are embedded in the build view */
    kFormatBuildTypePU = 2100,
    kFormatSignedCB,
    kFormatLilEndianCB,
    kFormatHexCB,
    kFormatEditLine,
    kFormViewTitleText  =  4550
};
#define __FormatPeekWINDOW__

#include "PeekIt.h"

// formatter standard data sizes
SInt32 FormatterDataStandardLengths[]={1,2,4,1,-1,-1,1
};

extern PeekitStructFormatterPtr gFormatters;
void InstallFormatterWindKeyHandlers(WindowRef theWindow);


void HitFormatWWIND(WindowRef theWindow, Point *thePoint);


struct FormatWWindData {
    CGRect FormatterListViewRect;
    HIViewRef FormatterListView;
    ControlRef fListScroll;
    CGRect FormatterBuildViewRect;
    HIViewRef FormatterBuildView;
    ControlRef fBuildScroll;
    ControlRef floatingEdit;
    ControlRef buildFloatingEdit;
    ControlRef typePU;
    SInt16 selected;
    SInt16 buildSelected;
    PeekitStructFormatterPtr currentFormatter;
    
};
typedef struct FormatWWindData FormatWWindData;
typedef FormatWWindData *FormatWWDataP/* , **FormatWWDataH */;
/* protos */


static void ReArrangeFormatWWControls(WindowRef theWindow, FormatWWDataP nowCD);
static void SizeFormatWWINDControls(WindowRef theWindow);
static void SetUpFormatterWindowMenus(FormatWWDataP nowCD,UInt32 theID);


#include "formatterlistview.pi.c"
#include "formatterbuildview.pi.c"


void CalcFormatScrollBars(WindowRef theWindow,FormatWWDataP nowCD);
void MakePIFormatterFile(FormatWWDataP nowCD);


OSStatus FormatWWindowDrawingCode(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
    OSStatus myStatus = noErr;
    CallNextEventHandler(
                         inHandlerCallRef,
                         inEvent);
    
    return(myStatus);
    
}
OSStatus FormatWWindowClickCode(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData);

OSStatus FormatWWindowClickCode(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
    OSStatus myStatus = noErr;
    // extract the mouse
    Point theMouse;
    mPushPort((WindowRef)inUserData)
        
        GetEventParameter (inEvent, kEventParamMouseLocation, typeQDPoint,
                           NULL, sizeof(Point), NULL, &theMouse);
    
    // now hand off
    // TEST TEMP get the mouse
    // GetMouse(&theMouse);  // I should not have to get the mouse again
    HitFormatWWIND((WindowRef)inUserData,&theMouse);
    mPullPort
        
        CallNextEventHandler(
                             inHandlerCallRef,
                             inEvent);
    
    return(myStatus);
    
}
OSStatus FormatWWindowStateChangeCode(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
    OSStatus myStatus = noErr;
    ZapPort((WindowRef)inUserData);
    CallNextEventHandler(
                         inHandlerCallRef,
                         inEvent);
    
    return(myStatus);
    
}
OSStatus FormatWWindowSizeCode(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
    OSStatus myStatus = noErr;
    
    SizeFormatWWINDControls((WindowRef) inUserData);
    
    CallNextEventHandler(
                         inHandlerCallRef,
                         inEvent);
    
    return(myStatus);
    
}
OSStatus FormatWWindowCloseCode(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
    OSStatus myStatus = noErr;
    // just hide the window
    WindowRef theWindow=(    WindowRef) inUserData;
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;

    
    HideWindow((WindowRef)inUserData);
    
    
    return(myStatus);
    
}

OSStatus FormatWWindowSpecialCode(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{
    OSStatus myStatus = noErr;
    
    HICommand commandStruct;
    GetEventParameter (inEvent, kEventParamDirectObject,
                       kEventClassWindow, NULL, sizeof(HICommand),
                       NULL, &commandStruct);
    
    CallNextEventHandler(
                         inHandlerCallRef,
                         inEvent);
    
    return(myStatus);
    
}






OSStatus InstallFormatWWindowHandlers(
                                      WindowRef theWindow,
                                      void * refCon,
                                      ULong flags)

{
    OSStatus myErr = noErr;
    long realRefCon = 0;
    EventHandlerRef windowOutRef;
    EventTypeSpec  windowDrawEventList[1]={{kEventClassWindow,kEventWindowDrawContent}};
    
    EventTypeSpec  windowStateEventList[2]={{kEventClassWindow,kEventWindowActivated},{kEventClassWindow,kEventWindowDeactivated}};
    
    EventTypeSpec  windowSizeEventList[1]={{kEventClassWindow,kEventWindowBoundsChanged}};
    
    EventTypeSpec  windowCloseEventList[1]={{kEventClassWindow,kEventWindowClose}};
    
    //    EventTypeSpec  windowSpecialEventList[1]={{kEventClassWindow,kEventWindowContextualMenuSelect}};
    
    EventTypeSpec  windowClickEventList[1]={   {kEventClassWindow,kEventWindowHandleContentClick}};
    
    if(refCon == NULL)realRefCon = (long)theWindow;
    // we should collect all these event refs in the window data struct
    myErr = InstallEventHandler (GetWindowEventTarget (theWindow), NewEventHandlerUPP(FormatWWindowDrawingCode),     sizeof(windowDrawEventList)/sizeof(EventTypeSpec),    &windowDrawEventList,     (void *)theWindow,   &windowOutRef);
    
    myErr = InstallEventHandler (GetWindowEventTarget (theWindow), NewEventHandlerUPP(FormatWWindowClickCode),     sizeof(windowClickEventList)/sizeof(EventTypeSpec),    &windowClickEventList, (void *)theWindow,      &windowOutRef);
    
    myErr = InstallEventHandler (GetWindowEventTarget (theWindow), NewEventHandlerUPP(FormatWWindowStateChangeCode),     sizeof(windowStateEventList)/sizeof(EventTypeSpec),    &windowStateEventList, (void *)theWindow,      &windowOutRef);
    
    myErr = InstallEventHandler (GetWindowEventTarget (theWindow), NewEventHandlerUPP(FormatWWindowSizeCode),     sizeof(windowSizeEventList)/sizeof(EventTypeSpec),    &windowSizeEventList, (void *)theWindow,      &windowOutRef);
    
    myErr = InstallEventHandler (GetWindowEventTarget (theWindow), NewEventHandlerUPP(FormatWWindowCloseCode),     sizeof(windowCloseEventList)/sizeof(EventTypeSpec),    &windowCloseEventList, (void *)theWindow,      &windowOutRef);
    
    // taking the special out for a miunutes
    // myErr = InstallEventHandler (GetWindowEventTarget (theWindow), NewEventHandlerUPP(FormatWWindowSpecialCode),     sizeof(windowSpecialEventList)/sizeof(EventTypeSpec),
    // &windowSizeEventList, (void *)theWindow,      &windowOutRef);
    
    myErr = InstallStandardEventHandler(GetWindowEventTarget (theWindow));
    
    
    
    return(myErr);
    
}






void DrawFormatWWIND(WindowRef theWindow, EventRecord *theEvent)
{
}



void HitFormatWWIND(WindowRef theWindow, Point *thePoint)
{
    
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    Point theP;
}


void PrepEditFormatWWIND(WindowRef theWindow, Boolean *theEdits)
{
#if 0
#pragma unused (theEdits )
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    FormatWWDataH nowCD = (FormatWWDataH)(*tempWC)->dataStore;
    /* file */
    // EnableItem(GetMHandle(kFileMenu),kSave);
    EnableItem(GetMenuHandle(kFileMenu), kSaveAs);
    EnableItem(GetMenuHandle(kFileMenu), kPrint);
    /* edit */
    
    if ((*(*tempWC)->undoAction)->undoWhat)
        EnableItem(GetMenuHandle(kEditMenu), kUndo);
    //    if (objSelected(theWindow)) {
    // cut/copy the screen text on demand
    EnableItem(GetMenuHandle(kEditMenu), kCut);
    EnableItem(GetMenuHandle(kEditMenu), kCopy);
    //        EnableItem(GetMenuHandle(kEditMenu), kClear);
    //    }
    EnableItem(GetMenuHandle(kEditMenu), kSelectAll);
    EnableItem(GetMenuHandle(kEditMenu), kClipBoard);
    EnableItem(GetMenuHandle(kCompanionMenu),1);
    
#endif
}
void CalcFormatBuildScrollBar(WindowRef theWindow,FormatWWDataP nowCD){
    UInt32  theNum=0;
    SInt16     numRows =0;
    SInt16 numFormatters = 0;
    SInt16 remainder = 0;
    UInt32 max,value;
    GetControlData(
                   nowCD->FormatterBuildView,
                   88,
                   kslibHIViewCellHeight,
                   sizeof(theNum),
                   &theNum,
                   0);
    // figure it out
    numRows = nowCD->FormatterBuildViewRect.size.height/theNum;
    numFormatters = CountDataFormattersInThisStructFormatter(nowCD->currentFormatter)+1;
    remainder=    numFormatters-numRows;
    if(remainder <0)remainder = 0;
    SetControlMaximum(nowCD->fBuildScroll,remainder);
    if(remainder == 0)SetControlValue(nowCD->fBuildScroll,0);
    
    
    
}

void CalcFormatListScrollBar(WindowRef theWindow,FormatWWDataP nowCD)
{UInt32  theNum=0;
    SInt16     numRows =0;
    SInt16 numFormatters = 0;
    SInt16 remainder = 0;
    UInt32 max,value;
    GetControlData(
                   nowCD->FormatterListView,
                   88,
                   kslibHIViewCellHeight,
                   sizeof(theNum),
                   &theNum,
                   0);
    // figure it out
    numRows = nowCD->FormatterListViewRect.size.height/theNum;
    numFormatters = CountAllStructureFormatters();
    remainder=    numFormatters-numRows;
    if(remainder <0)remainder = 0;
    SetControlMaximum(nowCD->fListScroll,remainder);
    if(remainder == 0)SetControlValue(nowCD->fListScroll,0);
}
void CalcFormatScrollBars(WindowRef theWindow,FormatWWDataP nowCD)
{
    CalcFormatListScrollBar( theWindow, nowCD);
    CalcFormatBuildScrollBar( theWindow, nowCD);
    
}

void DoFormatterExport(WindowRef theWindow,FormatWWDataP nowCD, UInt32 selector)
{
    Str15 theX ="\ppiform";
    long theCount;
    short exportFormatterRefNum;
    OSStatus myErr = noErr;
    FileTrackerPtr newFile =   SimplePutFile(CFSTR("Create a formatter file"),"\puntitled",'RWp1','PIFM',theX);
    
    
    
    if(newFile){
        InitMFile(newFile->fsSpec);
        myErr = OpenMFile(newFile->fsSpec,fsRdWrPerm, &exportFormatterRefNum);
        if(myErr == noErr){
            // all or nothing
            if(selector == kExportAllFormatters ){
                PeekitStructFormatterPtr startHere;
                startHere=gFormatters;
                while(startHere){
                        // save this one
                        GRACPtr theCriteria = startHere->theCriteria;
                        
                        Ptr flatHead =  FlattenFormatter(startHere);
                        
                        
                        myErr= SaveMEntry(exportFormatterRefNum,  theCriteria,  flatHead, ((FlatFormatterHeader *)flatHead)->lenFlattened);
                        // I'ma gonna clear the flag just because
                    
                    startHere = startHere->next;
                }
                
                CloseMFile(exportFormatterRefNum);
                
                
            } else {
            // just the one
                GRACPtr theCriteria = nowCD->currentFormatter->theCriteria;
                
                Ptr flatHead =  FlattenFormatter(nowCD->currentFormatter);
                
                
                myErr= SaveMEntry(exportFormatterRefNum,  theCriteria,  flatHead, ((FlatFormatterHeader *)flatHead)->lenFlattened);
                
                CloseMFile(exportFormatterRefNum);

            }
            
        }
        
    }
    
    
    
}

Boolean getFormattterFilter(AEDesc *theItem, void *info, void *callBackUD, NavFilterModes filterMode)
{Boolean retVal = true;
    NavFileOrFolderInfo * theInfo = info;
    
    // look at the info and See
    if(theItem->descriptorType == typeFSS || theItem->descriptorType==typeFSRef){
        if(theInfo->isFolder == true)return(true);
        if(theInfo->fileAndFolder.fileInfo.finderInfo.fdType ==  'PIFM'&&theInfo->fileAndFolder.fileInfo.finderInfo.fdCreator =='RWp1' ){
            return(true);
        } else {
            return(false);
        }
    }
    return(retVal);
}


// have to be sensitive to saved unique IDs and potentially embedded formatters
void OpenAndAddFormatters(FileTrackerPtr theFile)
{
    short formatterRefNum;
 PeekitStructFormatterPtr   tempgFormatters=0;
OSStatus myErr=0;    
// get the file
FileTrackerPtr  theFT;
Str255 prompt="\pSelect a changes file";
Str255 windowName="\pApply a changes file";
Str15 exten="\ppiform";
myErr= SimpleGetFileII(&theFT, &prompt,&windowName, getFormattterFilter, 0,0);

if(myErr == noErr){
myErr = OpenMFile(theFT->fsSpec,fsRdWrPerm, &formatterRefNum);
    if(myErr == noErr){
        UInt32 numFFMs=0;
        PeekitStructFormatterPtr startHere;
        // actually, don't do shit I guess
        // well wait, we can at least, oh nevermind
        //mFillCompare(gTempCompare, 'BMHD',1, 0, 0);
        // ok, yes I do want to do something.  Load the headers
        numFFMs=        CountMEntries(formatterRefNum,kPIFlatFormatter);
        if(numFFMs){
            ULong counter=0;
            // load all the headers in
            do{
                GRACPtr returnedCriteria= calloc(1,sizeof(GRACompare));
                Handle theFFM;
                PeekitStructFormatterPtr theFormatter;
                theFFM =  ReadIndexedMEntry(formatterRefNum,counter,kPIFlatFormatter,returnedCriteria);
                // now make it a pointer and copy it
                
                theFormatter = ExpandFlatFormatter(*theFFM);
                DisposeHandle((Handle)theFFM);
                // add the gracompare
                theFormatter->theCriteria=returnedCriteria;
                // mark it as changed
                theFormatter->flags |=            kPIStructChanged;
                if(tempgFormatters == 0){
                    tempgFormatters=theFormatter;
                } else {
                    // go to the end and tack this one on
                    startHere = tempgFormatters;
                    while(startHere->next)startHere = startHere->next;
                    startHere->next = theFormatter;
                    theFormatter->previous = startHere;
                    
                }
                
                
                numFFMs--;
                counter++;
            } while(numFFMs);
// lets look at all the formatters and see if there are any id collisions            
            startHere = tempgFormatters;
            while(startHere){
                if(GetPIStructFormatterByID(startHere->uniqueID)){
                // collision.  Resolve, and see if anyone has embedded the original  I think that's easy enough
                    UInt32 savedUniqueID = startHere->uniqueID;
                    UInt32 newUniqeID;
                    // get a new one
                    startHere->uniqueID = 0;
                    AddUniqueIDToThisStructFormatter(startHere);
                    newUniqeID=startHere->uniqueID;
                    // now see if anyone is holding oldUID, if so, replace with newUID;
                    // and remember, we're loloking inside
                    {PeekitStructFormatterPtr notehrLooper = tempgFormatters;
                        PIDataFormatterPtr innerData;
                        while(notehrLooper){
                            innerData = notehrLooper->formatters;
                            while(innerData){
                            if(innerData->dataType == -2 && innerData->embeddedFormatterUniqueID == savedUniqueID ){
                                innerData->embeddedFormatterUniqueID= newUniqeID;
                                innerData->embeddedFormatter = startHere;
                                // and the pointer
                            }
                                innerData = innerData->next;
                            }
                            notehrLooper = notehrLooper->next;
                        }
                    }
                    
                }
                startHere = startHere->next;
            }
        // now link to the rest of the formatters already in place
            // go to the end of gformatters
            startHere = gFormatters;
            if(startHere){
                while(startHere->next)startHere = startHere->next;
                startHere->next = tempgFormatters;
                tempgFormatters->previous = startHere;
            } else {
                gFormatters = tempgFormatters;
            }
        // and ask our clients to update;
            // is the formatter window open?
WindowRef            FormatWWINDWindow= FindWindowByKind(kFormatWWINDWindow);
            if(FormatWWINDWindow){
                WCH tempWC = (WCH)GetWRefCon(FormatWWINDWindow);
                FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
                HIViewSetNeedsDisplay(
                                      nowCD->FormatterListView,
                                      true);
// update the menus.  Urg
                UpdateAllValDrawerPopups();

            }
        }
        CloseMFile(formatterRefNum);
        DisposeFileTracker(theFT);
    }
}

    
}
void SizeFormatWWIND(WindowRef theWindow, EventRecord *theEvent, short how)
{
#pragma unused (theEvent )
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    
    mPushPort(theWindow)
        SizeFormatWWINDControls(theWindow);
    mPullPort
}

//  save the current screen snapshot
void SaveFormatWWIND(WindowRef theWindow, Boolean as)
{
    
}

void IdleFormatWWIND(WindowRef theWindow, Boolean front)
{
    
#pragma unused (front )
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    LoopVar qq;
    
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    
}

void KeyFormatWWIND(WindowRef theWindow, EventRecord *theEvent)
{
    
}

Boolean EditFormatWWINDWindow(WindowRef theWindow, EventRecord *theEvent, short editAction)
{
#pragma unused (theEvent )
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    Boolean retVal = false;
    
    switch (editAction) {
        case kCut:
        case kCopy:
            // spit the screen text to the clipboard
            //	PutScrap(320,'TEXT',&(nowCD)->alltext[0]);
            // PutScrapFlavor(  0,  'TEXT',  0,  320, &(nowCD)->alltext[0]);
            
            
            return(retVal);
    }
    return(retVal);
}

void SendFormatWWINDBoard(void)
{
    
}

void invalFormatWWIND(void)
{
    WindowRef theW = FindWindowByKind(kFormatWWINDWindow);
    mPushPort(theW)
        ZapPort(theW);
    mPullPort
}

OSErr AEFormatWWIND(WindowRef theWindow, AppleEvent *Event)
{
#pragma unused (theWindow,Event )
    OSErr  myErr = noErr;
    
    return(myErr);
}
void  CommandFormatWWIND(WindowRef theWindow, EventRef inEvent,void *inUserData,HICommand *commandStruct)
{
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    // switch on the command
    switch((commandStruct->commandID)){
deafult:
#ifndef __FINAL__
        DebugStr("\p command in FormatW window defaulted");
#endif
        break;
    }
    
}
void GenFormatWWIND(WindowRef theWindow, UShort selector, void *theData)
{
#pragma unused (theWindow,theData )
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    WindowPrefStructHdl thePrefs;
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    LoopVar qq;
    switch (selector) {
        case kMenuGeneral:
            break;
        case kwmgActContHit:
            // coming forward mouse hit, so use it as well
            SetPort(theWindow);
            HitFormatWWIND( theWindow,nil);
            break;
            
        case kwmgSetUpMenus:
            SetUpFormatterWindowMenus(nowCD,theData);
            break;
            
        case kwmgUpdatePrefs: 
            // no prefs
            break;
        case kOpenAddFormatters:
            OpenAndAddFormatters(0);

            break;
        case kExportThisFormatter:
        case kExportAllFormatters:
            DoFormatterExport(theWindow,nowCD,selector);
            break;
    }
}

void CloseFormatWWIND(WindowRef theWindow, Boolean kill)
{
#pragma unused (kill )
    LoopVar qq;
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    SaveWindowVitalStats(theWindow,CFSTR("FMSTANDARDSTATE"));
    // save the columnrights
    FormatterBuildViewData* theNum;          
    UInt16 * colRs = malloc(sizeof(UInt16)*6);
    UInt16 * hold = colRs;
    GetControlData(
                   nowCD->FormatterBuildView,
                   88,
                   kslibReturnViewRefCon,
                   sizeof(theNum),
                   &theNum,
                   0);
    
    for(qq=0;qq<6;qq++){
        *colRs = theNum->columnRightsCG[qq];
        colRs = colRs + 1;
    }
    // save it
    {
     CFDataRef   colDataRs = CFDataCreate (
                                    0,
                                    hold,
                                    (sizeof(UInt16)*6)
                                    );
        CFStringRef colsrKey = CFSTR("BuildColRights");
        CFPreferencesSetAppValue(colsrKey, colDataRs,
                                 kCFPreferencesCurrentApplication);
    }
    HideWindow(theWindow);
    
}


static  OSStatus FormatNewHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    
    return(myErr);
}    
static  OSStatus FormatDeleteHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    
    return(myErr);
}    
static  OSStatus FormatDupHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    
    return(myErr);
}    
static  OSStatus FormatLoadHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    
    return(myErr);
}    
static  OSStatus FormatSaveHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    
    return(myErr);
}  
// this one selects the added formatter

static  OSStatus FormatListPlusEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    UInt16 ookl=1;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData); 
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    // add a new formatter
    PeekitStructFormatterPtr startHere = gFormatters;
    PeekitStructFormatterPtr newOne=calloc(1,sizeof(PeekitStructFormatter));
    AddUniqueIDToThisStructFormatter(newOne);
    newOne->flags |=            kPIStructChanged;
    {    GRACPtr theCriteria=calloc(1,sizeof(GRACompare));
        theCriteria->      unitType=kPIFlatFormatter;
        theCriteria->compare1 = newOne->uniqueID;
        newOne->theCriteria = theCriteria;
    }
    newOne->title =  CFStringCreateWithPascalString(0,"\pNew formatter",0);
    newOne->description=CFStringCreateWithPascalString(0,"\pempty",0);
    
    if(startHere){
        while( startHere->next){startHere= startHere->next;ookl++;}
        startHere->next= newOne;
        newOne->previous = startHere;
    } else {
        gFormatters=newOne;
        ookl=0;
    }
    //    SetControlMaximum(nowCD->fListScroll,GetControlMaximum(nowCD->fListScroll)+1);
    CalcFormatListScrollBar( theWindow, nowCD);
    SetControlValue(nowCD->fListScroll,ookl);
    EnableControl( SnatchCRef(theWindow,'FORM', 1001));
    EnableControl( SnatchCRef(theWindow,'FORM', 1002));
    
    // 
    nowCD->selected = ookl;
    
    {
        PeekitStructFormatterPtr startHere = gFormatters;
        UInt16 counter = nowCD->selected;
        while(counter){
            counter --;
            startHere = startHere->next;
        }
        nowCD->currentFormatter = startHere;
    }
    
    HIViewSetNeedsDisplay(
                          nowCD->FormatterListView,
                          true);
    if(nowCD->buildSelected >=0){
        long dummy;
        nowCD->buildSelected=-1;
        SetControlData(
                       nowCD->FormatterBuildView ,
                       0,
                       'FBCL',
                       sizeof(dummy),
                       &dummy);
        
    }
    HIViewSetNeedsDisplay( nowCD->FormatterBuildView, true );
    UpdateAllValDrawerPopups();
    
    return(myErr);
}
static  OSStatus FormatListMinusEventHandlerProc ( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData); 
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    PeekitStructFormatterPtr startHere =    gFormatters;
    UInt16 counter = nowCD->selected;
    while(counter){
        startHere = startHere->next;
        counter--;
    }
    // first, first, we see if this is being used by anyone else
    if(IsThisFormatterEmbedded(startHere->uniqueID)){
        // do something.  Actually, just tell 'em and go
        SInt16 outItemHit;
        StandardAlert(
                      kAlertStopAlert,
                      "\pThis formatter is embedded in another formatter.",
                      "\pPlease remove it from the other formatter before deleting.",
                      0,                          &outItemHit)   ;
        
        return(0);
        
        
    }
    // sanity check
    if(startHere){
        UInt16 numFormatters = CountAllStructureFormatters();
        PeekitStructFormatterPtr prev,next;
        prev=startHere->previous;
        next = startHere->next;
        if(	IsControlVisible(nowCD->floatingEdit)){
            DisableControl(nowCD->floatingEdit);
            HideControl(nowCD->floatingEdit);
        }
        if(gFormatters == startHere){
            gFormatters = next; // startHere->next;
        }
        if(prev)prev->next = next; // startHere->next;
        if(next)next->previous = prev;     // if(startHere->next)(startHere->next)->previous = prev;
        // 
        if(startHere->title)CFRelease(startHere->title);
        if(startHere->description)CFRelease(startHere->description);
        // and release the build elements
        {
            PIDataFormatterPtr nowFormatter = startHere->formatters;
            PIDataFormatterPtr temp;
            while(nowFormatter){
                if(nowFormatter->title)CFRelease(nowFormatter->title);
                if(nowFormatter->description)CFRelease(nowFormatter->description);
                temp=nowFormatter;
                nowFormatter = nowFormatter->next;
                free(temp);
            }
            
        }
        // mark this for deletion and move it, don't free it yet
        // free(startHere);

        {
            extern PeekitStructFormatterPtr     gFormattersMarkedForDeletion;
            startHere->flags |=kPIStructMarkForDeletion;
            // clear any lingering connections
            startHere->next = 0;
            startHere->previous = 0;
            PeekitStructFormatterPtr startHereDelete =    gFormattersMarkedForDeletion;
            if(startHereDelete){
                while(startHereDelete->next)startHereDelete = startHereDelete->next;
                startHereDelete->next = startHere;
            } else {
                gFormattersMarkedForDeletion = startHere;
            }
        }

        // now select something interesting
        counter = nowCD->selected;
        nowCD->selected = -1;
        DisableControl( SnatchCRef(theWindow,'FORM', 1001));
        DisableControl( SnatchCRef(theWindow,'FORM', 1002));
        DisableControl( SnatchCRef(theWindow,'FORM', 1003));
        
        nowCD->buildSelected = -1;
        long dummy;
        SetControlData(
                       nowCD->FormatterBuildView ,
                       0,
                       'FBCL',
                       sizeof(dummy),
                       &dummy);
        
        
        
        nowCD->currentFormatter =0;
        numFormatters = CountAllStructureFormatters();

        if(numFormatters){
            // select the previous or next one
            // previous first?
            if(prev){nowCD->selected= counter -1;
                nowCD->currentFormatter=prev;
            } else {
                if(next){
                    nowCD->selected= counter;
                    nowCD->currentFormatter=next;
                }
            }
        }

        if(nowCD->selected >=0){EnableControl( SnatchCRef(theWindow,'FORM', 1001));

        }
        
        // and turn stuff off if it's locked
        {
            if(    nowCD->currentFormatter == 0 || nowCD->currentFormatter->flags& kPIDataFormatterLocked){
                // and do this
                DisableControl( SnatchCRef(theWindow,'FORM', 1001));
                DisableControl( SnatchCRef(theWindow,'FORM', 1002));
                DisableControl( SnatchCRef(theWindow,'FORM', 1003));
            }
        }
        CalcFormatListScrollBar( theWindow, nowCD);
        HIViewSetNeedsDisplay(
                              nowCD->FormatterListView,
                              true);
        HIViewSetNeedsDisplay(
                              nowCD->FormatterBuildView,
                              true);
        
        
    }
    UpdateAllValDrawerPopups();
    
    return(myErr);
}
static  OSStatus FormatBuildPlusEventHandlerProc ( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData); 
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    // add a new formatter to the currentFormater
    PeekitStructFormatterPtr nowFormatter=nowCD->currentFormatter;
    if(nowCD->currentFormatter)nowCD->currentFormatter->flags |=            kPIStructChanged;
    
    if(nowFormatter){
        PIDataFormatterPtr newFormatter = calloc(1,sizeof(PeekitDataFormatter));
        PIDataFormatterPtr startHere = nowFormatter->formatters;
        newFormatter->title =  CFStringCreateWithPascalString(0,"\pData element",0);
        newFormatter->description=CFStringCreateWithPascalString(0,"\pempty",0);
        
        // since they defualt to byte
        newFormatter->length = 1;
        AddUniqueIDToThisDataFormatter(newFormatter);
        
        // create a unique ID
        
        if(startHere){
            while(startHere->next)startHere=startHere->next;
            startHere->next= newFormatter;
            newFormatter->previous = startHere;
            
        } else{
            nowFormatter->formatters=newFormatter;
        }
        CalcFormatBuildScrollBar( theWindow, nowCD);
        HIViewSetNeedsDisplay(
                              nowCD->FormatterBuildView,
                              true);
        
    }
    return(myErr);
}


static  OSStatus FormatExportOneEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData); 
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    PeekitStructFormatterPtr theStruct = nowCD->currentFormatter;
    PIDataFormatterPtr nowFormatter =theStruct->formatters;

    return(myErr);  
}

static  OSStatus FormatExportAllEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData); 
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    PeekitStructFormatterPtr theStruct = nowCD->currentFormatter;
    PIDataFormatterPtr nowFormatter =theStruct->formatters;
    

    return(myErr);
}
static  OSStatus FormatBuildMinusEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData); 
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    PeekitStructFormatterPtr theStruct = nowCD->currentFormatter;
    PIDataFormatterPtr nowFormatter =theStruct->formatters;
   if(nowCD->currentFormatter) nowCD->currentFormatter->flags |=            kPIStructChanged;
    
    UInt16 counter = nowCD->buildSelected;
    while(counter){
        nowFormatter = nowFormatter->next;
        counter--;
    }
    if(nowFormatter){
        PIDataFormatterPtr prev,next;
        // disable the controls if they're showing
        prev=nowFormatter->previous;
        next = nowFormatter->next;
        if(prev){
            prev->next = next;
        } else {
            theStruct->formatters=next;
        }
        if(next)next->previous = prev;
        
        if(nowFormatter->title)CFRelease(nowFormatter->title);
        if(nowFormatter->description)CFRelease(nowFormatter->description);
        free(nowFormatter);
        // controls and selection, I'm just killing it at this point.
        nowCD->buildSelected = -1;
        DisableControl( SnatchCRef(theWindow,'FORM', 1003));
        long dummy;
        SetControlData(
                       nowCD->FormatterBuildView ,
                       0,
                       'FBCL',
                       sizeof(dummy),
                       &dummy);
        
        CalcFormatBuildScrollBar( theWindow, nowCD);
        HIViewSetNeedsDisplay(
                              nowCD->FormatterBuildView,
                              true);
        
        
    }
    
    return(myErr);
}

static  OSStatus FormatTypePUHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData); 
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    PeekitStructFormatterPtr currentFormatter =nowCD->currentFormatter;
    UInt16             tempCounter = nowCD->buildSelected;
    PIDataFormatterPtr  startHere=0;
    
    startHere=nowCD->currentFormatter->formatters;
    while(tempCounter){
        startHere = startHere->next;
        tempCounter--;
    }
    if(startHere){
        UInt16 type = GetControlValue(nowCD-> typePU);
        if(type <= sizeof(FormatterDataStandardLengths)/sizeof(SInt32))
            startHere->length = FormatterDataStandardLengths[type-1];
        else
            startHere->length = -2;  // -2 means derived from the formatter
        
        HIViewSetNeedsDisplay(  nowCD->FormatterBuildView, true );
        SetControlValue(nowCD-> typePU,type);
        
    }
    return(myErr);
}
static  OSStatus FormatScrollBarListEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{
    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    UInt32 theVal;
    UInt32 newVal;
    ControlRef theCont;
    ControlPartCode thePart;
    
    GetEventParameter (inEvent, kEventParamDirectObject, typeControlRef,
                       NULL, sizeof(ControlRef), NULL, &theCont);
    GetEventParameter (inEvent, kEventParamControlPart, typeControlPartCode,
                       NULL, sizeof(ControlPartCode), NULL, &thePart);
    
    theVal=GetControl32BitValue(theCont);
    
    // get the value and move to it
    switch(thePart){
        case  kControlUpButtonPart :
            //            newVal = theVal-1;
            //            if(newVal <0)newVal = 0;
            break;
            
        case  kControlDownButtonPart:
            //            SetControl32BitValue(theCont,theVal+1);
            //           newVal = theVal+1;
            
            break;
            
        case kControlPageUpPart:
            //        newVal = theVal-10;
            //          if(newVal <0)newVal = 0;
            
            break;
            
        case kControlPageDownPart:
            //        newVal = theVal+10;
            //            if(newVal <0)newVal = 0;
            
            break;
        default:
            // should be the Tumb
            newVal = theVal;
            SetControl32BitValue(nowCD->fListScroll,newVal);
            
            break;
    }
    
    
    // and of course set the value of the other control to this one
    // and tell the views to redraw
    HIViewSetNeedsDisplay(
                          nowCD->FormatterListView,
                          true);
    return(myErr);
    
}
static  OSStatus FormatScrollBarBuildEventHandlerProc( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
{
    OSStatus myErr = noErr;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    UInt32 theVal;
    UInt32 newVal;
    ControlRef theCont;
    ControlPartCode thePart;
    
    GetEventParameter (inEvent, kEventParamDirectObject, typeControlRef,
                       NULL, sizeof(ControlRef), NULL, &theCont);
    GetEventParameter (inEvent, kEventParamControlPart, typeControlPartCode,
                       NULL, sizeof(ControlPartCode), NULL, &thePart);
    
    theVal=GetControl32BitValue(theCont);
    
    // get the value and move to it
    switch(thePart){
        case  kControlUpButtonPart :
            //            newVal = theVal-1;
            //            if(newVal <0)newVal = 0;
            break;
            
        case  kControlDownButtonPart:
            //            SetControl32BitValue(theCont,theVal+1);
            //           newVal = theVal+1;
            
            break;
            
        case kControlPageUpPart:
            //        newVal = theVal-10;
            //          if(newVal <0)newVal = 0;
            
            break;
            
        case kControlPageDownPart:
            //        newVal = theVal+10;
            //            if(newVal <0)newVal = 0;
            
            break;
        default:
            // should be the Tumb
            newVal = theVal;
            SetControl32BitValue(nowCD->fBuildScroll,newVal);
            
            break;
    }
    
    
    // and of course set the value of the other control to this one
    // and tell the views to redraw
    HIViewSetNeedsDisplay(
                          nowCD->FormatterBuildView,
                          true);
    return(myErr);
    
}


static void liveListScroller(ControlRef theCont, ControlPartCode thePart)
{
    
    if(thePart >0){
        WindowRef theWindow = GetControlOwner(theCont);
        if(theWindow){
            WCH tempWC = (WCH)GetWRefCon(theWindow);
            FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
            UInt32 newVal;
            UInt32 theVal=GetControl32BitValue(theCont);
            
            // get the value and move to it
            switch(thePart){
                case  kControlUpButtonPart :
                    newVal = theVal-1;
                    if(newVal <0)newVal = 0;
                        break;
                    
                case  kControlDownButtonPart:
                    //            SetControl32BitValue(theCont,theVal+1);
                    newVal = theVal+1;
                    
                    break;
                    
                case kControlPageUpPart:
                    newVal = theVal-10;
                    if(newVal <0)newVal = 0;
                        
                        break;
                    
                case kControlPageDownPart:
                    newVal = theVal+10;
                    if(newVal <0)newVal = 0;
                        
                        break;
                default:
                    // should be the Tumb
                    newVal = theVal;
                    break;
            }
            SetControl32BitValue(nowCD->fListScroll,newVal);
            
            HIViewSetNeedsDisplay(
                                  nowCD->FormatterListView,
                                  true);
            
            
        }
    }
    
}
static void liveBuildScroller(ControlRef theCont, ControlPartCode thePart)
{
    
    if(thePart >0){
        WindowRef theWindow = GetControlOwner(theCont);
        if(theWindow){
            WCH tempWC = (WCH)GetWRefCon(theWindow);
            FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
            UInt32 newVal;
            UInt32 theVal=GetControl32BitValue(theCont);
            
            // get the value and move to it
            switch(thePart){
                case  kControlUpButtonPart :
                    newVal = theVal-1;
                    if(newVal <0)newVal = 0;
                        break;
                    
                case  kControlDownButtonPart:
                    //            SetControl32BitValue(theCont,theVal+1);
                    newVal = theVal+1;
                    
                    break;
                    
                case kControlPageUpPart:
                    newVal = theVal-10;
                    if(newVal <0)newVal = 0;
                        
                        break;
                    
                case kControlPageDownPart:
                    newVal = theVal+10;
                    if(newVal <0)newVal = 0;
                        
                        break;
                default:
                    // should be the Tumb
                    newVal = theVal;
                    break;
            }
            SetControl32BitValue(nowCD->fBuildScroll,newVal);
            
            HIViewSetNeedsDisplay(
                                  nowCD->FormatterBuildView,
                                  true);
            
            
        }
    }
}




#pragma mark creation
WindowRef CreateOrShowFormatWWIND(FSSpecPtr theFile, Boolean visi)
{
#pragma unused (theFile )
    LoopVar qq;
    WindowPrefStructHdl thePrefs=nil;
    EventTypeSpec	FormatlControlEvents[] =
    {
    {kEventClassControl,    kEventControlHit}
    };
    EventTypeSpec	fwControlEvents[] =
    {
    {kEventClassControl,    kEventControlHit},
    {kEventClassControl,    kEventControlDraw},
    {kEventClassControl,    kEventControlClick}   
        
        
    };
    
    WCH tempWC;
    FormatWWDataP nowCD;
    Ptr colRightPtr = 0;

    OSErr myErr = 0;
    AliasHandle theA;
    WindowRef FormatWWINDWindow = nil;
    
    // see if it exists yet
    FormatWWINDWindow= FindWindowByKind(kFormatWWINDWindow);
    if(FormatWWINDWindow){ShowWindow(FormatWWINDWindow);SelectWindow(FormatWWINDWindow);return(FormatWWINDWindow);}
    
    
    myErr = CreateWindowFromNib(gNibRef, CFSTR("FormatterWindow"), &FormatWWINDWindow);
    
    // NEW
    InstallFormatWWindowHandlers(
                                 FormatWWINDWindow,
                                 0,
                                 0);
    
    tempWC = (WCH)NewHandleClear(sizeof(windowControl));
    
    SetWindowKind(FormatWWINDWindow, kFormatWWINDWindow);
    //    nowCD = (FormatWWDataH)NewHandleClear(sizeof(FormatWWindData));
    nowCD=(FormatWWDataP) malloc(sizeof(FormatWWindData));
    ZeroPtr((Ptr)nowCD,sizeof(FormatWWindData));
    
    mPushPort(FormatWWINDWindow)
        TextSize(9);
    
    mPullPort
        (*tempWC)->undoAction = (UndoHand)NewHandleClear(sizeof(UndoControl));
    (*tempWC)->dataStore = (Handle)nowCD;
    SetWRefCon(FormatWWINDWindow, (long)tempWC);
    AddWindowID(FormatWWINDWindow);
    (*tempWC)->closeMe = CloseFormatWWIND;
    
#if 0
    /* set these goddam things */
    (*tempWC)->drawMe = DrawFormatWWIND;
    (*tempWC)->clickMe = HitFormatWWIND;
    (*tempWC)->saveMe = SaveFormatWWIND;
    (*tempWC)->closeMe = CloseFormatWWIND;
    (*tempWC)->keyMe = KeyFormatWWIND;
    //    (*tempWC)->prepEdit = PrepEditFormatWWIND;
    (*tempWC)->editMe = EditFormatWWINDWindow;
    //    (*tempWC)->activateMe = ActivateFormatWWIND;
    //    (*tempWC)->deactMe = DeActivateFormatWWIND;
    (*tempWC)->sizeMe = SizeFormatWWIND;
#endif    
    (*tempWC)->idleMe = IdleFormatWWIND;
#if 0
    (*tempWC)->appleEventMe = AEFormatWWIND;
#endif    
    (*tempWC)->generalMe = GenFormatWWIND;
    (*tempWC)->commandMe = CommandFormatWWIND;
    
    
    
    // set up the initial rects, either defaulted or saved
    //    SizeFormatWWINDControls(FormatWWINDWindow);
    
    InstallControlEventHandler(          SnatchCRef(FormatWWINDWindow,'FORM', kFormatListScroll), FormatScrollBarListEventHandlerProc  , GetEventTypeCount(FormatlControlEvents), FormatlControlEvents, FormatWWINDWindow, NULL );
    InstallControlEventHandler(          SnatchCRef(FormatWWINDWindow,'FORM', kFormatBuildScroll), FormatScrollBarBuildEventHandlerProc  , GetEventTypeCount(FormatlControlEvents), FormatlControlEvents, FormatWWINDWindow, NULL );
    InstallControlEventHandler(          SnatchCRef(FormatWWINDWindow,'FORM', kFormatBuildTypePU), FormatTypePUHandlerProc  , GetEventTypeCount(FormatlControlEvents), FormatlControlEvents, FormatWWINDWindow, NULL );
    
    InstallControlEventHandler(          SnatchCRef(FormatWWINDWindow,'FORM', 1000), FormatListPlusEventHandlerProc  , GetEventTypeCount(FormatlControlEvents), FormatlControlEvents, FormatWWINDWindow, NULL );
    InstallControlEventHandler(          SnatchCRef(FormatWWINDWindow,'FORM', 1001), FormatListMinusEventHandlerProc  , GetEventTypeCount(FormatlControlEvents), FormatlControlEvents, FormatWWINDWindow, NULL );
    InstallControlEventHandler(          SnatchCRef(FormatWWINDWindow,'FORM', 1002), FormatBuildPlusEventHandlerProc  , GetEventTypeCount(FormatlControlEvents), FormatlControlEvents, FormatWWINDWindow, NULL );
    InstallControlEventHandler(          SnatchCRef(FormatWWINDWindow,'FORM', 1003), FormatBuildMinusEventHandlerProc  , GetEventTypeCount(FormatlControlEvents), FormatlControlEvents, FormatWWINDWindow, NULL );

    // exporters

    
    
    nowCD-> typePU=  SnatchCRef(FormatWWINDWindow,'FORM', kFormatBuildTypePU);
    nowCD->  fListScroll=  SnatchCRef(FormatWWINDWindow,'FORM', kFormatListScroll);
    nowCD->  fBuildScroll=  SnatchCRef(FormatWWINDWindow,'FORM', kFormatBuildScroll);
    // two live scrollers
    
    SetControlAction ( nowCD->fListScroll,
                       NewControlActionUPP(liveListScroller));
    SetControlAction ( nowCD->fBuildScroll,
                       NewControlActionUPP(liveBuildScroller));
    // create the views
    nowCD-> FormatterListViewRect.origin.x=20;
    nowCD-> FormatterListViewRect.origin.y=20;
    nowCD-> FormatterListViewRect.size.height=220;
    nowCD-> FormatterListViewRect.size.width=220;
    
    FormatterListViewCreate(FormatWWINDWindow);    
    // get saved columnrights
    {
        CFStringRef colsrKey = CFSTR("BuildColRights");
        CFDataRef   colDataRs  = CFPreferencesCopyAppValue(colsrKey,
                                             kCFPreferencesCurrentApplication);
        if(colDataRs){
        UInt8 * dataIn;
        dataIn = CFDataGetBytePtr (
                                   colDataRs
                                   );
        colRightPtr = malloc(sizeof(UInt16)*6);
        BlockMoveData(dataIn,colRightPtr,(sizeof(UInt16)*6));
        CFRelease(colDataRs);
        }
        
    
        
        
        
    }
    
    
    FormatterBuildViewCreate(FormatWWINDWindow,colRightPtr);    
    if(colRightPtr)free(colRightPtr);
    ShowControl(nowCD->FormatterListView);
    ShowControl(nowCD->FormatterBuildView);
    // embed and hide our freinds
    nowCD->selected = -1;
    nowCD->buildSelected=-1;
    
    
    DisableControl( SnatchCRef(FormatWWINDWindow,'FORM', 1001));
    DisableControl( SnatchCRef(FormatWWINDWindow,'FORM', 1002));
    DisableControl( SnatchCRef(FormatWWINDWindow,'FORM', 1003));

    
    
    
    RestoreWindowVitalStats(FormatWWINDWindow,CFSTR("FMSTANDARDSTATE"));
    
    if (visi) {
        if(        gAddPrefs.windowFlags&  kWindowMetalFlag)
            MakeWindowMetal(FormatWWINDWindow,true);
        
        // ‚Ä¢‚Ä¢‚Ä¢ FIX   AddToWindowMenu(FormatWWINDWindow, nil, kWindowMenu);
        Rect eee={0,0,30,30};
        CreateEditUnicodeTextControl (
                                      FormatWWINDWindow,
                                      &eee,
                                      0,
                                      false,
                                      0,
                                      &nowCD->floatingEdit
                                      );   
        CreateEditUnicodeTextControl (
                                      FormatWWINDWindow,
                                      &eee,
                                      0,
                                      false,
                                      0,
                                      &nowCD->buildFloatingEdit
                                      );   
        
        
        EmbedControl(nowCD->floatingEdit,nowCD->FormatterListView);
        EmbedControl(nowCD->buildFloatingEdit,nowCD->FormatterBuildView);
        
        EmbedControl(nowCD->typePU,nowCD->FormatterBuildView);
        EmbedControl( SnatchCRef(FormatWWINDWindow,'FORM',kFormatSignedCB),nowCD->FormatterBuildView);
        EmbedControl( SnatchCRef(FormatWWINDWindow,'FORM',kFormatLilEndianCB),nowCD->FormatterBuildView);
        HideControl(nowCD->floatingEdit);
        HideControl(nowCD->buildFloatingEdit);
        
        HideControl(nowCD->typePU);
        HideControl( SnatchCRef(FormatWWINDWindow,'FORM',kFormatSignedCB));
        HideControl( SnatchCRef(FormatWWINDWindow,'FORM',kFormatLilEndianCB));
        SizeFormatWWINDControls(FormatWWINDWindow);
        
        InstallFormatterWindKeyHandlers(FormatWWINDWindow);
        
        ShowWindow(FormatWWINDWindow);
        
        
    }
    
    
    return(FormatWWINDWindow);
}



// size scroll bar and text area
#pragma mark  sizing
static void SizeFormatWWINDControls(WindowRef theWindow)
{
#pragma unused (theWindow )
    // see if we can change the menu position by mussing with the rect
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    Rect    wRect,otherRect,spareRect;
    CGRect makeup;
    UInt16 topOfButtons;
    UInt16 wide,hi;
    UInt16 flistWide,fconstWide;
    UInt16 hPos;
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    GetControlBounds(SnatchCRef(theWindow,'FORM',1000),&spareRect);
    // 1/3 minus 20 - 16 -16 - 12 - 12
    GetWindowPortBounds(theWindow,&wRect );
    topOfButtons = wRect.bottom - (spareRect.bottom - spareRect.top +4);
    
    wide = wRect.right-wRect.left - (20 + 16 + 16 + 12 + 12);
    flistWide = wide/4;  // make it a quarter, not a third
    fconstWide = wide - flistWide;
    hPos = 12;
    makeup.origin.y = 30;
    makeup.origin.x = hPos;
    
    makeup.size.width = makeup.origin.x+flistWide;
    // make tis an actual multiple of the height
    makeup.size.height =((topOfButtons) -( makeup.origin.y+4));
    hi =makeup.size.height/( gDefaultFontSize+4);
    makeup.size.height = hi * ( gDefaultFontSize+4);
    HIViewSetFrame(
                   nowCD->FormatterListView,
                   &makeup);
    nowCD-> FormatterListViewRect= makeup;
    // title
    GetControlBounds(SnatchCRef(theWindow,'FORM',kFormViewTitleText),&otherRect);
    wide = otherRect.right - otherRect.left;
    mCGRectToRect(makeup,otherRect);         
    otherRect.bottom = otherRect.top;
    otherRect.top-=14;
    otherRect.right = otherRect.left+wide;
    SetControlBounds(SnatchCRef(theWindow,'FORM',kFormViewTitleText),&otherRect);
    // bottom controls
    
    GetControlBounds(SnatchCRef(theWindow,'FORM',1000),&otherRect);
    wide = otherRect.right - otherRect.left;
    hi= otherRect.bottom - otherRect.top;
    mCGRectToRect(makeup,otherRect);         
    otherRect.top = otherRect.bottom;
    otherRect.bottom = otherRect.top+hi;
    otherRect.right = otherRect.left+wide;
    SetControlBounds(SnatchCRef(theWindow,'FORM',1000),&otherRect);
    otherRect.left=otherRect.right ;
    otherRect.right =otherRect.left+wide;
    hi= otherRect.bottom - otherRect.top;
    SetControlBounds(SnatchCRef(theWindow,'FORM',1001),&otherRect);
    
    
    // matching scroll bar
    
    GetControlBounds(nowCD->fListScroll,&spareRect);
    mCGRectToRect(makeup,otherRect);         
    otherRect.left = otherRect.right;
    otherRect.right = otherRect.left+mRectWide(spareRect);
    SetControlBounds(nowCD->fListScroll,&otherRect);
    mRectToCGRect(otherRect,makeup);
    makeup.origin.x+=30;
    makeup.size.width=flistWide*3;
    HIViewSetFrame(
                   nowCD->FormatterBuildView,
                   &makeup);
    nowCD-> FormatterBuildViewRect= makeup;
    
    // title
    GetControlBounds(SnatchCRef(theWindow,'FORM',kFormViewTitleText+1),&otherRect);
    wide = otherRect.right - otherRect.left;
    
    mCGRectToRect(makeup,otherRect);         
    otherRect.bottom = otherRect.top;
    otherRect.top-=14;
    otherRect.right = otherRect.left+wide;
    SetControlBounds(SnatchCRef(theWindow,'FORM',kFormViewTitleText+1),&otherRect);
    
    mCGRectToRect(makeup,otherRect);         
    otherRect.left = otherRect.right+1;
    otherRect.right = otherRect.left+mRectWide(spareRect);
    SetControlBounds(nowCD->fBuildScroll,&otherRect);
    // bottom
    GetControlBounds(SnatchCRef(theWindow,'FORM',1002),&otherRect);
    wide = otherRect.right - otherRect.left;
    hi= otherRect.bottom - otherRect.top;
    mCGRectToRect(makeup,otherRect);         
    otherRect.top = otherRect.bottom;
    otherRect.bottom = otherRect.top+hi;
    otherRect.right = otherRect.left+wide;
    SetControlBounds(SnatchCRef(theWindow,'FORM',1002),&otherRect);
    otherRect.left=otherRect.right ;
    otherRect.right =otherRect.left+wide;
    hi= otherRect.bottom - otherRect.top;
    SetControlBounds(SnatchCRef(theWindow,'FORM',1003),&otherRect);
    
    
    CalcFormatScrollBars(theWindow,nowCD);
    
}












static void SetUpFormatterWindowMenus(FormatWWDataP nowCD,UInt32 theID)
{
    static MenuCommand fileenablers[]={  kHICommandQuit ,
        
        kHICommandPreferences,  kHICommandAbout,
        kHICommandOpen ,  kHICommandClose ,kExportCommand,
        kHICommandSaveAs,
        kHICommandPrint ,
        kHICommandPageSetup,
        kHICommandAppHelp
        
    };
    static MenuCommand editenablers[]={
        kHICommandCopy
    };
    
    LoopVar qq;
    switch(theID){
        case kFileMenu:
            for(qq=0;qq<sizeof(fileenablers)/sizeof(MenuCommand);qq++){
                EnableMenuCommand(0,fileenablers[qq]);
            }
            break;
        case kEditMenu:
            // enable editors
            for(qq=0;qq<sizeof(editenablers)/sizeof(MenuCommand);qq++){
                EnableMenuCommand(0,editenablers[qq]);
                
                
            }
            //
            
            break;
        case kToolsMenu:
            if(nowCD->selected>=0){
            EnableMenuCommand(0,'EFOR');
            }
            if(gFormatters)
                EnableMenuCommand(0,'EAFR');
            EnableMenuCommand(0,'OFFR');
            break;
            
#if 0
            others
                kHICommandUndo ,kHICommandRedo,kHICommandCut ,kHICommandCopy , kHICommandPaste ,kHICommandClear, kHICommandSelectAll           = 'sall',
                
                kHICommandRevert              = 'rvrt',
                kHICommandSave                = 'save',
                kHICommandNew                 = 'new ',
                
#endif
    }
}











void ReArrangeFormatWWControls(WindowRef theWindow, FormatWWDataP nowCD)
{
#if 0
    // make sure they're drawn
    Point thePoint;
    LoopVar qq;
    mPushPort(theWindow)
        PenPat(&gGrayPat);
    PenSize(2, 2);
    
    for (qq = 0; qq < kNumCWPicts; qq++) {
        
        
        FrameRect(&(nowCD)->compRects[qq]);
        
        
    }
    QDFlushPortBuffer(
                      GetWindowPort((WindowRef)theWindow),
                      0);
    
    PenSize(1, 1);
    PenPat(&gBlackPat);
    
    GetMouse(&thePoint);
    // see if we're in any. FIFo
    for (qq = 0; qq < kNumCWPicts; qq++) {
        if (PtInRect(thePoint, &(nowCD)->compRects[qq])) {
            
            // drag this one
            Rect tempRect = (nowCD)->compRects[qq];
            Rect old = tempRect;
            DragABM(theWindow, &tempRect);
            
            // ask 'em Format it
            (nowCD)->compRects[qq] = tempRect;
            // save this to the prefs
            gPrefs.userCompRects[qq] = (nowCD)->compRects[qq];
            // resize here
            ZapRect(theWindow, &old);
            ZapRect(theWindow, &(nowCD)->compRects[qq]);
            // make sure the border gets redrawn
            (nowCD)->drewOutline=false;
        }
    }
    mPullPort
        
        ResetCWRectOffsets(theWindow, nowCD);
#endif
}





Ptr FlattenFormatter(PeekitStructFormatterPtr theFM)
{Ptr theResult,inUsePtr;
    // first firgure out the total size of the flattened formatter
    UInt32 formLen = sizeof(FlatFormatterHeader);
    UInt16 numFormatters=0;
    PIDataFormatterPtr startHere;
    FlatFormatter *temp = calloc(1,sizeof(FlatFormatter));
    FlatFormatterHeader * theX = calloc(1,sizeof(FlatFormatterHeader));
    // count the formatters
    startHere = theFM->formatters;
    while(startHere){
        numFormatters++;
        startHere=startHere->next;
    }
    formLen += numFormatters * sizeof(FlatFormatter /* PeekitDataFormatter*/ );
    theResult = calloc(formLen,1);
    inUsePtr=theResult;
    
    // move header
    theX->version = theFM->version;
    theX->uniqueID = theFM->uniqueID;
    theX->flags = theFM->flags;
    theX->lenFlattened = formLen;  // total size of this formatter
                                   // title
    CFStringGetPascalString(theFM->title, &theX->title, 255,0);
    CFStringGetPascalString(theFM->description, &theX->description, 255,0);
    
    theX->numberOfFormatters = numFormatters;
    BlockMoveData(theX,inUsePtr,sizeof(FlatFormatterHeader));
    free(theX);
    inUsePtr = inUsePtr + sizeof(FlatFormatterHeader);
    // now all the formatters
    startHere = theFM->formatters;
    while(numFormatters){
        temp->version = startHere->version;
        temp->uniqueID = startHere->uniqueID;
        
        CFStringGetPascalString(startHere->title, &temp->title, 255,0);
        // added a description field
        CFStringGetPascalString(startHere->description, &temp->description, 255,0);
        
        temp->flags = startHere->flags;
        temp->dataType = startHere->dataType;
        temp->embeddedFormatterUniqueID = startHere->embeddedFormatterUniqueID;
        
        temp->length = startHere->length;
        temp->flags = startHere->flags;        
        BlockMoveData(temp,inUsePtr,sizeof(FlatFormatter));
        startHere=startHere->next;
        inUsePtr = inUsePtr + sizeof(FlatFormatter);        
        numFormatters--;
    }
    free(temp);
    
    return(theResult);
}

PeekitStructFormatterPtr  ExpandFlatFormatter(Ptr theFFM)
{
    PeekitStructFormatterPtr theFormatter = calloc(1,sizeof(PeekitStructFormatter));
    FlatFormatterHeader theHeader;
    PIDataFormatterPtr oldFormatter=0;
    UInt16 numFormatters=0;
    Ptr inUse = theFFM;
    BlockMoveData(inUse,&theHeader,sizeof(FlatFormatterHeader));
    theFormatter->version = theHeader.version;
    theFormatter->uniqueID = theHeader.uniqueID;
    theFormatter->flags = theHeader.flags;
    theFormatter->title= CFStringCreateWithPascalString(0, theHeader.title, kCFStringEncodingASCII);
    theFormatter->description= CFStringCreateWithPascalString(0, theHeader.description, kCFStringEncodingASCII);
    
    numFormatters = theHeader.numberOfFormatters;
    // walk through the formatters
    inUse= inUse + sizeof(FlatFormatterHeader);
    while(numFormatters){
        PIDataFormatterPtr newFormatter = calloc(1,sizeof(PeekitDataFormatter));
        FlatFormatter *holder = (FlatFormatter *)inUse;
        newFormatter->version = holder->version;
        newFormatter->uniqueID = holder->uniqueID;
        newFormatter->dataType =holder-> dataType;
        newFormatter->embeddedFormatterUniqueID = holder->embeddedFormatterUniqueID;
        newFormatter->length=        holder->length;
        newFormatter->flags=        holder->flags;
        newFormatter->title= CFStringCreateWithPascalString(0, holder->title, kCFStringEncodingASCII);
        newFormatter->description= CFStringCreateWithPascalString(0, holder->description, kCFStringEncodingASCII);
        
        if(oldFormatter){
            oldFormatter->next = newFormatter;
            newFormatter->previous = oldFormatter;
            oldFormatter=newFormatter;
        } else {
            oldFormatter = newFormatter;
            theFormatter->formatters = newFormatter; // set up the master
        }
        
        numFormatters --;
        inUse = inUse + sizeof(FlatFormatter);
    }
    return(theFormatter);
}

void BuildFormatterMenu(MenuRef thisMenu)
{UInt32 formCount = CountAllStructureFormatters();
    UInt32 indexer = 0;
    PeekitStructFormatterPtr startHere = gFormatters;
    
    while(formCount){
        AppendMenuItemTextWithCFString(
                                       thisMenu,
                                       startHere->title,
                                       0,
                                       0,
                                       0) ;
        formCount--;
        startHere        = startHere->next;
    }
}


OSStatus FormatWindKeyHandler(EventHandlerCallRef inHandlerCallRef, EventRef inEvent, void *inUserData)
{OSErr myErr=noErr;
    Boolean tellEm = true;
    WindowRef theWindow=(WindowRef)inUserData;
    WCH tempWC = (WCH)GetWRefCon((WindowRef)inUserData);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    ControlRef focusedControl=0;
    
    UInt32 modKeys;
    ControlRef theControl;
    UInt32     ookies;
    Boolean holid ;
    UInt32	eventKind = GetEventKind( inEvent );
    char theChar = 0;
    // get the key
    // kEventParamKeyCode
    
    
    myErr = GetEventParameter( inEvent, kEventParamKeyMacCharCodes, typeChar,
                               NULL, sizeof( typeChar ), NULL,&theChar );
    
    myErr = GetEventParameter( inEvent, kEventParamKeyModifiers, typeUInt32,
                               NULL, sizeof( UInt32 ), NULL,&modKeys );
    
    
    GetKeyboardFocus(
                     theWindow,
                     &focusedControl)    ;
    
    
    /**********/
    tellEm = true;
    // don't do this if there is no focus
    if(focusedControl){
        switch(eventKind){
            FormatterBuildViewData* theNum = 0;
            case kEventRawKeyDown:
            case kEventRawKeyRepeat:
                
                if(theChar == 0xd || theChar == kEnterKey){
                    // close the thingme if the dingus is verplunkt
                    if(IsControlVisible(nowCD->floatingEdit) && focusedControl ==nowCD->floatingEdit ){
                        slibTextBlockPtr theText = slibGetTextFromEditControl(nowCD->floatingEdit);
                        // and replace the name of the current formatter with this name.
                        CFRelease(nowCD->currentFormatter->title);
                        nowCD->currentFormatter->title = theText->theString;
                        CFRetain(nowCD->currentFormatter->title);
                        slibDisposeTextBlock(theText);
                        SetKeyboardFocus(
                                         theWindow,
                                         nowCD->floatingEdit,
                                         kControlFocusNoPart);
                        DisableControl(nowCD->floatingEdit);
                        HideControl(nowCD->floatingEdit);
                        // if the other one is visible, move focus toit
                        if                    (IsControlVisible(nowCD->buildFloatingEdit)){
                            SetKeyboardFocus(
                                             theWindow,
                                             nowCD->buildFloatingEdit,
                                             kControlFocusNoPart);
                            SetKeyboardFocus(
                                             theWindow,
                                             nowCD->buildFloatingEdit,
                                             kControlFocusNextPart);}
                        
                        /*
                         GetControlData(
                                        nowCD->floatingEdit,
                                        88,
                                        kslibReturnViewRefCon,
                                        sizeof(theNum),
                                        &theNum,
                                        0);
                         if(theNum){
                             
                         }
                         */
                        tellEm = false;
                    } 
                    if(IsControlVisible(nowCD->buildFloatingEdit) && focusedControl ==nowCD->buildFloatingEdit){
                        tellEm = false;
                        {  FormatterBuildViewData* theNum;          
                            PIDataFormatterPtr theFormatter=0;
                            slibTextBlockPtr theText = slibGetTextFromEditControl(nowCD->buildFloatingEdit);
                            
                            GetControlData(
                                           nowCD->FormatterBuildView,
                                           88,
                                           kslibReturnViewRefCon,
                                           sizeof(theNum),
                                           &theNum,
                                           0);
                            
                            theFormatter=theNum->activeFormatter;
                            theFormatter-> title = theText->theString;
                            CFRetain(     theFormatter-> title);
                            slibDisposeTextBlock(theText);
                            SetKeyboardFocus(
                                             theWindow,
                                             nowCD->buildFloatingEdit,
                                             kControlFocusNoPart);
                            
                            SetControlVisibility(nowCD->buildFloatingEdit,false,true);
                            
                            // if the other one is visible, move focus toit
                            if                    (IsControlVisible(nowCD->floatingEdit)){
                                SetKeyboardFocus(
                                                 theWindow,
                                                 nowCD->floatingEdit,
                                                 kControlFocusNoPart);
                                SetKeyboardFocus(
                                                 theWindow,
                                                 nowCD->floatingEdit,
                                                 kControlFocusNextPart);}
                            
                            
                            if(theNum){
                                theNum->  editColumnActive=-1;
                                
                            }
                            
                            
                        }
                        
                    }
                }
                break;
        }}
    /***********/
    
    
    if(tellEm){
        CallNextEventHandler(
                             inHandlerCallRef,
                             inEvent);
    }
    
    
    return(myErr);
    
}
// stupid edit text.  Well, I'll try and fix it this way
// raw keyboard messing about
void InstallFormatterWindKeyHandlers(WindowRef theWindow)

{OSErr myErr = 0;
    EventTypeSpec keyEventList[3]={
    {kEventClassKeyboard,kEventRawKeyDown},
    {kEventClassKeyboard,kEventRawKeyRepeat},
    {kEventClassKeyboard,kEventRawKeyUp}};
    myErr = InstallEventHandler (GetWindowEventTarget (theWindow), NewEventHandlerUPP(FormatWindKeyHandler),     sizeof(keyEventList)/sizeof(EventTypeSpec),    &keyEventList,     (void *)theWindow,   nil);
    
}





#undef __FormatPeekWINDOW__


/*
 *  formatterlistview.pi.c
 *  PeekIt
 *
 *  Created by C.K. Haun on 11/26/05.
 *  Copyright 2005 Ravenware Software. All rights reserved.
 *
 */
// -----------------------------------------------------------------------------
// FormatterListView API
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewCreate(                            WindowRef				inWindow);
extern CGRGBColor  gCGSelectionRangeColor;




// -----------------------------------------------------------------------------
//	constants
// -----------------------------------------------------------------------------
//

#define kFormatterListViewClassID	CFSTR( "com.Ravenware.FormatterListView" )


// -----------------------------------------------------------------------------
//	types
// -----------------------------------------------------------------------------
//
typedef struct
{
	HIViewRef			view;
	// Geometry
    Rect ourSize;
    UInt16 listViewCellHi;
        WindowRef theWindow;        
        UInt32 clickCount;
        Boolean editVisible;
        UInt32 countInView;   // added up during drawing
} FormatterListViewData;

// -----------------------------------------------------------------------------
//	prototypes
// -----------------------------------------------------------------------------
//

OSStatus FormatterListViewRegister(void);
OSStatus FormatterListViewHandler(
	EventHandlerCallRef		inCallRef,
	EventRef				inEvent,
	void*					inUserData );
OSStatus FormatterListViewConstruct(
	EventRef				inEvent );
OSStatus FormatterListViewInitialize(
	EventHandlerCallRef		inCallRef,
	EventRef				inEvent,
	FormatterListViewData*		inData );
OSStatus FormatterListViewDestruct(
	EventRef				inEvent,
	FormatterListViewData*		inData );
OSStatus FormatterListViewDraw(
	EventRef				inEvent,
	FormatterListViewData*		inData );
OSStatus FormatterListViewHitTest(
	EventRef				inEvent,
	FormatterListViewData*		inData );
OSStatus FormatterListViewTrack(
	EventRef				inEvent,
	FormatterListViewData*		inData );
OSStatus FormatterListViewChanged(
	EventRef				inEvent,
	FormatterListViewData*		inData );
OSStatus FormatterListViewGetData(
	EventRef				inEvent,
	FormatterListViewData*		inData );
OSStatus FormatterListViewSetData(
	EventRef				inEvent,
	FormatterListViewData*		inData );
OSStatus FormatterListViewGetRegion(
	EventRef				inEvent,
	FormatterListViewData*		inData );
ControlPartCode FormatterListViewFindPart(
	const HIRect*			inBounds,
	const HIPoint*			inWhere,
	FormatterListViewData*		inData );
void FormatterListViewDefaultDrawPart(
	ControlPartCode			inPart,
	const HIRect*			inPartRect
	);
void FormatterListViewDefaultDrawPartLabel(
	ControlPartCode			inPart,
	const HIRect*			inPartRect
	);
void FormatterListViewSetUpData(
	FormatterListViewData*		inData );

// -----------------------------------------------------------------------------
//	globals
// -----------------------------------------------------------------------------
//

// -----------------------------------------------------------------------------
//	FormatterListViewCreate
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewCreate(	WindowRef			theWindow )
{
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    Rect rectR;
    
	OSStatus			err=noErr;
	ControlRef			root;
	EventRef			event;
	
	// Make sure this type of view is registered
	FormatterListViewRegister();

	// Make the initialization event
	err = CreateEvent( NULL, kEventClassHIObject, kEventHIObjectInitialize,
			GetCurrentEventTime(), 0, &event );
	
	// Set the bounds into the event
        rectR.top=rectR.left=0;
rectR.right=        nowCD->FormatterListViewRect.size.width;
      rectR.bottom=  nowCD->FormatterListViewRect.size.height;
        err = SetEventParameter( event, 'Boun', typeQDRectangle,
                                 sizeof( Rect ), &rectR );

        err = SetEventParameter(event,'MYWR',typeVoidPtr,sizeof(WindowRef),&theWindow);
	err = HIObjectCreate( kFormatterListViewClassID, event, (HIObjectRef*) &nowCD->FormatterListView );

	// Get the content root
	err = GetRootControl( theWindow, &root );
	
	// And stick this view into it
	err = HIViewAddSubview( root, nowCD->FormatterListView );
	
	ReleaseEvent( event );

             

	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewRegister
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewRegister(void)
{
	OSStatus				err = noErr;
	static HIObjectClassRef	sFormatterListViewClassRef = NULL;

	if ( sFormatterListViewClassRef == NULL )
	{
		EventTypeSpec		eventList[] = {
			{ kEventClassHIObject, kEventHIObjectConstruct },
			{ kEventClassHIObject, kEventHIObjectInitialize },
			{ kEventClassHIObject, kEventHIObjectDestruct },
			{ kEventClassControl, kEventControlInitialize },
			{ kEventClassControl, kEventControlDraw },
                                                                                { kEventClassControl, kEventControlClick },
			{ kEventClassControl, kEventControlHitTest },
			{ kEventClassControl, kEventControlTrack },
			{ kEventClassControl, kEventControlValueFieldChanged },
			{ kEventClassControl, kEventControlHiliteChanged },
			{ kEventClassControl, kEventControlGetData },
			{ kEventClassControl, kEventControlSetData },
			{ kEventClassControl, kEventControlGetPartRegion },
                {                    kEventClassScrollable,kEventScrollableInfoChanged}

                };

   
		err = HIObjectRegisterSubclass(
			kFormatterListViewClassID,		// class ID
			kHIViewClassID,				// base class ID
			NULL,						// option bits
			FormatterListViewHandler,		// construct proc
			GetEventTypeCount( eventList ),
			eventList,
			NULL,						// construct data,
			&sFormatterListViewClassRef );
	}
	
	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewHandler
// -----------------------------------------------------------------------------
//	This is the bottleneck for incoming events
//
OSStatus FormatterListViewHandler(
	EventHandlerCallRef		inCallRef,
	EventRef				inEvent,
	void*					inUserData )
{
	OSStatus				err = eventNotHandledErr;
	UInt32					eventClass = GetEventClass( inEvent );
	UInt32					eventKind = GetEventKind( inEvent );
	FormatterListViewData*		data = (FormatterListViewData*) inUserData;

	switch ( eventClass )
	{
		case kEventClassHIObject:
		{
			switch ( eventKind )
			{
				case kEventHIObjectConstruct:
					err = FormatterListViewConstruct( inEvent );
					break;

				case kEventHIObjectInitialize:
					err = FormatterListViewInitialize( inCallRef, inEvent, data );
					break;

				case kEventHIObjectDestruct:
					// don't CallNextEventHandler!
					err = FormatterListViewDestruct( inEvent, data );
					break;
			}
		}
		break;
		
		case kEventClassControl:
		{
			switch ( eventKind )
			{
				case kEventControlInitialize:
					err = noErr;
					break;

				case kEventControlDraw:
// err=                                    FormatterListViewDrawQuartz( inEvent, data );
                                   err=                                    FormatterListViewDraw( inEvent, data );

                                    break;
                                case kEventControlClick:
                                    data->clickCount = 1;
                                    GetEventParameter(inEvent, kEventParamClickCount, typeUInt32, NULL, sizeof(data->clickCount), NULL, &data->clickCount);
                                    
                                    break;
                                    
				case kEventControlHitTest:
					err = FormatterListViewHitTest( inEvent, data );
					break;
				
				case kEventControlTrack:
					err = FormatterListViewTrack( inEvent, data );
					break;
				
				case kEventControlValueFieldChanged:
				case kEventControlHiliteChanged:
					err = FormatterListViewChanged( inEvent, data );
					break;

				case kEventControlGetData:
					err = FormatterListViewGetData( inEvent, data );
					break;

				case kEventControlSetData:
					err = FormatterListViewSetData( inEvent, data );
					break;
				
				case kEventControlGetPartRegion:
					err = FormatterListViewGetRegion( inEvent, data );
					break;
			}
		}
		break;
                case kEventClassScrollable:
                    // kEventScrollableInfoChanged
                    DoAbout();
                    break;
        }
	
	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewConstruct
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewConstruct(
	EventRef			inEvent )
{
    OSStatus			err=noErr;
	FormatterListViewData*	data;
        
	// don't CallNextEventHandler!
	data = (FormatterListViewData*) calloc( 1,sizeof( FormatterListViewData ) );
	// Set up the default drawing callbacks

	
	// Keep a copy of the created HIViewRef
	err = GetEventParameter( inEvent, kEventParamHIObjectInstance, typeHIObjectRef,
			NULL, sizeof( HIObjectRef ), NULL, (HIObjectRef*) &data->view );
  
        
	// Set the userData that will be used with all subsequent eventHandler calls
	err = SetEventParameter( inEvent, kEventParamHIObjectInstance, typeVoidPtr,
			sizeof( FormatterListViewData* ), &data ); 

        
        
	if ( err != noErr )
		free( data );

	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewDestruct
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewDestruct(
	EventRef			inEvent,
	FormatterListViewData*	inData )
{
#pragma unused( inEvent )
	// Clean up any allocated data
	free( inData );

	return noErr;
}

// -----------------------------------------------------------------------------
//	FormatterListViewInitialize
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewInitialize(
	EventHandlerCallRef	inCallRef,
	EventRef			inEvent,
	FormatterListViewData*	inData )
{
	OSStatus			err;
    CGContextRef cgRef;
	Rect				bounds;
	UInt32				features = kControlSupportsDataAccess+kControlHasSpecialBackground+kControlSupportsDragAndDrop;
	// Let the base class initialization occur
	err = CallNextEventHandler( inCallRef, inEvent );
	require_noerr( err, TroubleInSuperClass );

	// Extract the initial view bounds from the event
	err = GetEventParameter( inEvent, 'Boun', typeQDRectangle,
			NULL, sizeof( Rect ), NULL, &bounds );
	require_noerr( err, ParameterMissing );
	       err = GetEventParameter(inEvent,'MYWR',typeVoidPtr,0,sizeof(WindowRef),NULL,&inData->theWindow);

               err = GetEventParameter( inEvent, kEventParamCGContextRef, typeCGContextRef,
                                        NULL, sizeof( CGContextRef ), NULL, &cgRef );

	// Set up this view's feature bits
	err = SetEventParameter( inEvent, kEventParamControlFeatures, typeUInt32,
			sizeof( UInt32 ), &features );

	SetControlBounds( inData->view, &bounds );
        {
            WindowRef theWindow=inData->theWindow; // GetControlOwner(inData->view);
            WCH tempWC = (WCH)GetWRefCon(theWindow);
            FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
// set a flag
            

        }
        
ParameterMissing:
TroubleInSuperClass:
	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewDraw
// -----------------------------------------------------------------------------
//
#pragma mark Drawing
OSStatus FormatterListViewDraw(
	EventRef			inEvent,
	FormatterListViewData*	inData )
{
	OSStatus			err;
	HIRect				bounds;
        CGRect rowRect;
        Boolean switcher=false;
        ControlID theID;
        CGrafPtr thePort;
        LoopVar qq;
        UInt16 numRows,numRowsToWrite;
        UInt16 vInc,vPos,hPos,curScrollVal,tempNummer;
        CGContextRef cgRef;
        UInt32 formatterCount = CountAllStructureFormatters();
         PeekitStructFormatterPtr startHere=gFormatters;
        char buffer[10];
        WCH tempWC = (WCH)GetWRefCon( inData->theWindow);
        FormatWWDataP  nowCD = (FormatWWDataP)(*tempWC)->dataStore;
// and the parent parent
        err = GetEventParameter( inEvent, kEventParamCGContextRef, typeCGContextRef,
                                 NULL, sizeof( CGContextRef ), NULL, &cgRef );
        
        
        // an I set the text paramters here?
        CGContextSetRGBFillColor (cgRef, 0, 0, 0, 1); 
        Str255 fontName="\pLucida Grande";
        inData->countInView =0; // none drawn yet
        fontName[fontName[0] + 1] = 0;  // make (char*)&fontName[1] a C-string
        CGContextSelectFont(cgRef, (char*)&fontName[1],  gDefaultFontSize, kCGEncodingMacRoman);        
        CGContextSetTextMatrix(cgRef, CGAffineTransformMakeScale(1, -1));
        err = HIViewGetBounds( inData->view, &bounds );

        rowRect.origin.x = 0; // theHIRect.origin.x;
        rowRect.origin.y= 0; // theHIRect.origin.y ;
        rowRect.size.width = bounds.size.width;
        rowRect.size.height=inData->listViewCellHi;

     numRows = bounds.size.height/inData->listViewCellHi;
        curScrollVal = GetControlValue(nowCD->fListScroll);
		tempNummer = curScrollVal;
// move to this one
        while(tempNummer){startHere = startHere->next;tempNummer--;}
hPos=        rowRect.origin.x +2;
vPos = inData->listViewCellHi-2;
        for(qq=0;qq<numRows;qq++){
            if((curScrollVal + qq)&0x1){
                PaintCGRectWithCGRGBColorPtr(cgRef,rowRect,&gTheColors[kRightColColor]);
                
            } else {
                PaintCGRectWithCGRGBColorPtr(cgRef,rowRect,&gTheColors[kLeftColColor]);
                
            }
            // frame it if selected
            if(nowCD->selected == qq+ curScrollVal){
                gCGSelectionRangeColor.alpha=.3;
                
                PaintCGRectWithCGRGBColorPtr(cgRef,rowRect,&gCGSelectionRangeColor);
                
            }
            
            // and ther name of this formatter
            
                if(startHere){
                    char bytes[50];
                    CFIndex used;
                    inData->countInView++;
                CGContextSetRGBFillColor (cgRef, gBlack.red, gBlack.green, gBlack.blue, 1); 

// if it's locked then add a display dot a'for it.  Nah, that's ugly.  Make a locked colunmn
                // lock column would be the last 20? pixels
            // so do some clipping
                {
                    CGRect clipRect;
char dot = 'L';
UInt16 hp2=hPos;
                    CGContextSaveGState(cgRef);
                         clipRect=bounds;   
                         clipRect.size.width-=20;
                         CGContextClipToRect (cgRef,clipRect  );    
                    CFStringGetBytes(startHere->title, CFRangeMake(0,CFStringGetLength(startHere->title)), kCFStringEncodingASCII,0, false, &bytes,50, &used);

                    
                     CGContextShowTextAtPoint(cgRef,hPos,vPos,&bytes,used);
                     CGContextRestoreGState(cgRef);	
                     CGContextSaveGState(cgRef);

                     if(startHere->flags & kPIDataFormatterLocked){
                     // changing, if it's locked then bold, if not then pale
                         CGContextSetRGBFillColor (cgRef, 0, 0, 0, 1); 

                     } else {
                         CGContextSetRGBFillColor (cgRef, 0, 0, 0, .3); 
                     
                     }
                         // if it's locked, draw a dot
                     hp2=        rowRect.origin.x +rowRect.size.width - 12;
                     
                     CGContextShowTextAtPoint(cgRef,hp2,vPos,&dot,1);
                     CGContextRestoreGState(cgRef);	
                     

                }
                     startHere=startHere->next;
                }
            
            rowRect.origin.y+=inData->listViewCellHi;
vPos+=            inData->listViewCellHi;
        }

        FrameCGRectWithRGBColorPtr(cgRef,1,bounds/* grabRect*/,&gBlack);
        {    CGRGBColor draggerGrey={0,0,0,.5};
        // draw a line down too for the locked column.  ah, fuck it, nevermind
        CGContextSetRGBStrokeColor(cgRef,draggerGrey.red, draggerGrey.green, draggerGrey.blue, draggerGrey.alpha); 	

        // walk through the grabbers and drop a line
            CGContextBeginPath(cgRef);
            CGContextMoveToPoint(cgRef,(bounds.origin.x + bounds.size.width) - 20 ,bounds.origin.y);
            CGContextAddLineToPoint(cgRef, (bounds.origin.x + bounds.size.width) - 20, bounds.origin.y +bounds.size.height);
            CGContextStrokePath(cgRef);
        }
        
        
        
        
	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewHitTest
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewHitTest(
	EventRef			inEvent,
	FormatterListViewData*	inData )
{
	OSStatus			err=0;
	HIRect				bounds;
	HIPoint				where;
	ControlPartCode		part;


	err = GetEventParameter( inEvent, kEventParamMouseLocation, typeHIPoint,
			NULL, sizeof( HIPoint ), NULL, &where );
	require_noerr( err, ParameterMissing );

	err = HIViewGetBounds( inData->view, &bounds );

	part = FormatterListViewFindPart( &bounds, &where, inData );

	err = SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
			sizeof( ControlPartCode ), &part ); 

ParameterMissing:
	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewTrack
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewTrack(
	EventRef			inEvent,
	FormatterListViewData*	inData )
{	ControlID theID;
    RgnHandle r1;
	OSStatus			err;
	ControlPartCode		part;
	Point				qdPt;
	MouseTrackingResult	mouseResult;
        UInt16 height,rowsInView;;
        CGrafPtr thePorter;
        WCH tempWC;
        Rect controlBounds,newControl;
        FormatWWDataP nowCD;
        WindowRef theWindow = inData->theWindow;
        Rect tempRect;
        UInt16 oldSelected =0;

        tempWC = (WCH)GetWRefCon(theWindow);
        nowCD = (FormatWWDataP)(*tempWC)->dataStore;


        theWindow=GetControlOwner(inData->view);
        thePorter = GetWindowPort(theWindow);
        GetControlBounds(inData->view,&controlBounds);

        height =   inData->listViewCellHi;
        mPushPort(theWindow);
        GetMouse(&qdPt);
        mPullPort;
        oldSelected =  nowCD->selected ;
        rowsInView=((qdPt.v-controlBounds.top)/height);
            
        nowCD->selected = rowsInView+GetControlValue(nowCD->fListScroll);
		EnableControl( SnatchCRef(theWindow,'FORM', 1001));
		EnableControl( SnatchCRef(theWindow,'FORM', 1002));

        if((nowCD->selected -GetControlValue(nowCD->fListScroll)) < inData->countInView){
        if(nowCD->selected != oldSelected){
// ++++++++++
			if(IsControlVisible(nowCD->floatingEdit)){
				// we;ve been editing, save that and go away
				slibTextBlockPtr theText = slibGetTextFromEditControl(nowCD->floatingEdit);
				// and replace the name of the current formatter with this name.
				CFRelease(nowCD->currentFormatter->title);
				nowCD->currentFormatter->title = theText->theString;
				CFRetain(nowCD->currentFormatter->title);
				slibDisposeTextBlock(theText);
				
				DisableControl(nowCD->floatingEdit);
				HideControl(nowCD->floatingEdit);
//				inData->editVisible=false;
			}  
			
			// ++++++++++++
			
			HIViewSetNeedsDisplay( inData->view, true );
            nowCD->buildSelected = -1;
            long dummy;
            SetControlData(
                           nowCD->FormatterBuildView ,
                           0,
                           'FBCL',
                           sizeof(dummy),
                           &dummy);
            
            DisableControl( SnatchCRef(theWindow,'FORM', 1003));

            HIViewSetNeedsDisplay( nowCD->FormatterBuildView, true );
// and at this point set the formatter
			{
			PeekitStructFormatterPtr startHere = gFormatters;
				UInt16 counter = nowCD->selected;
				while(counter){
					counter --;
					startHere = startHere->next;
				}
				nowCD->currentFormatter = startHere;
			}
                        // and if the formatter is locked, then you can't do anything with the minus OR with the plus/minus in build world
                        if(nowCD->currentFormatter && nowCD->currentFormatter->flags &kPIDataFormatterLocked ){
                            DisableControl( SnatchCRef(theWindow,'FORM', 1001));
                            DisableControl( SnatchCRef(theWindow,'FORM', 1002));
                            DisableControl( SnatchCRef(theWindow,'FORM', 1003));

                        }
                        
			// and tell the build side to update
        }
        } else {
        // they clicked, but there is nothing there
            if(IsControlVisible(nowCD->floatingEdit)){
                // we;ve been editing, save that and go away
                slibTextBlockPtr theText = slibGetTextFromEditControl(nowCD->floatingEdit);
                // and replace the name of the current formatter with this name.
                CFRelease(nowCD->currentFormatter->title);
                nowCD->currentFormatter->title = theText->theString;
                CFRetain(nowCD->currentFormatter->title);
                slibDisposeTextBlock(theText);
                
                DisableControl(nowCD->floatingEdit);
                HideControl(nowCD->floatingEdit);
                //				inData->editVisible=false;
            }  
            
            nowCD->selected = -1;
			DisableControl( SnatchCRef(theWindow,'FORM', 1001));
                                                                                HIViewSetNeedsDisplay( inData->view, true );
			DisableControl( SnatchCRef(theWindow,'FORM', 1002));
			DisableControl( SnatchCRef(theWindow,'FORM', 1003));
			nowCD->buildSelected = -1;
                        long dummy;
                        SetControlData(
                                       nowCD->FormatterBuildView ,
                                       0,
                                       'FBCL',
                                       sizeof(dummy),
                                       &dummy);
                        
            HIViewSetNeedsDisplay( nowCD->FormatterBuildView, true );

        }
            
        if(inData->clickCount >1 &&  nowCD->selected >=0){
            //double click means they're wantin' to edit this name    
            // so the rect is.....
// of course, it looks like a double-click without a selection can happen
            // one more thing;  if it's in the last 30 pixels just flip the loccked state
            if(qdPt.h > controlBounds.right - 20){
                // flip the bit.  Seriaously
                if( nowCD->currentFormatter){
                if(               nowCD->currentFormatter->flags & kPIDataFormatterLocked)
                {nowCD->currentFormatter->flags &= ~kPIDataFormatterLocked;
                } else      {      
    nowCD->currentFormatter->flags |= kPIDataFormatterLocked;
                    // and do this
                    DisableControl( SnatchCRef(theWindow,'FORM', 1001));
                    DisableControl( SnatchCRef(theWindow,'FORM', 1002));
                    DisableControl( SnatchCRef(theWindow,'FORM', 1003));
                }}
                HIViewSetNeedsDisplay( inData->view, true );

            } else {
            newControl.top=   ( nowCD->selected*inData->listViewCellHi + controlBounds.top)+2;
            newControl.bottom= newControl.top+           inData->listViewCellHi-2; // about -2
            newControl.left = controlBounds.left;
            newControl.right=controlBounds.right;
            SetControlBounds(nowCD->floatingEdit,&newControl);
            ShowControl(nowCD->floatingEdit);
			if(nowCD->currentFormatter){
			//	CFStringToEditControl(nowCD->currentFormatter->title,nowCD->floatingEdit);
				SetControlData(
							   nowCD->floatingEdit,
							   0,
							   kControlEditTextCFStringTag,
							   sizeof(CFStringRef),
		 					   &nowCD->currentFormatter->title);
			}
			
			ControlEditTextSelectionRec  theSel;
			theSel.selStart =0;
			theSel.selEnd = CFStringGetLength(nowCD->currentFormatter->title);
			SetControlData(
						   nowCD->floatingEdit,                   0,
						   kControlEditTextSelectionTag,
						   sizeof(ControlEditTextSelectionRec),
						   &theSel
						   );
			
            EnableControl(nowCD->floatingEdit);
// set the text in the control
			
            SetKeyboardFocus(
                              inData->theWindow,
                             nowCD->floatingEdit,
                             kControlFocusNoPart);
            SetKeyboardFocus(
                             inData->theWindow,
                             nowCD->floatingEdit,
                             kControlFocusNextPart);
//            inData->editVisible = true;
        }
        } else {
do{

		err = TrackMouseLocation(thePorter, &qdPt, &mouseResult );
  switch(mouseResult){
      case kMouseTrackingMouseDragged:
      {
          oldSelected =  nowCD->selected ;
          rowsInView=((qdPt.v-controlBounds.top)/height);
              
              nowCD->selected = rowsInView+GetControlValue(nowCD->fListScroll);
			  EnableControl( SnatchCRef(theWindow,'FORM', 1001));
			  EnableControl( SnatchCRef(theWindow,'FORM', 1002));


          if((nowCD->selected -GetControlValue(nowCD->fListScroll)) < inData->countInView){
              if(nowCD->selected != oldSelected){
                  HIViewSetNeedsDisplay( inData->view, true );
                  
                  DisableControl( SnatchCRef(theWindow,'FORM', 1003));

                  nowCD->buildSelected = -1;
                  long dummy;
                  SetControlData(
                                 nowCD->FormatterBuildView ,
                                 0,
                                 'FBCL',
                                 sizeof(dummy),
                                 &dummy);
                  
                  HIViewSetNeedsDisplay( nowCD->FormatterBuildView, true );
                  
              }
          } else {
              // they clicked, but there is nothing there
              nowCD->selected = -1;
			  DisableControl( SnatchCRef(theWindow,'FORM', 1001));
// whennever we negate the selection of a formatter, we also have to negate the build thingus
			  DisableControl( SnatchCRef(theWindow,'FORM', 1002));
			  DisableControl( SnatchCRef(theWindow,'FORM', 1003));
			  nowCD->buildSelected = -1;

              HIViewSetNeedsDisplay( inData->view, true );
              long dummy;
              SetControlData(
                             nowCD->FormatterBuildView ,
                             0,
                             'FBCL',
                             sizeof(dummy),
                             &dummy);
              
              HIViewSetNeedsDisplay( nowCD->FormatterBuildView, true );

          }
          
    
      }
              break;        
  

  }
}while( mouseResult != kMouseTrackingMouseUp);
}
// at this point I want to wake up the build side.
    err = SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
			sizeof( ControlPartCode ), &part ); 

	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewChanged
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewChanged(
	EventRef			inEvent,
	FormatterListViewData*	inData )
{
#pragma unused( inEvent )
	OSStatus			err = noErr;

	HIViewSetNeedsDisplay( inData->view, true );

	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewGetData
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewGetData(
	EventRef				inEvent,
	FormatterListViewData*		inData )
{
	OSStatus				err;
	ControlPartCode			part;
	OSType					tag;
	Ptr						ptr;
	Size					size;
	Size					outSize;
	
	err = GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
			NULL, sizeof( ControlPartCode ), NULL, &part );
	require_noerr( err, ParameterMissing );

	err = GetEventParameter( inEvent, kEventParamControlDataTag, typeEnumeration,
			NULL, sizeof( OSType ), NULL, &tag );
	require_noerr( err, ParameterMissing );

	err = GetEventParameter( inEvent, kEventParamControlDataBuffer, typePtr,
			NULL, sizeof( Ptr ), NULL, &ptr );
	require_noerr( err, ParameterMissing );

	err = GetEventParameter( inEvent, kEventParamControlDataBufferSize, typeLongInteger,
			NULL, sizeof( Size ), NULL, &size );
	require_noerr( err, ParameterMissing );
        switch(tag){
            case kslibHIVIewElementsInView:
                // tell 'em how many will fit
                
                break;
            case     kslibHIViewCellHeight:
                inData->listViewCellHi=gDefaultFontSize+4;
                *((long *)ptr) = gDefaultFontSize+4;  // ‚Ä¢‚Ä¢¬†fix 
                break;
case                kslibHIViewCellWide:
    break;
        }

	if ( err == noErr )
		err = SetEventParameter( inEvent, kEventParamControlDataBufferSize, typeLongInteger,
				sizeof( Size ), &outSize );

ParameterMissing:
	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewSetData
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewSetData(
	EventRef				inEvent,
	FormatterListViewData*		inData )
{
	OSStatus				err;
	ControlPartCode			part;
	OSType					tag;
	Ptr						ptr;
            Ptr aLong=0;
UInt32  yesL=0;
            Size					size;
	err = GetEventParameter( inEvent, kEventParamControlDataTag, typeEnumeration,
                                 NULL, sizeof( OSType ), NULL, &tag );
        if(tag == 'VIWP'){

            err = GetEventParameter( inEvent, kEventParamControlDataBufferSize, typeLongInteger,
                                     NULL, sizeof( Size ), NULL, &size );
            err = GetEventParameter( inEvent, kEventParamControlDataBuffer, typePtr,
                                     NULL, sizeof( Ptr ), NULL, &aLong );
            yesL = *((long *)aLong);

        }
	return err;
}

// -----------------------------------------------------------------------------
//	FormatterListViewGetRegion
// -----------------------------------------------------------------------------
//
OSStatus FormatterListViewGetRegion(
	EventRef				inEvent,
	FormatterListViewData*		inData )
{
	OSStatus				err;
	ControlPartCode			part;
	RgnHandle				outRegion;
	HIRect					bounds;
	Rect					qdBounds;
	
	err = GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
			NULL, sizeof( ControlPartCode ), NULL, &part );
	require_noerr( err, ParameterMissing );

	err = GetEventParameter( inEvent, kEventParamControlRegion, typeQDRgnHandle,
			NULL, sizeof( RgnHandle ), NULL, &outRegion );

	if ( part == kControlContentMetaPart
			|| part == kControlStructureMetaPart
	) //		 || part == kControlOpaqueRegionMetaPart  )
	{
		HIViewGetBounds( inData->view, &bounds );
		qdBounds.top = (SInt16) CGRectGetMinY( bounds );
		qdBounds.left = (SInt16) CGRectGetMinX( bounds );
		qdBounds.bottom = (SInt16) CGRectGetMaxY( bounds );
		qdBounds.right = (SInt16) CGRectGetMaxX( bounds );
	
		RectRgn( outRegion, &qdBounds );
	}
	
ParameterMissing:
	return err;
}

// -----------------------------------------------------------------------------
//	FindPart
// -----------------------------------------------------------------------------
//
ControlPartCode FormatterListViewFindPart(
	const HIRect*		inBounds,
	const HIPoint*		inWhere,
	FormatterListViewData*	inData )
{
	ControlPartCode		part;
// don't really have parts.
        // so just say 1
	part = 1;

	return part;
}

void SizeFormatterListViews(WindowRef theWindow,FormatWWDataP nowCD)
{
    Rect thisRect;
    HIRect   inRect;
    /*     CGPoint origin;
    CGSize size */
    if(nowCD->FormatterListView){
        HIViewSetFrame(
                       nowCD->FormatterListView,
                       &nowCD->FormatterListViewRect);
            HIViewSetNeedsDisplay(  nowCD->FormatterListView, true );
    }


}






/*
 *  formatterbuildview.pi.c
 *  PeekIt
 *
 *  Created by C.K. Haun on 11/26/05.
 *  Copyright 2005 Ravenware Software. All rights reserved.
 *
 */

// -----------------------------------------------------------------------------
// FormatterBuildView API
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewCreate(                            WindowRef				inWindow,void * columnRights);





// -----------------------------------------------------------------------------
//	constants
// -----------------------------------------------------------------------------
//

#define kFormatterBuildViewClassID	CFSTR( "com.Ravenware.FormatterBuildView" )

// const ControlPartCode	kControlOpaqueRegionMetaPart = -3;

// -----------------------------------------------------------------------------
//	types
// -----------------------------------------------------------------------------
//
typedef struct
{
    HIViewRef			view;
    // Geometry
    Boolean setRightsFromSave;
    WindowRef theWindow;
    UInt16 buildViewCellHi;
    //	UInt16        buildSelected;
    UInt16 columnRightsCG[6];
    UInt16 columnRightsQD[6];
    CGRect dragRectsCG[6];
    Rect dragRectsQD[6];
    UInt16 hPos;
    UInt16 vPos;
    
    UInt32        clickCount;
    UInt32 countInView;   // added up during drawing
    SInt16 editColumnActive;
    PIDataFormatterPtr activeFormatter;
    MouseTrackingRef trackingRef;
    UInt16 numOfStandardMenuItems;
} FormatterBuildViewData;
enum{
    kFormNameColRight=0,
    kFormTypeColRight,
    kFormLenColRight,
    kFormSignColRight,
    kFormEndianColRight,
    kFormEndColRight
};
enum{
    kFBNameCol,
    kFBTypeCol,
    kFBLenCol,
    kFBSignCol,
    kFBEndianCol,
    kFBHexCol
};
// -----------------------------------------------------------------------------
//	prototypes
// -----------------------------------------------------------------------------
//

OSStatus FormatterBuildViewRegister(void);
OSStatus FormatterBuildViewHandler(
                                   EventHandlerCallRef		inCallRef,
                                   EventRef				inEvent,
                                   void*					inUserData );
OSStatus FormatterBuildViewConstruct(
                                     EventRef				inEvent );
OSStatus FormatterBuildViewInitialize(
                                      EventHandlerCallRef		inCallRef,
                                      EventRef				inEvent,
                                      FormatterBuildViewData*		inData );
OSStatus FormatterBuildViewDestruct(
                                    EventRef				inEvent,
                                    FormatterBuildViewData*		inData );
OSStatus FormatterBuildViewDraw(
                                EventRef				inEvent,
                                FormatterBuildViewData*		inData );
OSStatus FormatterBuildViewHitTest(
                                   EventRef				inEvent,
                                   FormatterBuildViewData*		inData );
OSStatus FormatterBuildViewTrack(
                                 EventRef				inEvent,
                                 FormatterBuildViewData*		inData );
OSStatus FormatterBuildViewChanged(
                                   EventRef				inEvent,
                                   FormatterBuildViewData*		inData );
OSStatus FormatterBuildViewGetData(
                                   EventRef				inEvent,
                                   FormatterBuildViewData*		inData );
OSStatus FormatterBuildViewSetData(
                                   EventRef				inEvent,
                                   FormatterBuildViewData*		inData );
OSStatus FormatterBuildViewGetRegion(
                                     EventRef				inEvent,
                                     FormatterBuildViewData*		inData );
OSStatus FormatterBuildViewBoundsChanged(
                                         EventRef				inEvent,
                                         FormatterBuildViewData*		inData );
ControlPartCode FormatterBuildViewFindPart(
                                           const HIRect*			inBounds,
                                           const HIPoint*			inWhere,
                                           FormatterBuildViewData*		inData );
void FormatterBuildViewDefaultDrawPart(
                                       ControlPartCode			inPart,
                                       const HIRect*			inPartRect
                                       );
void FormatterBuildViewDefaultDrawPartLabel(
                                            ControlPartCode			inPart,
                                            const HIRect*			inPartRect
                                            );
void FormatterBuildViewSetUpData(
                                 FormatterBuildViewData*		inData );
void SetInitialBuildColumnRights(  FormatterBuildViewData*	inData, FormatWWDataP  nowCD ,void * theOther);
void CalculateBuildAreaRects(  FormatterBuildViewData*	inData, FormatWWDataP  nowCD );

// -----------------------------------------------------------------------------
//	globals
// -----------------------------------------------------------------------------
//

// -----------------------------------------------------------------------------
//	FormatterBuildViewCreate
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewCreate(	WindowRef			theWindow,void * columnRightsIn )
{
    WCH tempWC = (WCH)GetWRefCon(theWindow);
    FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    Rect rectR;
    
    OSStatus			err=noErr;
    ControlRef			root;
    EventRef			event;
    
    // Make sure this type of view is registered
    FormatterBuildViewRegister();
    
    // Make the initialization event
    err = CreateEvent( NULL, kEventClassHIObject, kEventHIObjectInitialize,
                       GetCurrentEventTime(), 0, &event );
    
    // Set the bounds into the event
    rectR.top=rectR.left=0;
    rectR.right=        nowCD->FormatterBuildViewRect.size.width;
    rectR.bottom=  nowCD->FormatterBuildViewRect.size.height;
    err = SetEventParameter( event, 'Boun', typeQDRectangle,
                             sizeof( Rect ), &rectR );
    
    err = SetEventParameter(event,'MYWR',typeVoidPtr,sizeof(WindowRef),&theWindow);
    if(columnRightsIn){
    Ptr ookies = malloc(sizeof(UInt16  )*6);
    BlockMoveData(    columnRightsIn,ookies,sizeof(UInt16  )*6);
    err = SetEventParameter(event,'CLRT',typeVoidPtr,sizeof(Ptr),&ookies);
    }
        // free(ookies);  // someday
    err = HIObjectCreate( kFormatterBuildViewClassID, event, (HIObjectRef*) &nowCD->FormatterBuildView );
    
    // Get the content root
    err = GetRootControl( theWindow, &root );
    
    // And stick this view into it
    err = HIViewAddSubview( root, nowCD->FormatterBuildView );
    
    ReleaseEvent( event );
    
    
    
    return err;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewRegister
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewRegister(void)
{
    OSStatus				err = noErr;
    static HIObjectClassRef	sFormatterBuildViewClassRef = NULL;
    
    if ( sFormatterBuildViewClassRef == NULL )
    {
        EventTypeSpec		eventList[] = {
        { kEventClassHIObject, kEventHIObjectConstruct },
        { kEventClassHIObject, kEventHIObjectInitialize },
        { kEventClassHIObject, kEventHIObjectDestruct },
        { kEventClassControl, kEventControlInitialize },
        { kEventClassControl, kEventControlDraw },
        { kEventClassControl, kEventControlClick },                    
        { kEventClassControl, kEventControlHitTest },
        { kEventClassControl, kEventControlTrack },
        { kEventClassControl, kEventControlValueFieldChanged },
        { kEventClassControl, kEventControlHiliteChanged },
        { kEventClassControl, kEventControlGetData },
        { kEventClassControl, kEventControlSetData },
        { kEventClassControl, kEventControlGetPartRegion },
        {kEventClassControl,kEventControlBoundsChanged},
        {                    kEventClassScrollable,kEventScrollableInfoChanged}
            
            
        };
        
        
        err = HIObjectRegisterSubclass(
                                       kFormatterBuildViewClassID,		// class ID
                                       kHIViewClassID,				// base class ID
                                       NULL,						// option bits
                                       FormatterBuildViewHandler,		// construct proc
                                       GetEventTypeCount( eventList ),
                                       eventList,
                                       NULL,						// construct data,
                                       &sFormatterBuildViewClassRef );
    }
    
    return err;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewHandler
// -----------------------------------------------------------------------------
//	This is the bottleneck for incoming events
//
OSStatus FormatterBuildViewHandler(
                                   EventHandlerCallRef		inCallRef,
                                   EventRef				inEvent,
                                   void*					inUserData )
{
    OSStatus				err = eventNotHandledErr;
    UInt32					eventClass = GetEventClass( inEvent );
    UInt32					eventKind = GetEventKind( inEvent );
    FormatterBuildViewData*		data = (FormatterBuildViewData*) inUserData;
    
    switch ( eventClass )
    {
        case kEventClassHIObject:
        {
            switch ( eventKind )
            {
                case kEventHIObjectConstruct:
                    err = FormatterBuildViewConstruct( inEvent );
                    break;
                    
                case kEventHIObjectInitialize:
                    err = FormatterBuildViewInitialize( inCallRef, inEvent, data );
                    break;
                    
                case kEventHIObjectDestruct:
                    // don't CallNextEventHandler!
                    err = FormatterBuildViewDestruct( inEvent, data );
                    break;
            }
        }
            break;
            
        case kEventClassControl:
        {
            switch ( eventKind )
            {
                case kEventControlInitialize:
                    err = noErr;
                    break;
                    
                case kEventControlDraw:
                    // err=                                    FormatterBuildViewDrawQuartz( inEvent, data );
                    err=                                    FormatterBuildViewDraw( inEvent, data );
                    
                    break;
                case kEventControlClick:
                    data->clickCount = 1;
                    GetEventParameter(inEvent, kEventParamClickCount, typeUInt32, NULL, sizeof(data->clickCount), NULL, &data->clickCount);
                    
                    break;
                case kEventControlHitTest:
                    err = FormatterBuildViewHitTest( inEvent, data );
                    break;
                    
                case kEventControlTrack:
                    err = FormatterBuildViewTrack( inEvent, data );
                    break;
                    
                case kEventControlValueFieldChanged:
                case kEventControlHiliteChanged:
                    err = FormatterBuildViewChanged( inEvent, data );
                    break;
                    
                case kEventControlGetData:
                    err = FormatterBuildViewGetData( inEvent, data );
                    break;
                    
                case kEventControlSetData:
                    err = FormatterBuildViewSetData( inEvent, data );
                    break;
                    
                case kEventControlGetPartRegion:
                    err = FormatterBuildViewGetRegion( inEvent, data );
                    break;
                case kEventControlBoundsChanged:
                    err = FormatterBuildViewBoundsChanged( inEvent, data );
                    
                    break;
            }
        }
            break;
        case kEventClassScrollable:
            // kEventScrollableInfoChanged
            DoAbout();
            break;
    }
    
    return err;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewConstruct
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewConstruct(
                                     EventRef			inEvent )
{
    OSStatus			err=noErr;
    FormatterBuildViewData*	data;
    
    // don't CallNextEventHandler!
    data = (FormatterBuildViewData*) calloc( 1,sizeof( FormatterBuildViewData ) );
    // Set up the default drawing callbacks
    
    
    // Keep a copy of the created HIViewRef
    err = GetEventParameter( inEvent, kEventParamHIObjectInstance, typeHIObjectRef,
                             NULL, sizeof( HIObjectRef ), NULL, (HIObjectRef*) &data->view );
    
    
    // Set the userData that will be used with all subsequent eventHandler calls
    err = SetEventParameter( inEvent, kEventParamHIObjectInstance, typeVoidPtr,
                             sizeof( FormatterBuildViewData* ), &data ); 
    
    
    
    if ( err != noErr )
        free( data );
    
    return err;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewDestruct
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewDestruct(
                                    EventRef			inEvent,
                                    FormatterBuildViewData*	inData )
{
#pragma unused( inEvent )
    // Clean up any allocated data
    free( inData );
    
    return noErr;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewInitialize
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewInitialize(
                                      EventHandlerCallRef	inCallRef,
                                      EventRef			inEvent,
                                      FormatterBuildViewData*	inData )
{
    OSStatus			err;
    CGContextRef cgRef;
    LoopVar qq;
    Rect				bounds;
    UInt32				features = kControlSupportsDataAccess+kControlHasSpecialBackground+kControlSupportsDragAndDrop;
    UInt16 * colRights=0;
    // Let the base class initialization occur
    err = CallNextEventHandler( inCallRef, inEvent );
    require_noerr( err, TroubleInSuperClass );
    
    // Extract the initial view bounds from the event
    err = GetEventParameter( inEvent, 'Boun', typeQDRectangle,
                             NULL, sizeof( Rect ), NULL, &bounds );
    require_noerr( err, ParameterMissing );
    err = GetEventParameter(inEvent,'MYWR',typeVoidPtr,0,sizeof(WindowRef),NULL,&inData->theWindow);
    err = GetEventParameter(inEvent,'CLRT',typeVoidPtr,0,sizeof(WindowRef),NULL,&colRights);
    if(err == noErr){
    LoopVar qq = 0;
        for(qq=0;qq<6;qq++){
            inData->columnRightsCG[qq] = *colRights;
            colRights = colRights + 1;
            
        }
        inData->setRightsFromSave = true;
    }
    err = GetEventParameter( inEvent, kEventParamCGContextRef, typeCGContextRef,
                             NULL, sizeof( CGContextRef ), NULL, &cgRef );
    
    // Set up this view's feature bits
    err = SetEventParameter( inEvent, kEventParamControlFeatures, typeUInt32,
                             sizeof( UInt32 ), &features );
    
    SetControlBounds( inData->view, &bounds );
    {
        OSStatus myErr = 0;
        WindowRef theWindow=inData->theWindow; // GetControlOwner(inData->view);
        WCH tempWC = (WCH)GetWRefCon(theWindow);
        FormatWWDataP nowCD = (FormatWWDataP)(*tempWC)->dataStore;
        // set a flag
        inData->buildViewCellHi=gDefaultFontSize+4;
// see if any rights were passed in
        if(colRights == 0)
            SetInitialBuildColumnRights( 	inData,   nowCD ,0);
        
        CalculateBuildAreaRects(  	inData,  nowCD );
        
    }
    inData->editColumnActive = -1; 
ParameterMissing:
TroubleInSuperClass:
        return err;
}
void SetInitialBuildColumnRights(  FormatterBuildViewData*	inData, FormatWWDataP  nowCD, void * theOther )
{
    HIRect				bounds,rowRect;
    CGRect grabRect ;
    UInt16 hInc,hPos,vPos;
    Rect controlRect;
    GetControlBounds(inData->view,&controlRect);
    HIViewGetBounds( inData->view, &bounds );
    // figure out the spacing
    hInc=bounds.size.width/10; 
    
    rowRect.origin.x = 0; // theHIRect.origin.x;
    rowRect.origin.y= 0; // theHIRect.origin.y ;
    rowRect.size.width = bounds.size.width;
    rowRect.size.height=inData->buildViewCellHi;
    grabRect = rowRect;
    hPos=    inData->hPos=        rowRect.origin.x +2;
//    vPos=    inData->vPos = inData->buildViewCellHi-2;
    hPos += hInc*4; // *3;
    inData->columnRightsCG[kFormNameColRight]=hPos;
    
    hPos += hInc*2;
    inData->columnRightsCG[kFormTypeColRight]=hPos;
    
    hPos += hInc ; // *2;
    inData->columnRightsCG[kFormLenColRight]=hPos;
    
    hPos += hInc; // *2;
    inData->columnRightsCG[kFormSignColRight]=hPos;
    
    
    hPos += hInc; // *2;
    inData->columnRightsCG[kFormEndianColRight]=hPos;
    
    inData->columnRightsCG[kFormEndColRight]= rowRect.origin.x+rowRect.size.width;
    
}


void fbuildmousecallback(EventKind eventKind,EventRef inEvent,MouseTrackingRef theRef, void * refCon)
{
    
    switch(eventKind){
        case  kEventMouseEntered:
            SetThemeCursor(kThemeResizeLeftRightCursor);
            break;
        case kEventMouseExited :
            SetThemeCursor(kThemeArrowCursor);
            break;
    }
}

void CalculateBuildAreaRects(  FormatterBuildViewData*	inData, FormatWWDataP  nowCD )
{
    HIRect				bounds,rowRect;
    CGRect grabRect ;
    UInt16 hInc,hPos,vPos;
    Point qdOrigin;
    Rect controlRect;
    GetControlBounds(inData->view,&controlRect);
    qdOrigin.h = controlRect.left;
    qdOrigin.v = controlRect.top;
    
    HIViewGetBounds( inData->view, &bounds );
    inData->vPos = inData->buildViewCellHi-2;

    // figure out the spacing
    hInc=bounds.size.width/10; 
    
    rowRect.origin.x = 0; // theHIRect.origin.x;
    rowRect.origin.y= 0; // theHIRect.origin.y ;
    rowRect.size.width = bounds.size.width;
    rowRect.size.height=bounds.size.height; // inData->buildViewCellHi;
    grabRect = rowRect;
    hPos=    inData->hPos; // =        rowRect.origin.x +2;
    vPos=    inData->vPos; //  = inData->buildViewCellHi-2;
    
    hPos = inData->columnRightsCG[kFormNameColRight];
    inData->columnRightsQD[kFormNameColRight]=hPos + controlRect.left; 
    grabRect.origin.x = hPos-4;
    grabRect.size.width = 3;
    inData->dragRectsCG[kFormNameColRight] = grabRect;
    
    CGRectToQDRect(grabRect,&inData->dragRectsQD[kFormNameColRight],&qdOrigin);
    
    hPos = inData->columnRightsCG[kFormTypeColRight];
    inData->columnRightsQD[kFormTypeColRight]=hPos + controlRect.left;
    grabRect.origin.x = hPos-4;
    grabRect.size.width = 3;
    inData->dragRectsCG[kFormTypeColRight] = grabRect;
    CGRectToQDRect(grabRect,&inData->dragRectsQD[kFormTypeColRight],&qdOrigin);
    
    hPos = inData->columnRightsCG[kFormLenColRight];
    
    inData->columnRightsQD[kFormLenColRight]=hPos + controlRect.left;
    grabRect.origin.x = hPos-4;
    grabRect.size.width = 3;
    inData->dragRectsCG[kFormLenColRight] = grabRect;
    CGRectToQDRect(grabRect,&inData->dragRectsQD[kFormLenColRight],&qdOrigin);
    
    
    hPos = inData->columnRightsCG[kFormSignColRight];
    inData->columnRightsQD[kFormSignColRight]=hPos + controlRect.left;
    grabRect.origin.x = hPos-4;
    grabRect.size.width = 3;
    inData->dragRectsCG[kFormSignColRight] = grabRect;
    CGRectToQDRect(grabRect,&inData->dragRectsQD[kFormSignColRight],&qdOrigin);
    
    hPos =inData->columnRightsCG[kFormEndianColRight];
    inData->columnRightsQD[kFormEndianColRight]=hPos + controlRect.left;
    grabRect.origin.x = hPos-4;
    grabRect.size.width = 3;
    inData->dragRectsCG[kFormEndianColRight] = grabRect;
    CGRectToQDRect(grabRect,&inData->dragRectsQD[kFormEndianColRight],&qdOrigin);
    
    
    inData->columnRightsQD[kFormEndColRight]=inData->columnRightsCG[kFormEndColRight]/* rowRect.origin.x+rowRect.size.width */+ controlRect.left;
    
    // do initial mousetracking setup
    {MouseTrackingRegionID inID;
        RgnHandle  inRegion = NewRgn();
        LoopVar qq;
        OSStatus err =0;
        inID.signature = 'PEEK';
        inID.id = 1;
        
        if(inData->trackingRef){
            ReleaseMouseTrackingRegion(inData->trackingRef);
            inData->trackingRef=0;
        }
        
        mPushPort(inData->theWindow);
        OpenRgn();
        for(qq=0;qq<4;qq++){
            FrameRect(&inData->dragRectsQD[qq]);
        }
        CloseRgn(inRegion);
        mPullPort;
        slibMouseTrackerDataBlockPtr theRefCon = calloc(1,sizeof(slibMouseTrackerDataBlock));
        theRefCon->refCon = inData;
        theRefCon->callMe = fbuildmousecallback;
        err = CreateMouseTrackingRegion (inData->theWindow, 
                                         inRegion,
                                         0,
                                         kMouseTrackingOptionsLocalClip,
                                         inID,
                                         theRefCon,
                                         0,
                                         &inData->trackingRef);
    }
    
}


// -----------------------------------------------------------------------------
//	FormatterBuildViewDraw
// -----------------------------------------------------------------------------
//
#pragma mark Drawing
OSStatus FormatterBuildViewDraw(
                                EventRef			inEvent,
                                FormatterBuildViewData*	inData )
{
    OSStatus			err;
    HIRect				bounds;
    CGRect rowRect,ookRect;
    CGRGBColor draggerGrey={0,0,0,.5};
    CGRGBColor fillerG;
    ControlID theID;
    CGrafPtr thePort;
    LoopVar qq;
    UInt16 numRows;
    UInt16 vInc,vPos,hPos,curScrollVal,hInc;
    UInt16 rightPos=0;
    CGContextRef cgRef;
    char buffer[10];
    WCH tempWC = (WCH)GetWRefCon( inData->theWindow);
    FormatWWDataP  nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    // and the parent parent
    UInt32 tempNummer=0;
    UInt32 formatterCount =  CountDataFormattersInThisStructFormatter(nowCD->currentFormatter);
    PIDataFormatterPtr  startHere=0;
    Rect controlRect;
    if(nowCD->currentFormatter){
        startHere=nowCD->currentFormatter->formatters;
    }
    err = GetEventParameter( inEvent, kEventParamCGContextRef, typeCGContextRef,
                             NULL, sizeof( CGContextRef ), NULL, &cgRef );
    
    GetControlBounds(inData->view,&controlRect);
    // an I set the text paramters here?
    CGContextSetRGBFillColor (cgRef, 0, 0, 0, 1); 
    Str255 fontName="\pLucida Grande";
    inData->countInView =0; // none drawn yet
    
    fontName[fontName[0] + 1] = 0;  // make (char*)&fontName[1] a C-string
    CGContextSelectFont(cgRef, (char*)&fontName[1],  gDefaultFontSize, kCGEncodingMacRoman);        
    CGContextSetTextMatrix(cgRef, CGAffineTransformMakeScale(1, -1));
    err = HIViewGetBounds( inData->view, &bounds );
    // figure out the spacing
    hInc=bounds.size.width/10; 
    
    rowRect.origin.x = 0; // theHIRect.origin.x;
    rowRect.origin.y= 0; // theHIRect.origin.y ;
    rowRect.size.width = bounds.size.width;
    rowRect.size.height=inData->buildViewCellHi;
    
    numRows = bounds.size.height/inData->buildViewCellHi;
    curScrollVal = GetControlValue(nowCD->fBuildScroll);
    tempNummer = curScrollVal;
    // move to this one
    while(tempNummer){startHere = startHere->next;tempNummer--;}
    
    hPos=        rowRect.origin.x +2;
    vPos = inData->buildViewCellHi-2;
    
    /**********/
    
    
    {CGRect grabRect = rowRect;
        CGRect clipRect;
        CGContextSelectFont(cgRef, (char*)&fontName[1],  12, kCGEncodingMacRoman);        
        // draw the header
        
#define mClipItBuDraw(A){                     CGContextSaveGState(cgRef);	    clipRect=bounds;    clipRect.size.width = inData->columnRightsCG[A];    CGContextClipToRect (cgRef,clipRect  );                    }
        
        mClipItBuDraw(0);
        CGContextSetRGBFillColor (cgRef, gBlack.red, gBlack.green, gBlack.blue, 1); 
        
        CopyString("\pName   ",gTempString);
        CGContextShowTextAtPoint(cgRef,inData->hPos,inData->vPos,&gTempString[1],gTempString[0]);
        
        CGContextRestoreGState(cgRef);	
        
        mClipItBuDraw(1);
        
        CopyString("\pType   ",gTempString); 
        CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[kFormNameColRight],inData->vPos,&gTempString[1],gTempString[0]);
        CGContextRestoreGState(cgRef);	
        
        mClipItBuDraw(2);
        
        CopyString("\pLength   ",gTempString);
        CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[kFormTypeColRight],inData->vPos,&gTempString[1],gTempString[0]);
        CGContextRestoreGState(cgRef);	
        
        
        mClipItBuDraw(3);
        
        CopyString("\pSign   ",gTempString);
        CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[kFormLenColRight],inData->vPos,&gTempString[1],gTempString[0]);        
        CGContextRestoreGState(cgRef);	
        
        mClipItBuDraw(4);
        
        CopyString("\pEndian   ",gTempString);
        CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[kFormSignColRight],inData->vPos,&gTempString[1],gTempString[0]);
        CGContextRestoreGState(cgRef);	
        
        
        CopyString("\pHex   ",gTempString);
        mClipItBuDraw(5);
        
        CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[kFormEndianColRight],inData->vPos,&gTempString[1],gTempString[0]);
        CGContextRestoreGState(cgRef);	
        
        
        
    } 
    /**********/
    
    hPos=        rowRect.origin.x +2;    
    rowRect.origin.y+=inData->buildViewCellHi;
    vPos+=            inData->buildViewCellHi;
    for(qq=0;qq<numRows-1;qq++){        
        if((curScrollVal + qq)&01){						
            PaintCGRectWithCGRGBColorPtr(cgRef,rowRect,&gTheColors[kRightColColor]);            
        } else {
            PaintCGRectWithCGRGBColorPtr(cgRef,rowRect,&gTheColors[kLeftColColor]);
        }
        
        if(nowCD->buildSelected == qq+ GetControlValue(nowCD->fBuildScroll)){
            gCGSelectionRangeColor.alpha=.3;            
            PaintCGRectWithCGRGBColorPtr(cgRef,rowRect,&gCGSelectionRangeColor);            
        }
        
        // now each row.  
        
        if(startHere)		{
            char bytes[200];
            CFIndex used;
            
            CGRect clipRect=bounds;
            inData->countInView++;
            if(nowCD->buildSelected != qq || (nowCD->buildSelected == qq && inData->editColumnActive != 0  ) ){            
                CGContextSaveGState(cgRef);			
                CGContextSetRGBFillColor (cgRef, gBlack.red, gBlack.green, gBlack.blue, 1); 
                // clip to the column
                // name
                clipRect=bounds;
                clipRect.size.width = inData->columnRightsCG[0];
                CGContextClipToRect (cgRef,clipRect  );
                CFStringGetBytes(startHere->title, CFRangeMake(0,CFStringGetLength(startHere->title)), kCFStringEncodingASCII,0, false, &bytes,50, &used);
                CGContextShowTextAtPoint(cgRef,hPos,vPos,&bytes,used);
                CGContextRestoreGState(cgRef);
            }
            // type
            if(nowCD->buildSelected != qq || (nowCD->buildSelected == qq && inData->editColumnActive != 1)){
                CGContextSaveGState(cgRef);
                clipRect.origin.x = inData->columnRightsCG[0];
                clipRect.size.width = inData->columnRightsCG[1]-inData->columnRightsCG[0];
                CGContextClipToRect (cgRef,clipRect  );
                CGContextSetRGBFillColor (cgRef, gBlack.red, gBlack.green, gBlack.blue, 1); 			
                // OK, we'll cheat and pull the text from the menu
                // whooo boy is that a bad idea for the embedded formatters.
                if(startHere->dataType  > -1 && startHere->dataType  < (sizeof(FormatterDataStandardLengths)/sizeof(SInt32))) {            CFStringRef theS;
                    MenuRef theMenu =      GetControlPopupMenuHandle(nowCD->typePU);
                    
                    CopyMenuItemTextAsCFString(
                                               theMenu,
                                               startHere->dataType+1,
                                               &theS);
                    CFStringGetBytes(theS, CFRangeMake(0,CFStringGetLength(theS)), kCFStringEncodingASCII,0, false, &bytes,50, &used);
                    CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[0]+2,vPos,&bytes,used);
                    CFRelease(theS);
                } else {
                    // pull the name from the formatter
                    CFStringGetBytes(startHere->embeddedFormatter->title, CFRangeMake(0,CFStringGetLength(startHere->embeddedFormatter->title)), kCFStringEncodingASCII,0, false, &bytes,50, &used);
                    CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[0]+2,vPos,&bytes,used);
                    
                }
                CGContextRestoreGState(cgRef);
            }
            // length
            if(nowCD->buildSelected != qq || (nowCD->buildSelected == qq && inData->editColumnActive != 2)){
                CGContextSaveGState(cgRef);
                clipRect.origin.x = inData->columnRightsCG[1];
                clipRect.size.width = inData->columnRightsCG[2]-inData->columnRightsCG[1];
                CGContextClipToRect (cgRef,clipRect  );
                CGContextSetRGBFillColor (cgRef, gBlack.red, gBlack.green, gBlack.blue, 2); 			
                if(startHere->length >0){
                    NumToString(startHere->length,gTempString);
                } else {
                    if(startHere->length == -1){
                    CopyString("\pPreDefined",gTempString);
                    } else {
                    // get the lengith
                        if(startHere->embeddedFormatter){
                            UInt32 totalFormatterStructLength = GetFormatterStructDataCount(startHere->embeddedFormatter);
   NumToString(totalFormatterStructLength,gTempString);
                        } else {
                            CopyString("\pBad len",gTempString);

                        }
                    }
                }
                CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[1]+2,vPos,&gTempString[1],gTempString[0]);			
                CGContextRestoreGState(cgRef);
            }
            // sign
            if(nowCD->buildSelected != qq || (nowCD->buildSelected == qq && inData->editColumnActive != 3) ){
                CGContextSaveGState(cgRef);
                clipRect.origin.x = inData->columnRightsCG[2];
                clipRect.size.width = inData->columnRightsCG[3]-inData->columnRightsCG[2];
                CGContextClipToRect (cgRef,clipRect  );
                CGContextSetRGBFillColor (cgRef, gBlack.red, gBlack.green, gBlack.blue, 2); 			
                if(startHere->flags & kPIDataFormatterSigned){
                    CopyString("\pyes",gTempString);
                }            else{
                    CopyString("\pno",gTempString);
                }
                CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[2]+2,vPos,&gTempString[1],gTempString[0]);			
                CGContextRestoreGState(cgRef);
            }
            // Endian
            if(nowCD->buildSelected != qq || (nowCD->buildSelected == qq && inData->editColumnActive != 4)){
                CGContextSaveGState(cgRef);
                clipRect.origin.x = inData->columnRightsCG[3];
                clipRect.size.width = inData->columnRightsCG[4]-inData->columnRightsCG[3];
                CGContextClipToRect (cgRef,clipRect  );
                CGContextSetRGBFillColor (cgRef, gBlack.red, gBlack.green, gBlack.blue, 2); 			
                if(startHere->flags & kPIDataFormatterLittleEndian){
                    CopyString("\plittle",gTempString);
                }                else{
                    CopyString("\pbig",gTempString);
                }
                
                CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[3]+2,vPos,&gTempString[1],gTempString[0]);			
                
                CGContextRestoreGState(cgRef);
            }
            // Hex
            if(nowCD->buildSelected != qq || (nowCD->buildSelected == qq && inData->editColumnActive != 5)){
                CGContextSaveGState(cgRef);
                clipRect.origin.x = inData->columnRightsCG[4];
                clipRect.size.width = inData->columnRightsCG[5]-inData->columnRightsCG[4];
                CGContextClipToRect (cgRef,clipRect  );
                CGContextSetRGBFillColor (cgRef, gBlack.red, gBlack.green, gBlack.blue, 2); 			
                if(startHere->flags & kPIDataFormatterDisplayHex){
                    CopyString("\pyes",gTempString);
                }            else{
                    CopyString("\pno",gTempString);
                }
                CGContextShowTextAtPoint(cgRef,inData->columnRightsCG[4]+2,vPos,&gTempString[1],gTempString[0]);			
                
                CGContextRestoreGState(cgRef);
            }
            
            startHere = startHere->next;
        }
        
        rowRect.origin.y+=inData->buildViewCellHi;
        vPos+=            inData->buildViewCellHi;
    }
    // finish off
    {CGRect iff;
        LoopVar qq;
        mRectToCGRect( controlRect,iff);
        iff.origin.x = 0;
        iff.origin.y = 0;
        FrameCGRectWithRGBColorPtr(cgRef,1,iff,&draggerGrey);
        CGContextSetRGBStrokeColor(cgRef,draggerGrey.red, draggerGrey.green, draggerGrey.blue, draggerGrey.alpha); 	
        // walk through the grabbers and drop a line
        for(qq=0;qq<5;qq++){
            CGContextBeginPath(cgRef);
            CGContextMoveToPoint(cgRef,inData->dragRectsCG[qq].origin.x+1,inData->dragRectsCG[qq].origin.y/* +inData->dragRectsCG[qq].size.height*/);
            CGContextAddLineToPoint(cgRef, inData->dragRectsCG[qq].origin.x+1, iff.origin.y +iff.size.height);
            CGContextStrokePath(cgRef);
            
        }
    }
    return err;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewHitTest
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewHitTest(
                                   EventRef			inEvent,
                                   FormatterBuildViewData*	inData )
{
    OSStatus			err=0;
    HIRect				bounds;
    HIPoint				where;
    ControlPartCode		part;
    
    
    err = GetEventParameter( inEvent, kEventParamMouseLocation, typeHIPoint,
                             NULL, sizeof( HIPoint ), NULL, &where );
    require_noerr( err, ParameterMissing );
    
    err = HIViewGetBounds( inData->view, &bounds );
    
    part = FormatterBuildViewFindPart( &bounds, &where, inData );
    
    err = SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
                             sizeof( ControlPartCode ), &part ); 
    
    
    
    
ParameterMissing:
        return err;
}
// selected is not valid at this point.
// editcolumn is valid
// activeFormatter is valid
// we exit with all controls turned off and editColumnActive set to -1
void BuildViewHarvestCurrentParam(FormatterBuildViewData*	inData,FormatWWDataP nowCD)
{ PIDataFormatterPtr theFormatter=inData->activeFormatter;
    nowCD->currentFormatter->flags |=            kPIStructChanged;
    
    switch(inData->  editColumnActive){
        case            kFBNameCol:
        {            slibTextBlockPtr theText = slibGetTextFromEditControl(nowCD->buildFloatingEdit);
            
            theFormatter-> title = theText->theString;
            CFRetain(     theFormatter-> title);
            slibDisposeTextBlock(theText);
            SetControlVisibility(nowCD->buildFloatingEdit,false,true);
            SetThemeCursor(kThemeArrowCursor);
        }
            
            break;
        case            kFBTypeCol:
        { 
            MenuRef theMenu=  GetControlPopupMenuHandle(nowCD-> typePU);
            UInt16 type = GetControlValue(nowCD-> typePU);
            theFormatter->dataType=type-1;
            // if this is greater than standard + divider, then pull the unique id
            // byte count matrix
            if(type <=  (sizeof(FormatterDataStandardLengths)/sizeof(SInt32))){
                theFormatter->length = FormatterDataStandardLengths[type-1];
            } else {
                 theFormatter->dataType  = -2;
                theFormatter->length =-2; // or something
                                          // and we need to pull the unique ID and put it where it belongs
                GetMenuItemProperty(
                                    theMenu,
                                    type,
                                    'PEEK',
                                    'UNID',
                                    sizeof(UInt32),
                                    0,
                                    &theFormatter->embeddedFormatterUniqueID) ;
                // now find this one and add it to the thingie
                theFormatter->embeddedFormatter = GetPIStructFormatterByID(theFormatter->embeddedFormatterUniqueID);
                
                
                
                
            }
            SetControlVisibility(nowCD-> typePU,false,true);
        }  
            break;
        case kFBLenCol:
            // populate as necessary
        {  slibTextBlockPtr theText = slibGetTextFromEditControl(nowCD->buildFloatingEdit);
            theFormatter->length=TextEditNumValUnsigned32(nowCD->buildFloatingEdit);
            SetControlVisibility(nowCD->buildFloatingEdit,false,true);
            
            // set the title
            
        }  
            break;
        case            kFBSignCol:
        {ControlRef                theRef =                 SnatchCRef(inData->theWindow,'FORM',kFormatSignedCB);
            UInt16 sign = GetControlValue(theRef);
            if(sign){
                theFormatter->flags |=                kPIDataFormatterSigned;
                
            } else {
                theFormatter->flags &= ~ kPIDataFormatterSigned;
                
            }
            
            SetControlVisibility(theRef,false,true);
        }
            break;
        case            kFBEndianCol:
        {ControlRef                theRef =                 SnatchCRef(inData->theWindow,'FORM',kFormatLilEndianCB);
            UInt16 endian = GetControlValue(theRef);
            SetControlVisibility(theRef,false,true);
            if(endian){
                theFormatter->flags |=                kPIDataFormatterLittleEndian;
                
            } else {
                theFormatter->flags &= ~ kPIDataFormatterLittleEndian;
                
                
            }
            
            
        }
            
            break;
        case kFBHexCol:
        {ControlRef                theRef =                 SnatchCRef(inData->theWindow,'FORM',kFormatLilEndianCB+1);
            UInt16 hexian = GetControlValue(theRef);
            if(hexian){
                
                theFormatter->flags |=                kPIDataFormatterDisplayHex;
                
            } else {
                theFormatter->flags &= ~ kPIDataFormatterDisplayHex;
                
                
            }
            
            SetControlVisibility(theRef,false,true);
            
        }
            
            break;
    }
    inData->  editColumnActive=-1;
    
    
}
void SetStandardDataTypesInMenu(MenuRef theMenu, FormatterBuildViewData*	inData)
{
    inData->numOfStandardMenuItems = 0;
    DeleteMenuItems(theMenu, 1, CountMenuItems(theMenu));
    AppendMenuItemTextWithCFString( theMenu, CFSTR("Byte"), 0, 0, NULL );
    inData->numOfStandardMenuItems++;
    AppendMenuItemTextWithCFString( theMenu, CFSTR("Word"), 0, 0, NULL );
    inData->numOfStandardMenuItems++;
    
    AppendMenuItemTextWithCFString( theMenu, CFSTR("Long"), 0, 0, NULL );
    inData->numOfStandardMenuItems++;
    
    AppendMenuItemTextWithCFString( theMenu, CFSTR("Byte String"), 0, 0, NULL );
    inData->numOfStandardMenuItems++;
    
    AppendMenuItemTextWithCFString( theMenu, CFSTR("C String"), 0, 0, NULL );
    inData->numOfStandardMenuItems++;
    
    AppendMenuItemTextWithCFString( theMenu, CFSTR("Pascal String"), 0, 0, NULL );
    inData->numOfStandardMenuItems++;
    AppendMenuItemTextWithCFString( theMenu, CFSTR("Padding bytes"), 0, 0, NULL );
    inData->numOfStandardMenuItems++;

    
    AppendMenuItemTextWithCFString( theMenu, NULL, kMenuItemAttrSeparator,
                                    0, NULL );
    
    inData->numOfStandardMenuItems++;
    
}


// -----------------------------------------------------------------------------
//	FormatterBuildViewTrack
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewTrack(
                                 EventRef			inEvent,
                                 FormatterBuildViewData*	inData )
{	ControlID theID;
    RgnHandle r1;
    OSStatus			err;
    ControlPartCode		part;
    Point				qdPt;
    MouseTrackingResult	mouseResult;
    UInt16 height,tempCounter;
    CGrafPtr thePorter;
    WCH tempWC;
    Rect controlBounds,newControl;
    FormatWWDataP nowCD;
    WindowRef theWindow = inData->theWindow;
    Rect tempRect;
    LoopVar qq,ww;
    UInt32 clickCount;
    UInt16 oldSelected =0;
    UInt16 rowsInView=0;
    PIDataFormatterPtr  startHere=0;
    SInt16 newColumnClicked =-1;
    Boolean trackedColumnRider = false;
    
    tempWC = (WCH)GetWRefCon(theWindow);
    nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    
    theWindow=GetControlOwner(inData->view);
    thePorter = GetWindowPort(theWindow);
    GetControlBounds(inData->view,&controlBounds);
    
    height =   inData->buildViewCellHi;
    mPushPort(theWindow);
    GetMouse(&qdPt);
    mPullPort;
    // if they are in a drag bar just go and deal with that
    
    for(ww=0;ww<6;ww++){
        
        if(PtInRect(qdPt,&inData->dragRectsQD[ww])){
            //            SetThemeCursor(kThemeResizeLeftRightCursor);
            // it is, track and go
            do{
                UInt16 dragMin,dragMax;
                
                err = TrackMouseLocation(thePorter, &qdPt, &mouseResult );
                switch(mouseResult){
                    case kMouseTrackingMouseDragged:
                    {
                        // the ww'th
                        // keep it from crashing into things
                        if(ww >0){
                            dragMin = inData->columnRightsQD[ww-1]+10;
                        } else {
                            dragMin = controlBounds.left+20;
                        }
                        if(ww < 5){
                            dragMax = inData->columnRightsQD[ww+1]-20;
                        } else {
                            dragMax = controlBounds.right -20;
                        }
                        
                        if(qdPt.h > dragMin && qdPt.h < dragMax){
                            inData->columnRightsCG[ww]= qdPt.h - controlBounds.left;
                            CalculateBuildAreaRects(  	inData,   nowCD );
                            FormatterBuildViewBoundsChanged(0,inData);
                            HIViewSetNeedsDisplay( inData->view, true );
                            
                        }
                        
                    }
                        break;
                }                    
            }while( mouseResult != kMouseTrackingMouseUp);
            SetThemeCursor(kThemeArrowCursor);
            trackedColumnRider = true;
            
        }
    }
    if(trackedColumnRider == false){
        
        oldSelected =  nowCD->buildSelected;
        rowsInView=((qdPt.v-controlBounds.top)/height);
        nowCD->buildSelected = (((qdPt.v-controlBounds.top)/height)+GetControlValue(nowCD->fBuildScroll))-1;
        // change active formatter
        
        if((nowCD->buildSelected -GetControlValue(nowCD->fBuildScroll)) < inData->countInView){
            
            // if the columns are both -1 then this will trigger, but I don't think that matters
            if(nowCD->buildSelected != oldSelected || inData->editColumnActive != newColumnClicked){
                // harvest the currently being edited parameter if there is one
                // fill all this in
                if( inData->editColumnActive >=0) BuildViewHarvestCurrentParam(inData,nowCD);
                // now move the new formatter into the active slot
                tempCounter = nowCD->buildSelected;
                startHere=nowCD->currentFormatter->formatters;
                while(tempCounter){
                    startHere = startHere->next;
                    tempCounter--;
                }
                inData->activeFormatter=startHere;
                
                
                HIViewSetNeedsDisplay( inData->view, true );
                
            }
        } else {
            // they clicked but nothing was there
            // we have to harvest if appropriate
            if( inData->editColumnActive >=0) BuildViewHarvestCurrentParam(inData,nowCD);
            
            nowCD->buildSelected = -1;
            inData->editColumnActive=-1;
            inData->activeFormatter = 0;
            DisableControl( SnatchCRef(theWindow,'FORM', 1003));
            HIViewSetNeedsDisplay( inData->view, true );
            //		HIViewSetNeedsDisplay( nowCD->FormatterBuildView, true );
        }
        
        
        if(inData->clickCount >1 &&  nowCD->buildSelected >=0 && (nowCD->currentFormatter && ((nowCD->currentFormatter->flags & kPIDataFormatterLocked)==0))){
            //double click means they're wantin' to edit this field    
            // figgure out which field this is
            // all data should already have been harvested, yes? Yes.
            // see where we are
            Rect targetRect;
            
            tempCounter = nowCD->buildSelected;
            startHere=nowCD->currentFormatter->formatters;
            while(tempCounter){
                startHere = startHere->next;
                tempCounter--;
            }
            
            
            targetRect.top=   ( (nowCD->buildSelected+1)*inData->buildViewCellHi + controlBounds.top)+2;
            targetRect.bottom= targetRect.top+           inData->buildViewCellHi-2; // about -2
                                                                                    // now see which column it's in
            for(qq=0;qq< kFormEndColRight;qq++){
                if(qdPt.h <inData->columnRightsQD[qq])break;
            }
            if(qq==0){
                targetRect.left = controlBounds.left;
                targetRect.right=inData->columnRightsQD[qq];
                
            }        else{
                targetRect.left     =inData->columnRightsQD[qq-1];
                targetRect.right=inData->columnRightsQD[qq];
            }
            // switch off on which control this is
            inData->editColumnActive = qq;
            switch(qq){
                case            kFBNameCol:
                    targetRect.right -=6;
                    SetControlBounds(nowCD->buildFloatingEdit,&targetRect);
                    ShowControl(nowCD->buildFloatingEdit);
                    SetControlData(
                                   nowCD->buildFloatingEdit,
                                   0,
                                   kControlEditTextCFStringTag,
                                   sizeof(CFStringRef),
                                   &startHere->title);
                    SetKeyboardFocus(
                                     inData->theWindow,
                                     nowCD->buildFloatingEdit,
                                     kControlFocusNoPart);
                    SetKeyboardFocus(
                                     inData->theWindow,
                                     nowCD->buildFloatingEdit,
                                     kControlFocusNextPart);
                    
                    
                    
                    
                    break;
                case            kFBTypeCol:
                    targetRect.right -=6;
                    
                    SetControlBounds(nowCD-> typePU,&targetRect);
                    {MenuRef theMenu=  GetControlPopupMenuHandle(nowCD-> typePU);
                        
                        // we have the standards, then the formatters
                        SetStandardDataTypesInMenu(theMenu,inData);
                        AddFormattersToMenu( theMenu,kFormatterMenuFilledOny,nowCD->currentFormatter->uniqueID);
                        SetControlMaximum(  nowCD-> typePU,                  CountMenuItems(theMenu));
                        ShowControl( nowCD-> typePU);
                    }
                        
                        SetControlValue(nowCD-> typePU,startHere->dataType+1);
                    HIViewSetZOrder(
                                    nowCD-> typePU,
                                    kHIViewZOrderAbove,
                                    0) ;
                    
                    break;
                case kFBLenCol:
                    // populate as necessary
                    // if the length is negative, then this is a non-editable length, it's defined by type (like a pstring)
                    if(startHere->length >0)            {
                        SetControlBounds(nowCD->buildFloatingEdit,&targetRect);
                        UnsignedIntToTextEdit(nowCD->buildFloatingEdit,startHere->length);
                        ShowControl(nowCD->buildFloatingEdit);
                    } else {
                        
                        // maybe someday we'd want to do something here
                        // we do today, actually
                        inData->editColumnActive = -1;
                    }
                    break;
                case            kFBSignCol:
                {ControlRef                theRef =                 SnatchCRef(theWindow,'FORM',kFormatSignedCB);
                    SetControlBounds(theRef,&targetRect);
                    
                    ShowControl(theRef);
                    SetControlValue(theRef,startHere->flags & kPIDataFormatterSigned);
                    HIViewSetZOrder(
                                    theRef,
                                    kHIViewZOrderAbove,
                                    0) ;
                } 
                    break;
                case            kFBEndianCol:
                {ControlRef                theRef =                 SnatchCRef(theWindow,'FORM',kFormatLilEndianCB);
                    SetControlBounds(theRef,&targetRect);
                    ShowControl(theRef);
                    SetControlValue(theRef,startHere->flags & kPIDataFormatterLittleEndian);
                    
                    HIViewSetZOrder(
                                    theRef,
                                    kHIViewZOrderAbove,
                                    0) ;
                    
                }
                    
                    break;
                    
                case            kFBHexCol:
                {ControlRef                theRef =                 SnatchCRef(theWindow,'FORM',kFormatLilEndianCB+1);
                    SetControlBounds(theRef,&targetRect);
                    ShowControl(theRef);
                    SetControlValue(theRef,startHere->flags & kPIDataFormatterDisplayHex);
                    
                    HIViewSetZOrder(
                                    theRef,
                                    kHIViewZOrderAbove,
                                    0) ;
                    
                }
                    
                    break;
                    
            }
            
            
        } else    {
            do{
                
                
                err = TrackMouseLocation(thePorter, &qdPt, &mouseResult );
                // kMouseTrackingMouseMoved later
                switch(mouseResult){
                    case kMouseTrackingMouseDragged:
                    {
                        
                        
                        oldSelected =  nowCD->buildSelected ;
                        rowsInView=((qdPt.v-controlBounds.top)/height);
                        
                        nowCD->buildSelected = rowsInView+GetControlValue(nowCD->fBuildScroll)-1;
                        // change active formatter
                        if(nowCD->currentFormatter && (nowCD->currentFormatter->flags & kPIDataFormatterLocked) == 0)
                            EnableControl( SnatchCRef(theWindow,'FORM', 1003));
                        
                        if((nowCD->buildSelected -GetControlValue(nowCD->fBuildScroll)) < inData->countInView){
                            if(nowCD->buildSelected != oldSelected){
                                HIViewSetNeedsDisplay( inData->view, true );
                                
                            }
                        } else {
                            // they clicked, but there is nothing there
                            nowCD->buildSelected = -1;
                            inData->editColumnActive=-1;
                            inData->activeFormatter = 0;
                            
                            DisableControl( SnatchCRef(theWindow,'FORM', 1003));
                            
                            HIViewSetNeedsDisplay( inData->view, true );
                            
                        }
                        
                        
                        
                    }
                        break;        
                        
                        
                }
            }while( mouseResult != kMouseTrackingMouseUp);
            
        }
        if(nowCD->buildSelected>=0  && (nowCD->currentFormatter && ((nowCD->currentFormatter->flags & kPIDataFormatterLocked)==0)))
            EnableControl( SnatchCRef(theWindow,'FORM', 1003));
        
    }
    err = SetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
                             sizeof( ControlPartCode ), &part ); 
    
    return err;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewChanged
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewChanged(
                                   EventRef			inEvent,
                                   FormatterBuildViewData*	inData )
{
#pragma unused( inEvent )
    OSStatus			err = noErr;
    
    HIViewSetNeedsDisplay( inData->view, true );
    
    return err;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewGetData
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewGetData(
                                   EventRef				inEvent,
                                   FormatterBuildViewData*		inData )
{
    OSStatus				err;
    ControlPartCode			part;
    OSType					tag;
    Ptr						ptr;
    Size					size;
    Size					outSize;
    
    err = GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
                             NULL, sizeof( ControlPartCode ), NULL, &part );
    require_noerr( err, ParameterMissing );
    
    err = GetEventParameter( inEvent, kEventParamControlDataTag, typeEnumeration,
                             NULL, sizeof( OSType ), NULL, &tag );
    require_noerr( err, ParameterMissing );
    err = GetEventParameter( inEvent, kEventParamControlDataBuffer, typePtr,
                             NULL, sizeof( Ptr ), NULL, &ptr );
    require_noerr( err, ParameterMissing );
    
    err = GetEventParameter( inEvent, kEventParamControlDataBufferSize, typeLongInteger,
                             NULL, sizeof( Size ), NULL, &size );
    require_noerr( err, ParameterMissing );
    switch(tag){
        case kslibHIVIewElementsInView:
            // tell 'em how many will fit
            
            break;
        case     kslibHIViewCellHeight:
            inData->buildViewCellHi=gDefaultFontSize+4;
            *((long *)ptr) = gDefaultFontSize+4;  // ‚Ä¢‚Ä¢¬†fix 
            break;
        case                kslibHIViewCellWide:
            break;
        case kslibReturnViewRefCon:
            *((long *)ptr) = inData;
            break;
    }
    
    if ( err == noErr )
        err = SetEventParameter( inEvent, kEventParamControlDataBufferSize, typeLongInteger,
                                 sizeof( Size ), &outSize );
    
ParameterMissing:
        return err;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewSetData
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewSetData(
                                   EventRef				inEvent,
                                   FormatterBuildViewData*		inData )
{
    OSStatus				err;
    ControlPartCode			part;
    OSType					tag;
    Ptr						ptr;
    Ptr aLong=0;
    UInt32  yesL=0;
    Size					size;
    WCH tempWC;
    FormatWWDataP nowCD;
    WindowRef theWindow = inData->theWindow;
    tempWC = (WCH)GetWRefCon(theWindow);
    nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    
    err = GetEventParameter( inEvent, kEventParamControlDataTag, typeEnumeration,
                             NULL, sizeof( OSType ), NULL, &tag );
    
    
    
    
    
    
    
    
    if(tag == 'FBCL'){
        
        // this means clear the current control if it's up without saving anything
        if(          inData->editColumnActive>=0){
            
            /*******************/
            switch(inData->  editColumnActive){
                case            kFBNameCol:
                    SetControlVisibility(nowCD->buildFloatingEdit,false,true);
                    
                    break;
                case            kFBTypeCol:
                    SetControlVisibility(nowCD-> typePU,false,true);
                    break;
                case kFBLenCol:
                    SetControlVisibility(nowCD->buildFloatingEdit,false,true);
                    
                    break;
                case            kFBSignCol:
                {ControlRef                theRef =                 SnatchCRef(inData->theWindow,'FORM',kFormatSignedCB);
                    SetControlVisibility(theRef,false,true);
                }
                    break;
                case            kFBEndianCol:
                {ControlRef                theRef =                 SnatchCRef(inData->theWindow,'FORM',kFormatLilEndianCB);
                    SetControlVisibility(theRef,false,true);
                    
                    
                }
                    
                    break;
                case kFBHexCol:
                {ControlRef                theRef =                 SnatchCRef(inData->theWindow,'FORM',kFormatLilEndianCB+1);
                    
                    SetControlVisibility(theRef,false,true);
                    
                }
                    
                    break;
            }
            
            
            
            /*********************/
            
            
            inData->editColumnActive=-1;
        }
        
    }
    return err;
}

// -----------------------------------------------------------------------------
//	FormatterBuildViewGetRegion
// -----------------------------------------------------------------------------
//
OSStatus FormatterBuildViewGetRegion(
                                     EventRef				inEvent,
                                     FormatterBuildViewData*		inData )
{
    OSStatus				err;
    ControlPartCode			part;
    RgnHandle				outRegion;
    HIRect					bounds;
    Rect					qdBounds;
    
    err = GetEventParameter( inEvent, kEventParamControlPart, typeControlPartCode,
                             NULL, sizeof( ControlPartCode ), NULL, &part );
    require_noerr( err, ParameterMissing );
    
    err = GetEventParameter( inEvent, kEventParamControlRegion, typeQDRgnHandle,
                             NULL, sizeof( RgnHandle ), NULL, &outRegion );
    
    if ( part == kControlContentMetaPart
         || part == kControlStructureMetaPart
         ) //		 || part == kControlOpaqueRegionMetaPart  )
    {
        HIViewGetBounds( inData->view, &bounds );
        qdBounds.top = (SInt16) CGRectGetMinY( bounds );
        qdBounds.left = (SInt16) CGRectGetMinX( bounds );
        qdBounds.bottom = (SInt16) CGRectGetMaxY( bounds );
        qdBounds.right = (SInt16) CGRectGetMaxX( bounds );
        
        RectRgn( outRegion, &qdBounds );
    }
    
ParameterMissing:
        return err;
}

// -----------------------------------------------------------------------------
//	FindPart
// -----------------------------------------------------------------------------
//
ControlPartCode FormatterBuildViewFindPart(
                                           const HIRect*		inBounds,
                                           const HIPoint*		inWhere,
                                           FormatterBuildViewData*	inData )
{
    ControlPartCode		part;
    // don't really have parts.
    // so just say 1
    part = 1;
    
    return part;
}

// if there is a control visible you've got to move it
OSStatus FormatterBuildViewBoundsChanged(
                                         EventRef				inEvent,
                                         FormatterBuildViewData*		inData )
{
    
    Rect targetRect,controlBounds;
    WCH tempWC;
    FormatWWDataP nowCD;
    WindowRef theWindow = inData->theWindow;
    tempWC = (WCH)GetWRefCon(theWindow);
    nowCD = (FormatWWDataP)(*tempWC)->dataStore;
    GetControlBounds(inData->view,&controlBounds);
    
    
    // lets try this here
    if(inEvent != 0){
        if(inData->setRightsFromSave== false){
        SetInitialBuildColumnRights( 	inData,   nowCD ,0);
        } else {
        // first one is free
            inData->setRightsFromSave = false;
        }
        
        CalculateBuildAreaRects(  inData,  nowCD );
    }
    targetRect.top=   ( (nowCD->buildSelected+1)*inData->buildViewCellHi + controlBounds.top)+2;
    targetRect.bottom= targetRect.top+           inData->buildViewCellHi-2; // about -2
    
    
    if(inData->  editColumnActive >=0){
        // see who it is and move it
        if(inData->  editColumnActive==0){
            targetRect.left = controlBounds.left;
            targetRect.right=inData->columnRightsQD[inData->  editColumnActive];
            
        }        else{
            targetRect.left     =inData->columnRightsQD[inData->  editColumnActive-1];
            targetRect.right=inData->columnRightsQD[inData->  editColumnActive];
        }
        
        switch(inData->  editColumnActive){
            case            kFBNameCol:
                SetControlBounds(nowCD->buildFloatingEdit,&targetRect);
                break;
            case            kFBTypeCol:
                SetControlBounds(nowCD-> typePU,&targetRect);
                
                break;
            case kFBLenCol:
                // populate as necessary
                SetControlBounds(nowCD->buildFloatingEdit,&targetRect);
                
                break;
            case            kFBSignCol:
            {ControlRef                theRef =                 SnatchCRef(theWindow,'FORM',kFormatSignedCB);
                SetControlBounds(theRef,&targetRect);
            }
                break;
            case            kFBEndianCol:
            {ControlRef                theRef =                 SnatchCRef(theWindow,'FORM',kFormatLilEndianCB);
                SetControlBounds(theRef,&targetRect);
                
            }
                
                break;
                
                
        }
        
        
    }
}


void SizeFormatterBuildViews(WindowRef theWindow,FormatWWDataP nowCD)
{
    Rect thisRect;
    HIRect   inRect;
    /*     CGPoint origin;
    CGSize size */
    if(nowCD->FormatterBuildView){
        HIViewSetFrame(
                       nowCD->FormatterBuildView,
                       &nowCD->FormatterBuildViewRect);
        HIViewSetNeedsDisplay(  nowCD->FormatterBuildView, true );
        
    }
    
    
}






/*
 *  formatterfile.pi.c
 *  PeekIt
 *
 *  Created by C.K. Haun on 11/26/05.
 *  Copyright 2005 Ravenware Software. All rights reserved.
 *
 */

#include "peekit.h"
extern short gFormatterRefNum;
extern PeekitStructFormatterPtr gFormatters;
extern PeekitStructFormatterPtr gFormattersMarkedForDeletion;
extern PeekitStructFormatterPtr genericMissingFormatter;

void CloseFormattersFile(short refNum)
{
  // see if we changed
    PeekitStructFormatterPtr startHere;
    OSStatus myErr = noErr;
        if(gFormatterRefNum ){
// firts, see if there are anythings to delete
            PeekitStructFormatterPtr startHereDelete =    gFormattersMarkedForDeletion;
            while(startHereDelete){
                
                DeleteMEntry(gFormatterRefNum,startHereDelete->theCriteria);
                startHereDelete=startHereDelete->next;

            
            }
            // walk through the formatters and see if any of them changed
startHere=gFormatters;
            while(startHere){
                if(startHere->flags & kPIStructChanged){
                // save this one
                    GRACPtr theCriteria = startHere->theCriteria;
                    
                    Ptr flatHead =  FlattenFormatter(startHere);

                    
                    myErr= SaveMEntry(gFormatterRefNum,  theCriteria,  flatHead, ((FlatFormatterHeader *)flatHead)->lenFlattened);
// I'ma gonna clear the flag just because
                    startHere->flags &=~kPIStructChanged;
                }
                startHere = startHere->next;
            }

            CloseMFile(gFormatterRefNum);
            gFormatterRefNum=0;
        }
}

OSStatus OpenStandardFormatterFile(void)
{
    OSStatus myErr = noErr;
    FSRef putItHere,fileRef;
    FSSpec dirSpec;
    HFSUniStr255  fileNameU;
    FSSpec fileSpec;
    Str255 name = "\pPeekIt Formatters.piform";
    Str255 name2 = "\pPeekIt Formatters.piform";
    
    CFStringRef theFileName;
    
    genericMissingFormatter = (    PeekitStructFormatterPtr)calloc(1,sizeof(    PeekitStructFormatter));
genericMissingFormatter->version = 1;
 genericMissingFormatter->uniqueID = 0;
 genericMissingFormatter->title = CFSTR("MISSING FORMATTER");
 genericMissingFormatter->description = CFSTR("MISSING FORMATTER");
 
    gFormatterRefNum=0;
    myErr =  GetRavenwareFolder(&putItHere);
    // until I move the mapped calls to fsrefs I'll do this
    FSGetCatalogInfo(
                     &  putItHere,
                     kFSCatInfoNone,
                     0,       /* can be NULL */ 
                     0,           /* can be NULL */
                     &dirSpec,            /* can be NULL */
                     0);
    theFileName=     CFStringCreateWithPascalString(0,name, 0);
    
    fileNameU.length = (UInt16) CFStringGetLength(theFileName);
    CFStringGetCharacters(theFileName, CFRangeMake(0, fileNameU.length), fileNameU.unicode);
    
    myErr = FSMakeFSRefUnicode(&putItHere, fileNameU.length, fileNameU.unicode, kTextEncodingUnknown, &fileRef);
    // dang it, have to pull the fsspec outta this
    if(myErr == noErr){
        myErr =        FSRefMakeFSSpec(&fileRef,&fileSpec);
    }
    if(myErr == -43){
        // try the same thing with the old name before creating new
        theFileName=     CFStringCreateWithPascalString(0,name2, 0);        
        fileNameU.length = (UInt16) CFStringGetLength(theFileName);
        CFStringGetCharacters(theFileName, CFRangeMake(0, fileNameU.length), fileNameU.unicode);        
        myErr = FSMakeFSRefUnicode(&putItHere, fileNameU.length, fileNameU.unicode, kTextEncodingUnknown, &fileRef);
        
        
        
        if(myErr == -43){
            
            myErr = FSCreateFileUnicode(
                                        &putItHere,
                                        fileNameU.length,
                                        fileNameU.unicode,
                                        0,
                                        0,       /* can be NULL */
                                        0,            /* can be NULL */
                                        &fileSpec);           /* can be NULL */ 
                                        if(myErr == noErr){
                                            InitMFile(&fileSpec);
                                        }
                                        
        }
    }


if(myErr == noErr){
    // open the file finally
    myErr = OpenMFile(&fileSpec,fsRdWrPerm, &gFormatterRefNum);
    if(myErr == noErr){
        UInt32 numFFMs=0;
        PeekitStructFormatterPtr startHere;
        // actually, don't do shit I guess
        // well wait, we can at least, oh nevermind
        //mFillCompare(gTempCompare, 'BMHD',1, 0, 0);
        // ok, yes I do want to do something.  Load the headers
        numFFMs=        CountMEntries(gFormatterRefNum,kPIFlatFormatter);
        if(numFFMs){
            ULong counter=0;
            // load all the headers in
            do{
                GRACPtr returnedCriteria= calloc(1,sizeof(GRACompare));
                Handle theFFM;
                PeekitStructFormatterPtr theFormatter;
                theFFM =  ReadIndexedMEntry(gFormatterRefNum,counter,kPIFlatFormatter,returnedCriteria);
                // now make it a pointer and copy it
                
                theFormatter = ExpandFlatFormatter(*theFFM);
                DisposeHandle((Handle)theFFM);
                // add the gracompare
                theFormatter->theCriteria=returnedCriteria;
                if(gFormatters == 0){
                    gFormatters=theFormatter;
                } else {
                    // go to the end and tack this one on
                    startHere = gFormatters;
                    while(startHere->next)startHere = startHere->next;
                    startHere->next = theFormatter;
                    theFormatter->previous = startHere;
                    
                }
                
                
                numFFMs--;
                counter++;
            } while(numFFMs);
            // now we have to go back through and embed any embedded formatters, and flag the missing one(s)
              startHere = gFormatters;
              while(startHere){
              PIDataFormatterPtr theFormatters = 0;
                  //
                  theFormatters = startHere->formatters;
                  while(theFormatters){
                      if(theFormatters->dataType == -2){
                      // find it
                          
                          theFormatters->embeddedFormatter= GetPIStructFormatterByID(theFormatters->embeddedFormatterUniqueID);
                          if(theFormatters->embeddedFormatter == 0){
                          // use the standard one
                          theFormatters->embeddedFormatter=    genericMissingFormatter;
                          }
                      }
                      theFormatters=theFormatters->next;
                  }
                  
                  startHere= startHere->next;
              }
        }
        
    }
}
}

FileTrackerPtr GetAndValidateFormatterFile(FileTrackerPtr theFile)
{FileTrackerPtr theFT = theFile;
    OSStatus myErr = 0;
    if(theFT == 0){
    // get a file
        myErr= SimpleGetFileII(&theFT,"\pSelect a Formatter Definition file","\pOpen Formatter File",0,0,0);
        if(myErr==noErr){
            
        } else {
        theFT = 0; // just to be certain
            
        }
    }
    if(theFT != 0){
    // got one.  Look for marks
        theFT->openResFork=false;
        theFT->openDataFork = true;
        myErr =     OpenFile(theFT);
        if(myErr == noErr){
            Boolean isValid = true;
            long theCount;
            char matcher[] = "<PeekIt Formatter File>";
            LoopVar qq;
            Ptr scratchPtr = malloc(100);
            theCount=sizeof(long);
            theCount = 23;
            FSRead(        theFT->dataForkRef,           &theCount,                   scratchPtr);
            // see if it matches
//            <PeekIt Formatter File>
            for(qq=0;qq<23;qq++){
                if(*(scratchPtr + qq) != matcher[qq]){isValid = false;break;}
            }
            CloseFile(theFT);
            if(isValid == false){
                DisposeFileTracker(theFT);
                theFT= 0;
            }
            
        }
    }
    
    return(theFT);
}

UInt32 CountDataFormattersInThisStructFormatter(PeekitStructFormatterPtr theStructFormatter)
{UInt32 count = 0;
    if(theStructFormatter){
    PIDataFormatterPtr theFormatter = theStructFormatter->formatters;
        while(theFormatter){
            count++;
            theFormatter=theFormatter->next;
        }}
        return(count);
}
// the amount of data needed to fill this formatter
UInt32 GetFormatterStructDataCount(PeekitStructFormatterPtr theStructFormatter)
{UInt32 returnVal = 0;
    PIDataFormatterPtr theFormatter = theStructFormatter->formatters;
    if(theFormatter){
    while(theFormatter){
        // since I'm using length as a flag sometimes, I'll have to check that.
        //note that nothing prevents a embed>embed>embed so this could recurse
        // its a formatter with a Difference
            // a predefined
            switch(theFormatter->dataType){
            // I'm just going to slam these with 255s
case -1:
                returnVal+=255;
    break;
            
            // a formatter
            case -2:
                returnVal+=GetFormatterStructDataCount(theFormatter->embeddedFormatter);
                break;
            case kFormatterValPString:
                returnVal+=255;
                break;
            case kFormatterValCString:
                returnVal+=1024;  // or less, we'll see

                break;
            default:
                     returnVal+=theFormatter->length;
                break;
        }
            
        theFormatter=theFormatter->next;
    }
    }
    return(returnVal);
}
UInt32 CountAllStructureFormatters(void)
{UInt32 count = 0;
        PeekitStructFormatterPtr startHere=gFormatters;
        while(startHere){
            count++;
            startHere = startHere->next;
        }
        return(count);
    
}
void AddUniqueIDToThisStructFormatter(PeekitStructFormatterPtr newOne)
{    PeekitStructFormatterPtr startHere = gFormatters;

    do{
        Boolean uni = true;
    UInt32 theTry = Choose(0xFFFF);
        theTry=    theTry<<16;
        theTry = theTry | Choose(0xFFFF);
    // see if it's unique
        startHere = gFormatters;
        uni = true;
        while(startHere){
            if(startHere->uniqueID == theTry){
                uni= false;break;
            }else{
                startHere = startHere->next;
            }
        }
        if(uni){
            newOne->uniqueID = theTry;
            break;
        }
    }while(true);
    }

PeekitStructFormatterPtr GetPIStructFormatterByID(UInt32 theID)
{PeekitStructFormatterPtr retVal = 0;
    PeekitStructFormatterPtr startHere = gFormatters;
    while(startHere){
        if(startHere->uniqueID == theID){
            retVal = startHere;
            break;
        } else {
            startHere=startHere->next;
        }
    }
    return(retVal);
}
// ids cannot be 0 or ffffffff
// go through every struct formatter and look at each data formatter inside it
void AddUniqueIDToThisDataFormatter(PIDataFormatterPtr newOne)
{
    PeekitStructFormatterPtr startHere = gFormatters;
    PIDataFormatterPtr theDataFormatter;
    do{
        Boolean uni = true;
        UInt32 theTry = Choose(0xFFFF);
        theTry=    theTry<<16;
        theTry = theTry | Choose(0xFFFF);
        if(theTry != 0 && theTry !=0xffffffff){
        // see if it's unique
        startHere = gFormatters;
        uni = true;
        while(startHere){
            // now each formatter
            theDataFormatter = startHere->formatters;
            while(theDataFormatter){
                if(theDataFormatter->uniqueID == theTry){
                   uni= false;break;
                } else {
                    theDataFormatter = theDataFormatter->next;
                }
            }
            startHere = startHere->next;
            if(uni == false)break;
        }
        if(uni){
            newOne->uniqueID = theTry;
            break;
        }
    }
    }while(true);
    
}


// returns the number of formatters added
UInt16 AddFormattersToMenu(MenuRef theMenu,UInt16 flags,UInt32 thisFormatterUniqe)
{UInt16 itemCount=1;
    PeekitStructFormatterPtr startHere = gFormatters;
    
    if(flags &           kFormatterMenuClear)
    { DeleteMenuItems(theMenu, 1, CountMenuItems(theMenu));
    } else {
itemCount = CountMenuItems(theMenu);
        itemCount++; // dont ask
    }
    while(startHere){
        //(flags &     kFormatterMenuFilledOny==0) || ((flags &     kFormatterMenuFilledOny) &&
        if( (startHere->formatters)){
        AppendMenuItemTextWithCFString( theMenu, startHere->title, 0,
                                        0, NULL );
        // I'm going to add the unique ID to this one too
        SetMenuItemProperty(
                            theMenu,
                            itemCount,
                            'PEEK',
                            'UNID',
                            sizeof(UInt32),
                            &startHere->uniqueID) ;
        if(thisFormatterUniqe == startHere->uniqueID)DisableMenuItem(theMenu,itemCount);

        itemCount++;        
        }
        startHere=startHere->next;
    }
    return(itemCount);
}

// this has got to dive deep
Boolean innerCheckEmbeddedFormatter(PeekitStructFormatterPtr theDataFormatter,UInt32 uniqueID)
{Boolean retVal =false;

    
    return(retVal);
}
Boolean innerIsEmbedded(      PIDataFormatterPtr theDataFormatter, UInt32 uniqueID)
{Boolean retVal=false;
    while(theDataFormatter){
        if(theDataFormatter->embeddedFormatterUniqueID == uniqueID){
            retVal = true;
            goto innerexit;
        } else {
    PeekitStructFormatterPtr startxxHere = theDataFormatter->embeddedFormatter;    
            if(startxxHere){
            PIDataFormatterPtr rest = startxxHere->formatters;

            if(innerIsEmbedded(rest,uniqueID)){
                retVal = true;
                goto innerexit;
            }
        }
        }
        theDataFormatter =theDataFormatter->next;
    }
innerexit:
        return(retVal);
}

Boolean IsThisFormatterEmbedded(UInt32 uniqueID)
{
    PeekitStructFormatterPtr startHere = gFormatters;
      PIDataFormatterPtr theDataFormatter;
    Boolean retVal=false;
    while(startHere){
    
        if(startHere->uniqueID != uniqueID){
            theDataFormatter = startHere->formatters;
            if(innerIsEmbedded(theDataFormatter,uniqueID)){
                retVal = true;
                goto exit;
    }
        
        
        }
        
        startHere=startHere->next;
    }
exit:
    return(retVal);
}

