/*
 * This file is autogenerated with bcop:
 * The Compiz option code generator
 *
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <compiz.h>

#define _SNAP_OPTIONS_INTERNAL
#include "snap_options.h"

static int displayPrivateIndex;

static CompMetadata snapOptionsMetadata;

static CompPluginVTable *snapPluginVTable = NULL;
CompPluginVTable snapOptionsVTable;

#define GET_SNAP_OPTIONS_DISPLAY(d) \
        ((SnapOptionsDisplay *) (d)->privates[displayPrivateIndex].ptr)

#define SNAP_OPTIONS_DISPLAY(d) \
        SnapOptionsDisplay *od = GET_SNAP_OPTIONS_DISPLAY (d)

#define GET_SNAP_OPTIONS_SCREEN(s, od) \
        ((SnapOptionsScreen *) (s)->privates[(od)->screenPrivateIndex].ptr)

#define SNAP_OPTIONS_SCREEN(s) \
        SnapOptionsScreen *os = GET_SNAP_OPTIONS_SCREEN (s, GET_SNAP_OPTIONS_DISPLAY (s->display))

typedef struct _SnapOptionsDisplay
{
    int screenPrivateIndex;

    CompOption opt[SnapDisplayOptionNum];
    snapDisplayOptionChangeNotifyProc notify[SnapDisplayOptionNum];
    unsigned int avoid_snap;
} SnapOptionsDisplay;

typedef struct _SnapOptionsScreen
{
    CompOption opt[SnapScreenOptionNum];
    snapScreenOptionChangeNotifyProc notify[SnapScreenOptionNum];
    unsigned int snap_type;
    unsigned int edges_categories;
} SnapOptionsScreen;

CompListValue * snapGetAvoidSnap (CompDisplay *d)
{
    SNAP_OPTIONS_DISPLAY(d);
    return &od->opt[SnapDisplayOptionAvoidSnap].value.list;
}

unsigned int snapGetAvoidSnapMask (CompDisplay *d)
{
    SNAP_OPTIONS_DISPLAY(d);
    return od->avoid_snap;
}

CompOption * snapGetAvoidSnapOption (CompDisplay *d)
{
    SNAP_OPTIONS_DISPLAY(d);
    return &od->opt[SnapDisplayOptionAvoidSnap];
}

void snapSetAvoidSnapNotify (CompDisplay *d, snapDisplayOptionChangeNotifyProc notify)
{
    SNAP_OPTIONS_DISPLAY(d);
    od->notify[SnapDisplayOptionAvoidSnap] = notify;
}

CompListValue * snapGetSnapType (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return &os->opt[SnapScreenOptionSnapType].value.list;
}

unsigned int snapGetSnapTypeMask (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return os->snap_type;
}

CompOption * snapGetSnapTypeOption (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return &os->opt[SnapScreenOptionSnapType];
}

void snapSetSnapTypeNotify (CompScreen *s, snapScreenOptionChangeNotifyProc notify)
{
    SNAP_OPTIONS_SCREEN(s);
    os->notify[SnapScreenOptionSnapType] = notify;
}

CompListValue * snapGetEdgesCategories (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return &os->opt[SnapScreenOptionEdgesCategories].value.list;
}

unsigned int snapGetEdgesCategoriesMask (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return os->edges_categories;
}

CompOption * snapGetEdgesCategoriesOption (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return &os->opt[SnapScreenOptionEdgesCategories];
}

void snapSetEdgesCategoriesNotify (CompScreen *s, snapScreenOptionChangeNotifyProc notify)
{
    SNAP_OPTIONS_SCREEN(s);
    os->notify[SnapScreenOptionEdgesCategories] = notify;
}

int snapGetResistanceDistance (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return os->opt[SnapScreenOptionResistanceDistance].value.i;
}

CompOption * snapGetResistanceDistanceOption (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return &os->opt[SnapScreenOptionResistanceDistance];
}

void snapSetResistanceDistanceNotify (CompScreen *s, snapScreenOptionChangeNotifyProc notify)
{
    SNAP_OPTIONS_SCREEN(s);
    os->notify[SnapScreenOptionResistanceDistance] = notify;
}

int snapGetAttractionDistance (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return os->opt[SnapScreenOptionAttractionDistance].value.i;
}

CompOption * snapGetAttractionDistanceOption (CompScreen *s)
{
    SNAP_OPTIONS_SCREEN(s);
    return &os->opt[SnapScreenOptionAttractionDistance];
}

void snapSetAttractionDistanceNotify (CompScreen *s, snapScreenOptionChangeNotifyProc notify)
{
    SNAP_OPTIONS_SCREEN(s);
    os->notify[SnapScreenOptionAttractionDistance] = notify;
}

CompOption * snapGetDisplayOption (CompDisplay *d, SnapDisplayOptions num)
{
    SNAP_OPTIONS_DISPLAY(d);
    return &od->opt[num];
}

CompOption * snapGetScreenOption (CompScreen *s, SnapScreenOptions num)
{
    SNAP_OPTIONS_SCREEN(s);
    return &os->opt[num];
}

static const CompMetadataOptionInfo snapOptionsDisplayOptionInfo[] = {
    { "avoid_snap", "list", "<type>int</type>", 0, 0 },
};

static Bool snapOptionsSetDisplayOption (CompPlugin *plugin, CompDisplay *d, char *name, CompOptionValue *value)
{
    SNAP_OPTIONS_DISPLAY(d);
    CompOption *o;
    int        index;

    o = compFindOption (od->opt, SnapDisplayOptionNum, name, &index);

    if (!o)
        return FALSE;

    switch (index)
    {
     case SnapDisplayOptionAvoidSnap:
        if (compSetDisplayOption (d, o, value))
        {
            int i;
            od->avoid_snap = 0;
            for (i = 0; i < o->value.list.nValue; i++)
                od->avoid_snap |= (1 << o->value.list.value[i].i);
            if (od->notify[SnapDisplayOptionAvoidSnap])
                (*od->notify[SnapDisplayOptionAvoidSnap]) (d, o, SnapDisplayOptionAvoidSnap);
            return TRUE;
        }
        break;
    default:
        break;
    }
    return FALSE;
}

static CompOption * snapOptionsGetDisplayOptions (CompPlugin *plugin, CompDisplay *d, int *count)
{
    SNAP_OPTIONS_DISPLAY(d);
    *count = SnapDisplayOptionNum;
    return od->opt;
}

static const CompMetadataOptionInfo snapOptionsScreenOptionInfo[] = {
    { "snap_type", "list", "<type>int</type>", 0, 0 },
    { "edges_categories", "list", "<type>int</type>", 0, 0 },
    { "resistance_distance", "int", "<min>1</min><max>100</max>", 0, 0 },
    { "attraction_distance", "int", "<min>1</min><max>100</max>", 0, 0 },
};

static Bool snapOptionsSetScreenOption (CompPlugin *plugin, CompScreen *s, char *name, CompOptionValue *value)
{
    SNAP_OPTIONS_SCREEN(s);
    CompOption *o;
    int        index;

    o = compFindOption (os->opt, SnapScreenOptionNum, name, &index);

    if (!o)
        return FALSE;

    switch (index)
    {
     case SnapScreenOptionSnapType:
        if (compSetScreenOption (s, o, value))
        {
            int i;
            os->snap_type = 0;
            for (i = 0; i < o->value.list.nValue; i++)
                os->snap_type |= (1 << o->value.list.value[i].i);
            if (os->notify[SnapScreenOptionSnapType])
                (*os->notify[SnapScreenOptionSnapType]) (s, o, SnapScreenOptionSnapType);
            return TRUE;
        }
        break;
     case SnapScreenOptionEdgesCategories:
        if (compSetScreenOption (s, o, value))
        {
            int i;
            os->edges_categories = 0;
            for (i = 0; i < o->value.list.nValue; i++)
                os->edges_categories |= (1 << o->value.list.value[i].i);
            if (os->notify[SnapScreenOptionEdgesCategories])
                (*os->notify[SnapScreenOptionEdgesCategories]) (s, o, SnapScreenOptionEdgesCategories);
            return TRUE;
        }
        break;
     case SnapScreenOptionResistanceDistance:
        if (compSetScreenOption (s, o, value))
        {
            if (os->notify[SnapScreenOptionResistanceDistance])
                (*os->notify[SnapScreenOptionResistanceDistance]) (s, o, SnapScreenOptionResistanceDistance);
            return TRUE;
        }
        break;
     case SnapScreenOptionAttractionDistance:
        if (compSetScreenOption (s, o, value))
        {
            if (os->notify[SnapScreenOptionAttractionDistance])
                (*os->notify[SnapScreenOptionAttractionDistance]) (s, o, SnapScreenOptionAttractionDistance);
            return TRUE;
        }
        break;
    default:
        break;
    }
    return FALSE;
}

static CompOption * snapOptionsGetScreenOptions (CompPlugin *plugin, CompScreen *s, int *count)
{
    SNAP_OPTIONS_SCREEN(s);
    *count = SnapScreenOptionNum;
    return os->opt;
}

static Bool snapOptionsInitScreen (CompPlugin *p, CompScreen *s)
{
    SnapOptionsScreen *os;
    CompOption *o;
    int i;
    
    SNAP_OPTIONS_DISPLAY (s->display);

    os = calloc (1, sizeof(SnapOptionsScreen));
    if (!os)
        return FALSE;

    s->privates[od->screenPrivateIndex].ptr = os;

    if (!compInitScreenOptionsFromMetadata (s, &snapOptionsMetadata, snapOptionsScreenOptionInfo, os->opt, SnapScreenOptionNum))
    {
        free (os);
        return FALSE;
    }
    o = &os->opt[SnapScreenOptionSnapType];
    os->snap_type = 0;
    for (i = 0; i < o->value.list.nValue; i++)
        os->snap_type |= (1 << o->value.list.value[i].i);

    o = &os->opt[SnapScreenOptionEdgesCategories];
    os->edges_categories = 0;
    for (i = 0; i < o->value.list.nValue; i++)
        os->edges_categories |= (1 << o->value.list.value[i].i);

    if (snapPluginVTable && snapPluginVTable->initScreen)
        return snapPluginVTable->initScreen (p, s);
    return TRUE;
}

static void snapOptionsFiniScreen (CompPlugin *p, CompScreen *s)
{
    if (snapPluginVTable && snapPluginVTable->finiScreen)
        return snapPluginVTable->finiScreen (p, s);

    SNAP_OPTIONS_SCREEN (s);


    compFiniScreenOptions (s, os->opt, SnapScreenOptionNum);

    free (os);
}

static Bool snapOptionsInitDisplay (CompPlugin *p, CompDisplay *d)
{
    SnapOptionsDisplay *od;
   CompOption *o;
    int i;
    
    
    od = calloc (1, sizeof(SnapOptionsDisplay));
    if (!od)
        return FALSE;

    od->screenPrivateIndex = allocateScreenPrivateIndex(d);
    if (od->screenPrivateIndex < 0)
    {
        free(od);
        return FALSE;
    }

    d->privates[displayPrivateIndex].ptr = od;

    if (!compInitDisplayOptionsFromMetadata (d, &snapOptionsMetadata, snapOptionsDisplayOptionInfo, od->opt, SnapDisplayOptionNum))
    {
        free (od);
        return FALSE;
    }
    o = &od->opt[SnapDisplayOptionAvoidSnap];
    od->avoid_snap = 0;
    for (i = 0; i < o->value.list.nValue; i++)
        od->avoid_snap |= (1 << o->value.list.value[i].i);

    if (snapPluginVTable && snapPluginVTable->initDisplay)
        return snapPluginVTable->initDisplay (p, d);
    return TRUE;
}

static void snapOptionsFiniDisplay (CompPlugin *p, CompDisplay *d)
{
    if (snapPluginVTable && snapPluginVTable->finiDisplay)
        return snapPluginVTable->finiDisplay (p, d);

    SNAP_OPTIONS_DISPLAY (d);

    freeScreenPrivateIndex(d, od->screenPrivateIndex);

    compFiniDisplayOptions (d, od->opt, SnapDisplayOptionNum);

    free (od);
}

static Bool snapOptionsInit (CompPlugin *p)
{
    displayPrivateIndex = allocateDisplayPrivateIndex();
    if (displayPrivateIndex < 0)
        return FALSE;

    if (!compInitPluginMetadataFromInfo (&snapOptionsMetadata, "snap",snapOptionsDisplayOptionInfo, SnapDisplayOptionNum, snapOptionsScreenOptionInfo, SnapScreenOptionNum))
        return FALSE;

    compAddMetadataFromFile (&snapOptionsMetadata, "snap");
    if (snapPluginVTable && snapPluginVTable->init)
        return snapPluginVTable->init (p);
    return TRUE;
}

static void snapOptionsFini (CompPlugin *p)
{
    if (snapPluginVTable && snapPluginVTable->fini)
        return snapPluginVTable->fini (p);

    if (displayPrivateIndex >= 0)
        freeDisplayPrivateIndex(displayPrivateIndex);

    compFiniMetadata (&snapOptionsMetadata);
}

static CompMetadata *
snapOptionsGetMetadata (CompPlugin *plugin)
{
    return &snapOptionsMetadata;
}

CompPluginVTable *getCompPluginInfo (void)
{
    if (!snapPluginVTable)
    {
        snapPluginVTable = snapOptionsGetCompPluginInfo ();
        memcpy(&snapOptionsVTable, snapPluginVTable, sizeof(CompPluginVTable));
        snapOptionsVTable.getMetadata = snapOptionsGetMetadata;
        snapOptionsVTable.init = snapOptionsInit;
        snapOptionsVTable.fini = snapOptionsFini;
        snapOptionsVTable.initDisplay = snapOptionsInitDisplay;
        snapOptionsVTable.finiDisplay = snapOptionsFiniDisplay;
        snapOptionsVTable.initScreen = snapOptionsInitScreen;
        snapOptionsVTable.finiScreen = snapOptionsFiniScreen;
        snapOptionsVTable.getDisplayOptions = snapOptionsGetDisplayOptions;
	snapOptionsVTable.setDisplayOption = snapOptionsSetDisplayOption;
	snapOptionsVTable.getScreenOptions = snapOptionsGetScreenOptions;
	snapOptionsVTable.setScreenOption = snapOptionsSetScreenOption;
	
    }
    return &snapOptionsVTable;
}



syntax highlighted by Code2HTML, v. 0.9.1