//
//  Globals.m
//  CamelBones
//
//  Copyright (c) 2002 Sherm Pendley. All rights reserved.
//

#import "Globals.h"
#import "Wrappers.h"
#import "Conversions.h"
#import "PerlImports.h"
#import "CBPerlArray.h"
#import "mach-o/dyld.h"

void CBWrapAllGlobals(void) {
    NSBundle *thisBundle;
    NSString *plistPath;

    NSArray *exports;
    NSEnumerator *e;
    NSString *thisExport;

    CBPerlArray *foundationISA;
    CBPerlArray *foundationEXPORT;
    CBPerlArray *appkitISA;
    CBPerlArray *appkitEXPORT;

    // Fill out the Foundation package's ISA and EXPORT arrays
    foundationISA = [CBPerlArray newArrayNamed:@"CamelBones::Foundation::Globals::ISA"];
    [foundationISA addObject:@"Exporter"];
    foundationEXPORT = [CBPerlArray newArrayNamed:@"CamelBones::Foundation::Globals::EXPORT"];

    // Fill out the AppKit package's ISA and EXPORT arrays
    appkitISA = [CBPerlArray newArrayNamed:@"CamelBones::AppKit::Globals::ISA"];
    [appkitISA addObject:@"Exporter"];
    appkitEXPORT = [CBPerlArray newArrayNamed:@"CamelBones::AppKit::Globals::EXPORT"];

    // Get a handle on the CamelBones framework bundle
    thisBundle = [NSBundle bundleForClass:NSClassFromString(@"CBPerl")];

    // Get the Foundation exports plist and loop over the entries
    plistPath = [thisBundle pathForResource:@"FoundationGlobalStrings" ofType:@"plist"];
    exports = [NSArray arrayWithContentsOfFile:plistPath];
    e = [exports objectEnumerator];
    while ((thisExport = [e nextObject])) {
        // Try to make a wrapper
        if (CBWrapString([thisExport UTF8String], "CamelBones::Foundation::Globals")) {
            // If successful, make the wrapper exportable
            [foundationEXPORT addObject:[thisExport substringFromIndex:1]];
        }
    }

    // Get the AppKit exports plist and loop over the entries
    plistPath = [thisBundle pathForResource:@"AppKitGlobalStrings" ofType:@"plist"];
    exports = [NSArray arrayWithContentsOfFile:plistPath];
    e = [exports objectEnumerator];
    while ((thisExport = [e nextObject])) {
        // Try to make a wrapper
        if (CBWrapString([thisExport UTF8String], "CamelBones::AppKit::Globals")) {
            // If successful, make the wrapper exportable
            [appkitEXPORT addObject:[thisExport substringFromIndex:1]];
        }
    }
}

BOOL CBWrapString(const char *varName, const char *pkgName) {
    // Define a Perl context
    dTHX;

    NSSymbol theSymbol;
    void *address;
    SV *mySV;
    
    // First see if the requested symbol exists
    if (NSIsSymbolNameDefined(varName)) {

        // The symbol exists, so bind it and get its address
        theSymbol = NSLookupAndBindSymbol(varName);
        address = NSAddressOfSymbol(theSymbol);

        // Create a new constant sub in the specified stash
        mySV = CBDerefIDtoSV(*(NSString**)address);
        newCONSTSUB(gv_stashpv(pkgName, 0), (char *)varName+1, mySV);
        
        return TRUE;

    } else {

        return FALSE;

    }
}
