root/src/apps/resedit/ResourceRoster.cpp
/*
 * Copyright (c) 2005-2010, Haiku, Inc.
 * Distributed under the terms of the MIT license.
 *
 * Author:
 *              DarkWyrm <darkwyrm@gmail.com>
 */
#include "ResourceRoster.h"

#include <Application.h>
#include <Bitmap.h>
#include <Directory.h>
#include <Entry.h>
#include <image.h>
#include <Path.h>
#include <Roster.h>
#include <String.h>

#include "InternalEditors.h"
#include "ResourceData.h"
#include "ResFields.h"

// For the MakeFieldForType temp code
#include <TranslatorFormats.h>
#include <TranslationUtils.h>
#include <DataIO.h>
#include <Mime.h>
#include <TypeConstants.h>

class EditorInfo
{
public:
                                        EditorInfo(const image_id &id, const char *name,
                                                                create_editor *allocator);
                                        ~EditorInfo(void);
        
        status_t                ID(void) const { return fID; }
        const char *    Name(void) const { return fName.String(); }
        Editor *                Instantiate(void);

private:
        image_id                fID;
        BString                 fName;
        create_editor * fAllocator;
};

EditorInfo::EditorInfo(const image_id &id, const char *name,
                                                create_editor *allocator)
  :     fID(id),
        fName(name),
        fAllocator(allocator)
{
}


EditorInfo::~EditorInfo(void)
{
}

        
Editor *
EditorInfo::Instantiate(void)
{
        return fAllocator();
}


ResourceRoster::ResourceRoster(void)
{
}


ResourceRoster::~ResourceRoster(void)
{
}


BField *
ResourceRoster::MakeFieldForType(const int32 &type, const char *data,
                                                                const size_t &length)
{
        // temporary code until editors are done
        switch (type) {
                case B_MIME_STRING_TYPE:
                        return new StringPreviewField(data);
                case B_GIF_FORMAT:
                case B_PPM_FORMAT:
                case B_TGA_FORMAT:
                case B_BMP_FORMAT:
                case B_TIFF_FORMAT:
                case B_PNG_FORMAT:
                case B_JPEG_FORMAT: {
                        BMemoryIO memio(data, length);
                        BBitmap *bitmap = BTranslationUtils::GetBitmap(&memio);
                        if (bitmap) {
                                BitmapPreviewField *field = new BitmapPreviewField(bitmap);
                                return field;
                        }
                        break;
                }
                default:
                        return NULL;
        }
        
        return NULL;
}


void
ResourceRoster::LoadEditors(void)
{
        app_info info;
        be_app->GetAppInfo(&info);
        
        BDirectory dir;
        BEntry entry(&info.ref);
        entry.GetParent(&dir);
        entry.SetTo(&dir, "addons");
        dir.SetTo(&entry);
        
        entry_ref ref;
        dir.Rewind();
        while (dir.GetNextRef(&ref) == B_OK) {
                BPath path(&ref);
                
                image_id addon = load_add_on(path.Path());
                if (addon < 0)
                        continue;
                
                char *temp;
                if (get_image_symbol(addon, "description", B_SYMBOL_TYPE_DATA, (void **)(&temp)) != B_OK) {
                        unload_add_on(addon);
                        continue;
                }
                
                create_editor *createFunc;
                if (get_image_symbol(addon, "instantiate_editor", B_SYMBOL_TYPE_TEXT, (void **)(&createFunc)) != B_OK) {
                        delete temp;
                        unload_add_on(addon);
                        continue;
                }
                
                if (createFunc && temp)
                        fList.AddItem(new EditorInfo(addon, temp, createFunc));
                
                delete temp;
        }
}

void
ResourceRoster::SpawnEditor(ResourceData *data, BHandler *handler)
{
        // temporary code until editors are done
        switch (data->GetType()) {
                case B_STRING_TYPE:
                case B_MIME_STRING_TYPE: {
                        StringEditor *strEd = new StringEditor(BRect(100, 100, 400, 200),
                                                                                                        data, handler);
                        strEd->Show();
                        break;
                }
                case B_GIF_FORMAT:
                case B_PPM_FORMAT:
                case B_TGA_FORMAT:
                case B_BMP_FORMAT:
                case B_TIFF_FORMAT:
                case B_PNG_FORMAT:
                case B_JPEG_FORMAT: {
                        ImageEditor *imgEd = new ImageEditor(BRect(100, 100, 300, 200),
                                                                                                        data, handler);
                        imgEd->Show();
                        break;
                }
                default:
                        break;
        }
}