/* Copyright (C) 2007-2015 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
*/
#include "android/globals.h"

#include "android/skin/file.h"

#include "android/skin/keycode.h"
#include "android/utils/path.h"
#include "android/utils/bufprint.h"
#include "android/utils/system.h"
#include "android/utils/debug.h"

#include <stdlib.h>

/** UTILITY ROUTINES
 **/
static SkinImage*
skin_image_find_in( const char*  dirname, const char*  filename )
{
    char   buffer[1024];
    char*  p   = buffer;
    char*  end = p + sizeof(buffer);

    p = bufprint( p, end, "%s" PATH_SEP "%s", dirname, filename );
    if (p >= end)
        return SKIN_IMAGE_NONE;

    return skin_image_find_simple(buffer);
}

/** SKIN BACKGROUND
 **/

static void
skin_background_done( SkinBackground*  background )
{
    if (background->image)
        skin_image_unref(&background->image);
}

static int skin_background_init_from(SkinBackground* background,
                                     const AConfig* node,
                                     const char* basepath) {
    const char* img = aconfig_str(node, "image", NULL);
    int         x   = aconfig_int(node, "x", 0);
    int         y   = aconfig_int(node, "y", 0);

    background->valid = 0;

    if (img == NULL)   /* no background */
        return -1;

    background->image = skin_image_find_in( basepath, img );
    if (background->image == SKIN_IMAGE_NONE) {
        background->image = NULL;
        return -1;
    }

    background->rect.pos.x  = x;
    background->rect.pos.y  = y;
    background->rect.size.w = skin_image_w( background->image );
    background->rect.size.h = skin_image_h( background->image );

    background->valid = 1;

    return 0;
}

/** SKIN DISPLAY
 **/

static void
skin_display_done(SkinDisplay*  display)
{
    if (display->framebuffer_funcs && display->owns_framebuffer) {
        display->framebuffer_funcs->free_framebuffer(display->framebuffer);
    }
}

static int skin_display_init_from(SkinDisplay* display,
                                  const AConfig* node,
                                  const SkinFramebufferFuncs* fb_funcs) {
    display->rect.pos.x  = aconfig_int(node, "x", 0);
    display->rect.pos.y  = aconfig_int(node, "y", 0);
    display->rect.size.w = aconfig_int(node, "width", 0);
    display->rect.size.h = aconfig_int(node, "height", 0);
    display->rotation    = aconfig_unsigned(node, "rotation", SKIN_ROTATION_0);
    display->bpp         = aconfig_int(node, "bpp", android_hw->hw_lcd_depth);
    display->owns_framebuffer = 1;

    display->valid = ( display->rect.size.w > 0 && display->rect.size.h > 0 );
    display->framebuffer_funcs = fb_funcs;
    if (display->valid && fb_funcs) {
        SkinRect  r;
        skin_rect_rotate( &r, &display->rect, -display->rotation );
        display->framebuffer = fb_funcs->create_framebuffer(
                r.size.w,
                r.size.h,
                display->bpp);
#if 0
        qframebuffer_init( display->qfbuff,
                           r.size.w,
                           r.size.h,
                           0,
                           display->bpp == 32 ? QFRAME_BUFFER_RGBX_8888
                                              : QFRAME_BUFFER_RGB565 );

        qframebuffer_fifo_add( display->qfbuff );
#endif
    }
    return display->valid ? 0 : -1;
}

/** SKIN BUTTON
 **/


static void
skin_button_free( SkinButton*  button )
{
    if (button) {
        skin_image_unref( &button->image );
        AFREE(button);
    }
}

static unsigned translate_button_name(const char* name) {
    typedef struct {
        const char*     name;
        SkinKeyCode  code;
    } KeyInfo;

    static const KeyInfo keyinfo_table[] = {
        { "dpad-up",      kKeyCodeDpadUp },
        { "dpad-down",    kKeyCodeDpadDown },
        { "dpad-left",    kKeyCodeDpadLeft },
        { "dpad-right",   kKeyCodeDpadRight },
        { "dpad-center",  kKeyCodeDpadCenter },
        { "soft-left",    kKeyCodeSoftLeft },
        { "soft-right",   kKeyCodeSoftRight },
        { "search",       kKeyCodeSearch },
        { "camera",       kKeyCodeCamera },
        { "volume-up",    kKeyCodeVolumeUp },
        { "volume-down",  kKeyCodeVolumeDown },
        { "power",        kKeyCodePower },
        { "home",         kKeyCodeHome },
        { "homepage",     kKeyCodeHomePage },
        { "back",         kKeyCodeBack },
        { "del",          kKeyCodeDel },
        { "0",            kKeyCode0 },
        { "1",            kKeyCode1 },
        { "2",            kKeyCode2 },
        { "3",            kKeyCode3 },
        { "4",            kKeyCode4 },
        { "5",            kKeyCode5 },
        { "6",            kKeyCode6 },
        { "7",            kKeyCode7 },
        { "8",            kKeyCode8 },
        { "9",            kKeyCode9 },
        { "star",         kKeyCodeStar },
        { "pound",        kKeyCodePound },
        { "phone-dial",   kKeyCodeCall },
        { "phone-hangup", kKeyCodeEndCall },
        { "q",            kKeyCodeQ },
        { "w",            kKeyCodeW },
        { "e",            kKeyCodeE },
        { "r",            kKeyCodeR },
        { "t",            kKeyCodeT },
        { "y",            kKeyCodeY },
        { "u",            kKeyCodeU },
        { "i",            kKeyCodeI },
        { "o",            kKeyCodeO },
        { "p",            kKeyCodeP },
        { "a",            kKeyCodeA },
        { "s",            kKeyCodeS },
        { "d",            kKeyCodeD },
        { "f",            kKeyCodeF },
        { "g",            kKeyCodeG },
        { "h",            kKeyCodeH },
        { "j",            kKeyCodeJ },
        { "k",            kKeyCodeK },
        { "l",            kKeyCodeL },
        { "DEL",          kKeyCodeDel },
        { "z",            kKeyCodeZ },
        { "x",            kKeyCodeX },
        { "c",            kKeyCodeC },
        { "v",            kKeyCodeV },
        { "b",            kKeyCodeB },
        { "n",            kKeyCodeN },
        { "m",            kKeyCodeM },
        { "COMMA",        kKeyCodeComma },
        { "PERIOD",       kKeyCodePeriod },
        { "ENTER",        kKeyCodeNewline },
        { "AT",           kKeyCodeAt },
        { "SPACE",        kKeyCodeSpace },
        { "SLASH",        kKeyCodeSlash },
        { "CAP",          kKeyCodeCapLeft },
        { "SYM",          kKeyCodeSym },
        { "ALT",          kKeyCodeAltLeft },
        { "ALT2",         kKeyCodeAltRight },
        { "CAP2",         kKeyCodeCapRight },
        { "tv",           kKeyCodeTV },
        { "epg",          kKeyCodeEPG },
        { "dvr",          kKeyCodeDVR },
        { "prev",         kKeyCodePrevious },
        { "next",         kKeyCodeNext },
        { "play",         kKeyCodePlay },
        { "playpause",    kKeyCodePlaypause },
        { "pause",        kKeyCodePause },
        { "stop",         kKeyCodeStop },
        { "rev",          kKeyCodeRewind },
        { "ffwd",         kKeyCodeFastForward },
        { "bookmarks",    kKeyCodeBookmarks },
        { "window",       kKeyCodeCycleWindows },
        { "channel-up",   kKeyCodeChannelUp },
        { "channel-down", kKeyCodeChannelDown },
        { "app-switch",   kKeyCodeAppSwitch },
        { 0, 0 },
    };

    const KeyInfo *ki = keyinfo_table;
    while(ki->name) {
        if(!strcmp(name, ki->name))
            return ki->code;
        ki++;
    }
    return 0;
}

static SkinButton* skin_button_create_from(const AConfig* node,
                                           const char* basepath) {
    SkinButton*  button;
    ANEW0(button);
    if (button) {
        const char*  img = aconfig_str(node, "image", NULL);
        int          x   = aconfig_int(node, "x", 0);
        int          y   = aconfig_int(node, "y", 0);

        button->name       = node->name;
        button->rect.pos.x = x;
        button->rect.pos.y = y;

        if (img != NULL)
            button->image = skin_image_find_in( basepath, img );

        if (button->image == SKIN_IMAGE_NONE) {
            skin_button_free(button);
            return NULL;
        }

        button->rect.size.w = skin_image_w( button->image );
        button->rect.size.h = skin_image_h( button->image );

        button->keycode = translate_button_name(button->name);
        if (button->keycode == 0) {
            dprint("Warning: skin file button uses unknown key name '%s'",
                   button->name);
        }
    }
    return button;
}

/** SKIN PART
 **/

static void
skin_part_free( SkinPart*  part )
{
    if (part) {
        skin_background_done( part->background );
        skin_display_done( part->display );

        SKIN_PART_LOOP_BUTTONS(part,button)
            skin_button_free(button);
        SKIN_PART_LOOP_END
        part->buttons = NULL;
        AFREE(part);
    }
}

static SkinLocation* skin_location_create_from_v2(const AConfig* node,
                                                  SkinPart* parts) {
    const char*    partname = aconfig_str(node, "name", NULL);
    int            x        = aconfig_int(node, "x", 0);
    int            y        = aconfig_int(node, "y", 0);
    SkinRotation   rot      = aconfig_int(node, "rotation", SKIN_ROTATION_0);
    SkinPart*      part;
    SkinLocation*  location;

    if (partname == NULL) {
        dprint( "### WARNING: ignoring part location without 'name' element" );
        return NULL;
    }

    for (part = parts; part; part = part->next)
        if (!strcmp(part->name, partname))
            break;

    if (part == NULL) {
        dprint( "### WARNING: ignoring part location with unknown name '%s'", partname );
        return NULL;
    }

    ANEW0(location);
    location->part     = part;
    location->anchor.x = x;
    location->anchor.y = y;
    location->rotation = rot;

    return location;
}

static SkinPart* skin_part_create_from_v1(
        const AConfig* root,
        const char* basepath,
        const SkinFramebufferFuncs* fb_funcs) {
    SkinPart* part;
    const AConfig* node;
    SkinBox box;

    ANEW0(part);
    part->name = root->name;

    node = aconfig_find_const(root, "background");
    if (node)
        skin_background_init_from(part->background, node, basepath);

    node = aconfig_find_const(root, "display");
    if (node)
        skin_display_init_from(part->display, node, fb_funcs);

    node = aconfig_find_const(root, "button");
    if (node) {
        for (node = node->first_child; node != NULL; node = node->next)
        {
            SkinButton*  button = skin_button_create_from(
                    node, basepath);

            if (button != NULL) {
                button->next  = part->buttons;
                part->buttons = button;
            }
        }
    }

    skin_box_minmax_init( &box );

    if (part->background->valid)
        skin_box_minmax_update( &box, &part->background->rect );

    if (part->display->valid)
        skin_box_minmax_update( &box, &part->display->rect );

    SKIN_PART_LOOP_BUTTONS(part, button)
        skin_box_minmax_update( &box, &button->rect );
    SKIN_PART_LOOP_END

    if ( !skin_box_minmax_to_rect( &box, &part->rect ) ) {
        skin_part_free(part);
        part = NULL;
    }

    return part;
}

static SkinPart* skin_part_create_from_v2(
        const AConfig* root,
        const char* basepath,
        const SkinFramebufferFuncs* fb_funcs) {
    SkinPart* part;
    const AConfig* node;
    SkinBox box;

    ANEW0(part);
    part->name = root->name;

    node = aconfig_find_const(root, "background");
    if (node)
        skin_background_init_from(part->background, node, basepath);

    node = aconfig_find_const(root, "display");
    if (node)
        skin_display_init_from(part->display, node, fb_funcs);

    node = aconfig_find_const(root, "buttons");
    if (node) {
        for (node = node->first_child; node != NULL; node = node->next)
        {
            SkinButton*  button = skin_button_create_from(
                    node, basepath);

            if (button != NULL) {
                button->next  = part->buttons;
                part->buttons = button;
            }
        }
    }

    skin_box_minmax_init( &box );

    if (part->background->valid)
        skin_box_minmax_update( &box, &part->background->rect );

    if (part->display->valid)
        skin_box_minmax_update( &box, &part->display->rect );

    SKIN_PART_LOOP_BUTTONS(part, button)
        skin_box_minmax_update( &box, &button->rect );
    SKIN_PART_LOOP_END

    if ( !skin_box_minmax_to_rect( &box, &part->rect ) ) {
        skin_part_free(part);
        part = NULL;
    }
    return part;
}

/** SKIN LAYOUT
 **/

static void
skin_layout_free( SkinLayout*  layout )
{
    if (layout) {
        SKIN_LAYOUT_LOOP_LOCS(layout,loc)
            AFREE(loc);
        SKIN_LAYOUT_LOOP_END
        layout->locations = NULL;
        if (layout->onion_image) {
          skin_image_unref( &layout->onion_image );
        }
        AFREE(layout);
    }
}

SkinDisplay*
skin_layout_get_display( SkinLayout*  layout )
{
    SKIN_LAYOUT_LOOP_LOCS(layout,loc)
        SkinPart*  part = loc->part;
        if (part->display->valid) {
            return part->display;
        }
    SKIN_LAYOUT_LOOP_END
    return NULL;
}

SkinRotation
skin_layout_get_dpad_rotation(SkinLayout* layout)
{
    if (layout->has_dpad_rotation)
        return layout->dpad_rotation;

    SKIN_LAYOUT_LOOP_LOCS(layout, loc)
        SkinPart*  part = loc->part;
        SKIN_PART_LOOP_BUTTONS(part,button)
            if (button->keycode == kKeyCodeDpadUp)
                return loc->rotation;
        SKIN_PART_LOOP_END
    SKIN_LAYOUT_LOOP_END

    return SKIN_ROTATION_0;
}


static int
skin_layout_event_decode( const char*  event, int  *ptype, int  *pcode, int *pvalue )
{
    typedef struct {
        const char*  name;
        int          value;
    } EventName;

    static const EventName  _event_names[] = {
        { "EV_SW", 0x05 },
        { NULL, 0 },
    };

    const char*       x = strchr(event, ':');
    const char*       y = NULL;
    const EventName*  ev = _event_names;

    if (x != NULL)
        y = strchr(x+1, ':');

    if (x == NULL || y == NULL) {
        dprint( "### WARNING: invalid skin layout event format: '%s', should be '<TYPE>:<CODE>:<VALUE>'", event );
        return -1;
    }

    for ( ; ev->name != NULL; ev++ )
        if (!memcmp( event, ev->name, x - event ) && ev->name[x-event] == 0)
            break;

    if (!ev->name) {
        dprint( "### WARNING: unrecognized skin layout event name: %.*s", x-event, event );
        return -1;
    }

    *ptype  = ev->value;
    *pcode  = strtol(x+1, NULL, 0);
    *pvalue = strtol(y+1, NULL, 0);
    return 0;
}

static SkinLayout* skin_layout_create_from_v2(const AConfig* root,
                                              SkinPart* parts,
                                              const char* basepath) {
    SkinLayout*    layout;
    int            width, height;
    SkinLocation** ptail;
    const AConfig* node;

    ANEW0(layout);

    width  = aconfig_int( root, "width", 400 );
    height = aconfig_int( root, "height", 400 );

    node = aconfig_find_const(root, "event");
    if (node != NULL) {
        skin_layout_event_decode( node->value,
                                  &layout->event_type,
                                  &layout->event_code,
                                  &layout->event_value );
    } else {
        layout->event_type  = 0x05;  /* close keyboard by default */
        layout->event_code  = 0;
        layout->event_value = 1;
    }

    layout->name  = root->name;
    layout->color = aconfig_unsigned( root, "color", 0x808080 ) | 0xff000000;
    ptail         = &layout->locations;

    node = aconfig_find_const(root, "dpad-rotation");
    if (node != NULL) {
        layout->dpad_rotation     = aconfig_int( root, "dpad-rotation", 0 );
        layout->has_dpad_rotation = 1;
    }

    node = aconfig_find_const(root, "onion");
    if (node != NULL) {
        const char* img = aconfig_str(node, "image", NULL);
        layout->onion_image = skin_image_find_in( basepath, img );
        if (layout->onion_image == SKIN_IMAGE_NONE) {
            layout->onion_image = NULL;
        }
        // In layout file, alpha is specified in range 0-100. Convert to
        // internal range 0-256 with default=128.
        int alpha = aconfig_int( node, "alpha", 50 );
        layout->onion_alpha = (256*alpha)/100;
        layout->onion_rotation = aconfig_int( node, "rotation", 0 );
    }

    for (node = root->first_child; node; node = node->next)
    {
        if (!memcmp(node->name, "part", 4)) {
            SkinLocation*  location = skin_location_create_from_v2( node, parts );
            if (location == NULL) {
                continue;
            }
            *ptail = location;
            ptail  = &location->next;
        }
    }

    if (layout->locations == NULL)
        goto Fail;

    layout->size.w = width;
    layout->size.h = height;

    return layout;

Fail:
    skin_layout_free(layout);
    return NULL;
}

// Rotates a given rect that is inside another rect around the center of its parent
// 'dst' is a pointer to the location where the result will be stored
// 'src' is a pointer to the rect that will be rotated and can be the same as 'dst'
// 'parent_size' is the width and height of src's parent rect
// 'by' is the amount of rotation, in 90-degree increments
static void
skin_rect_rotate_in_rect(SkinRect* dst, const SkinRect* src, const SkinSize* parent_size, SkinRotation by) {
    int x = src->pos.x;
    int y = src->pos.y;

    skin_size_rotate(&(dst->size), &(src->size), by);

    switch(by) {
    case SKIN_ROTATION_90:
        dst->pos.x = parent_size->w - y - dst->size.w;
        dst->pos.y = x;
        break;

    case SKIN_ROTATION_180:
        dst->pos.x = parent_size->w - x - dst->size.w;
        dst->pos.y = parent_size->h - y - dst->size.h;
        break;

    case SKIN_ROTATION_270:
        dst->pos.x = y;
        dst->pos.y = parent_size->h - x - dst->size.h;
        break;

    case SKIN_ROTATION_0:
    default:
        break;
    }
}

// Creates a version of the given button rotated around the center of the given part.
// 'src' is the button that needs rotation
// 'part_size' is the width and height of the part containing the button
// 'by' is the amount of rotation in 90-degree increments
static SkinButton*
skin_button_create_rotated(const SkinButton* src, const SkinSize* part_size, SkinRotation by) {
    SkinButton* new_button;
    ANEW0(new_button);
    *new_button = *src;
    new_button->next = NULL;
    skin_rect_rotate_in_rect(&(new_button->rect), &(src->rect), part_size, by);
    new_button->image = skin_image_clone_rotated(src->image, by);
    if (new_button->image == SKIN_IMAGE_NONE) {
        goto Fail;
    }
    return new_button;

Fail:
    skin_button_free(new_button);
    return NULL;
}

// Creates a version of the given skin part that is rotated around the center of the given
// layout.
// 'src' is the part that needs rotation
// 'layout_size' is the width and height of the parent layout
// 'by' is the amount of rotation in 90-degree increments
static SkinPart*
skin_part_create_rotated(const SkinPart* src, const SkinSize* layout_size, SkinRotation by) {
    SkinPart* new_part;
    ANEW0(new_part);

    *new_part = *src;
    new_part->next = NULL;
    new_part->buttons = NULL;

    // Rotate the background image
    if (new_part->background->image &&
        new_part->background->image != SKIN_IMAGE_NONE) {
        new_part->background->image =
            skin_image_clone_rotated(src->background->image, by);
        skin_size_rotate(&(new_part->background->rect.size), &(src->background->rect.size), by);
        if (new_part->background->image == SKIN_IMAGE_NONE) {
            goto Fail;
        }
    }

    // If the part has a display, rotate that too
    if (new_part->display->valid) {
        skin_size_rotate(&(new_part->display->rect.size), &(src->display->rect.size), by);
        new_part->display->rotation = skin_rotation_rotate(new_part->display->rotation, by);

        // Rotated part shares framebuffer with the original.
        new_part->display->owns_framebuffer = 0;
    }

    // Rotate each of the part's buttons so that they align with the rotated
    // background properly.
    SkinButton** new_btn = &(new_part->buttons);
    SKIN_PART_LOOP_BUTTONS(src, btn)
        *new_btn = skin_button_create_rotated(btn, &(new_part->background->rect.size), by);
        if (*new_btn == NULL) {
            goto Fail;
        }
        new_btn = &((*new_btn)->next);
    SKIN_PART_LOOP_END

    return new_part;

Fail:
    skin_part_free(new_part);
    return NULL;
}

// Rotates a given SkinLocation within its parent layout. It will create a rotated copy of
// the skin part that the location refernces.
static SkinLocation*
skin_location_create_rotated(const SkinLocation* src, const SkinSize* layout_size, SkinRotation by)
{
    SkinLocation* new_location;
    ANEW0(new_location);

    *new_location = *src;
    new_location->next = NULL;
    new_location->part = skin_part_create_rotated(src->part, layout_size, by);
    if (new_location->part == NULL) {
        goto Fail;
    }

    SkinRect r;
    r.pos = src->anchor;
    r.size = new_location->part->display->valid ?
        src->part->display->rect.size :
        src->part->background->rect.size;

    skin_rect_rotate_in_rect(&r, &r, layout_size, by);
    new_location->anchor.x = r.pos.x;
    new_location->anchor.y = r.pos.y;
    return new_location;

Fail:
    AFREE(new_location);
    return NULL;
}

// Create a new layout which is the same as src, but rotated by a given amount.
// This will also create rotated clones of all the parts used by the source layout.
// 'src' is the source layout.
// 'new_parts_ptr' is the pointer to the location where the head of the linked list
//                 of the new parts should be stored.
// 'by' is the amount of rotation to apply, in 90-degree increments.
static SkinLayout*
skin_layout_create_rotated(const SkinLayout* src, SkinPart** new_parts_ptr, SkinRotation by)
{
    SkinLayout* new_layout;
    ANEW0(new_layout);

    *new_layout = *src;

    new_layout->next = NULL;
    new_layout->orientation = skin_rotation_rotate(new_layout->orientation, by);

    // DPad rotation is needed to ensure the arrow keys work correctly, even if
    // the device isn't configured for a DPad
    new_layout->has_dpad_rotation = true;
    new_layout->dpad_rotation = by;
    skin_size_rotate(&(new_layout->size), &(src->size), by);

    new_layout->locations = NULL;
    SkinLocation** current_loc_ptr = &(new_layout->locations);
    SkinPart* new_parts = *new_parts_ptr; // A linked list of newly generated, rotated parts.

    SKIN_LAYOUT_LOOP_LOCS(src, loc)
        *current_loc_ptr = skin_location_create_rotated(loc, &(new_layout->size), by);
        if (current_loc_ptr == NULL) {
            goto Fail;
        }
        // Prepend the part generated for this location to the linked list of new parts
        (*current_loc_ptr)->part->next = new_parts;
        new_parts = (*current_loc_ptr)->part;

        (*current_loc_ptr)->next = NULL;
        current_loc_ptr = &((*current_loc_ptr)->next);
    SKIN_LAYOUT_LOOP_END

    // Rotate the onion image if there is one.
    if (src->onion_image && src->onion_image != SKIN_IMAGE_NONE) {
        new_layout->onion_rotation =
            skin_rotation_rotate(src->onion_rotation, by);
        new_layout->onion_image = skin_image_clone_rotated(src->onion_image, by);
        if (new_layout->onion_image == SKIN_IMAGE_NONE) {
            goto Fail;
        }
        new_layout->onion_image =
            skin_image_clone_rotated(
                new_layout->onion_image,
                skin_rotation_rotate(skin_image_rot(new_layout->onion_image), by));
        if (new_layout->onion_image == SKIN_IMAGE_NONE) {
            goto Fail;
        }
    }

    *new_parts_ptr = new_parts;
    return new_layout;

Fail:
    // Free the newly created skins because they're not going to be used.
    while (new_parts) {
        SkinPart* next = new_parts->next;
        skin_part_free(new_parts);
        new_parts = next;
    }

    // Free the layout itself.
    skin_layout_free(new_layout);
    return NULL;
}

/** SKIN FILE
 **/

static int skin_file_load_from_v1(SkinFile* file,
                                  const AConfig* aconfig,
                                  const char* basepath,
                                  const SkinFramebufferFuncs* fb_funcs) {
    SkinPart*      part;
    SkinLayout*    layout;
    SkinLayout**   ptail = &file->layouts;
    SkinLocation*  location;
    int            nn;

    file->parts = part = skin_part_create_from_v1(
            aconfig, basepath, fb_funcs);
    if (part == NULL)
        return -1;

    for (nn = 0; nn < 4; nn++)
    {
        ANEW0(layout);

        layout->color = 0xff808080;

        ANEW0(location);

        layout->event_type  = 0x05;  /* close keyboard by default */
        layout->event_code  = 0;
        layout->event_value = 0;

        location->part     = part;
        switch (nn) {
            case 0:
                location->anchor.x = 0;
                location->anchor.y = 0;
                location->rotation = SKIN_ROTATION_0;
                layout->size       = part->rect.size;
                break;

            case 1:
                location->anchor.x = part->rect.size.h;
                location->anchor.y = 0;
                location->rotation = SKIN_ROTATION_90;
                layout->size.w     = part->rect.size.h;
                layout->size.h     = part->rect.size.w;
                break;

            case 2:
                location->anchor.x = part->rect.size.w;
                location->anchor.y = part->rect.size.h;
                location->rotation = SKIN_ROTATION_180;
                layout->size       = part->rect.size;
                break;

            default:
                location->anchor.x = 0;
                location->anchor.y = part->rect.size.w;
                location->rotation = SKIN_ROTATION_270;
                layout->size.w     = part->rect.size.h;
                layout->size.h     = part->rect.size.w;
                break;
        }
        layout->locations = location;
        layout->orientation = location->rotation;

        *ptail = layout;
        ptail  = &layout->next;
    }
    file->version = 1;
    return 0;
}

// Names for auto-generated layouts.
// We don't need "portrait" - it is the first layout in
// skin files by convention, and we generate other
// orientations from it.
static const char* auto_layout_names[] =
    { "reverse_landscape", "reverse_portrait", "landscape" };

static int skin_file_load_from_v2(SkinFile* file,
                                  const AConfig* aconfig,
                                  const char* basepath,
                                  const SkinFramebufferFuncs* fb_funcs) {
    /* first, load all parts */
    const AConfig* node = aconfig_find_const(aconfig, "parts");
    if (node == NULL)
        return -1;
    else
    {
        SkinPart**  ptail = &file->parts;
        for (node = node->first_child; node != NULL; node = node->next)
        {
            SkinPart*  part = skin_part_create_from_v2(
                    node, basepath, fb_funcs);
            if (part == NULL) {
                dprint( "## WARNING: can't load part '%s' from skin\n", node->name ? "<NULL>" : node->name );
                continue;
            }

            part->next = NULL;
            *ptail     = part;
            ptail      = &part->next;
        }
    }

    if (file->parts == NULL)
        return -1;

    /* then load all layouts */
    node = aconfig_find_const(aconfig, "layouts");
    if (node == NULL)
        return -1;
    else
    {
        SkinLayout* next = skin_layout_create_from_v2(node->first_child, file->parts, basepath);
        next->orientation = SKIN_ROTATION_0;

        // We need to find the last element in the list of parts defined by the skin.
        // The automatically parts generated parts (generated by rotation) will be appended
        // after that part.
        SkinPart** last_part_ptr = &(file->parts);

        if (next == NULL) return -1;
        file->layouts = next;

        // Generate new layouts from the first layout. The new layouts are rotated
        // versions of the first layout.
        SkinLayout* layout = file->layouts;
        SkinLayout* first_layout = layout;
        SkinRotation r;

        for (r = SKIN_ROTATION_90; r <= SKIN_ROTATION_270; r++) {
            // Find the place in the list of parts at which to insert new
            // rotated versions of parts.
            while (*last_part_ptr) {
                last_part_ptr = &((*last_part_ptr)->next);
            }

            // Rotate the layout.
            layout->next = skin_layout_create_rotated(
                    first_layout, last_part_ptr,
                    (first_layout->dpad_rotation + r) % 4);
            if (layout->next != NULL) {
                // Update layout name.
                int layout_name_idx = r - SKIN_ROTATION_90;
                if (layout_name_idx >= 0 &&
                    layout_name_idx < sizeof(auto_layout_names) / sizeof(const char*)) {
                    layout->next->name = auto_layout_names[layout_name_idx];
                }

                layout = layout->next;
                layout->next = NULL;
            } else {
                dprint("## WARNING: failed to auto-generate rotated layout");
            }
        }
    }
    if (file->layouts == NULL)
        return -1;

    file->version = 2;
    return 0;
}

SkinFile* skin_file_create_from_aconfig(const AConfig* aconfig,
                                        const char* basepath,
                                        const SkinFramebufferFuncs* fb_funcs) {
    SkinFile*  file;

    ANEW0(file);

    if (aconfig_find_const(aconfig, "parts") != NULL) {
        if (skin_file_load_from_v2(
                file, aconfig, basepath, fb_funcs) < 0) {
            goto BAD_FILE;
        }
        file->version = aconfig_int(aconfig, "version", 2);
        /* The file version must be 1 or higher */
        if (file->version <= 0) {
            dprint( "## WARNING: invalid skin version: %d", file->version);
            goto BAD_FILE;
        }
    }
    else {
        if (skin_file_load_from_v1(
                file, aconfig, basepath, fb_funcs) < 0) {
            goto BAD_FILE;
        }
        file->version = 1;
    }
    return file;

BAD_FILE:
    skin_file_free( file );
    return NULL;
}

void
skin_file_free( SkinFile*  file )
{
    if (file) {
        SKIN_FILE_LOOP_LAYOUTS(file,layout)
            skin_layout_free(layout);
        SKIN_FILE_LOOP_END_LAYOUTS
        file->layouts = NULL;

        SKIN_FILE_LOOP_PARTS(file,part)
            skin_part_free(part);
        SKIN_FILE_LOOP_END_PARTS
        file->parts = NULL;

        AFREE(file);
    }
}
