/* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-

   framerender.c for the Openbox window manager
   Copyright (c) 2006        Mikael Magnusson
   Copyright (c) 2003-2007   Dana Jansens

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   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.

   See the COPYING file for a copy of the GNU General Public License.
*/

#include "openbox/plugin.h"
#include "openbox/openbox.h"
#include "openbox/screen.h"
#include "openbox/client.h"
#include "framerender.h"
#include "render/theme.h"
#include "frame_default_plugin.h"

static void framerender_label(ObDefaultFrame *self, RrAppearance *a);
static void framerender_icon(ObDefaultFrame *self, RrAppearance *a);
static void framerender_max(ObDefaultFrame *self, RrAppearance *a);
static void framerender_iconify(ObDefaultFrame *self, RrAppearance *a);
static void framerender_desk(ObDefaultFrame *self, RrAppearance *a);
static void framerender_shade(ObDefaultFrame *self, RrAppearance *a);
static void framerender_close(ObDefaultFrame *self, RrAppearance *a);

void framerender_frame(gpointer _self)
{
	ObDefaultFrame * self = (ObDefaultFrame *) _self;
    if (render_plugin->frame_iconify_animating(self))
        return; /* delay redrawing until the animation is done */
    if (!self->need_render)
        return;
    if (!self->visible)
        return;
    self->need_render = FALSE;

    {
        gulong px;

        px = (self->focused ?
              RrColorPixel(render_plugin->ob_rr_theme->cb_focused_color) :
              RrColorPixel(render_plugin->ob_rr_theme->cb_unfocused_color));

        XSetWindowBackground(render_plugin->ob_display, self->backback, px);
        XClearWindow(render_plugin->ob_display, self->backback);
        XSetWindowBackground(render_plugin->ob_display, self->innerleft, px);
        XClearWindow(render_plugin->ob_display, self->innerleft);
        XSetWindowBackground(render_plugin->ob_display, self->innertop, px);
        XClearWindow(render_plugin->ob_display, self->innertop);
        XSetWindowBackground(render_plugin->ob_display, self->innerright, px);
        XClearWindow(render_plugin->ob_display, self->innerright);
        XSetWindowBackground(render_plugin->ob_display, self->innerbottom, px);
        XClearWindow(render_plugin->ob_display, self->innerbottom);
        XSetWindowBackground(render_plugin->ob_display, self->innerbll, px);
        XClearWindow(render_plugin->ob_display, self->innerbll);
        XSetWindowBackground(render_plugin->ob_display, self->innerbrr, px);
        XClearWindow(render_plugin->ob_display, self->innerbrr);
        XSetWindowBackground(render_plugin->ob_display, self->innerblb, px);
        XClearWindow(render_plugin->ob_display, self->innerblb);
        XSetWindowBackground(render_plugin->ob_display, self->innerbrb, px);
        XClearWindow(render_plugin->ob_display, self->innerbrb);

        px = (self->focused ?
              RrColorPixel(render_plugin->ob_rr_theme->frame_focused_border_color) :
              RrColorPixel(render_plugin->ob_rr_theme->frame_unfocused_border_color));

        XSetWindowBackground(render_plugin->ob_display, self->left, px);
        XClearWindow(render_plugin->ob_display, self->left);
        XSetWindowBackground(render_plugin->ob_display, self->right, px);
        XClearWindow(render_plugin->ob_display, self->right);

        XSetWindowBackground(render_plugin->ob_display, self->titleleft, px);
        XClearWindow(render_plugin->ob_display, self->titleleft);
        XSetWindowBackground(render_plugin->ob_display, self->titletop, px);
        XClearWindow(render_plugin->ob_display, self->titletop);
        XSetWindowBackground(render_plugin->ob_display, self->titletopleft, px);
        XClearWindow(render_plugin->ob_display, self->titletopleft);
        XSetWindowBackground(render_plugin->ob_display, self->titletopright, px);
        XClearWindow(render_plugin->ob_display, self->titletopright);
        XSetWindowBackground(render_plugin->ob_display, self->titleright, px);
        XClearWindow(render_plugin->ob_display, self->titleright);

        XSetWindowBackground(render_plugin->ob_display, self->handleleft, px);
        XClearWindow(render_plugin->ob_display, self->handleleft);
        XSetWindowBackground(render_plugin->ob_display, self->handletop, px);
        XClearWindow(render_plugin->ob_display, self->handletop);
        XSetWindowBackground(render_plugin->ob_display, self->handleright, px);
        XClearWindow(render_plugin->ob_display, self->handleright);
        XSetWindowBackground(render_plugin->ob_display, self->handlebottom, px);
        XClearWindow(render_plugin->ob_display, self->handlebottom);

        XSetWindowBackground(render_plugin->ob_display, self->lgripleft, px);
        XClearWindow(render_plugin->ob_display, self->lgripleft);
        XSetWindowBackground(render_plugin->ob_display, self->lgriptop, px);
        XClearWindow(render_plugin->ob_display, self->lgriptop);
        XSetWindowBackground(render_plugin->ob_display, self->lgripbottom, px);
        XClearWindow(render_plugin->ob_display, self->lgripbottom);

        XSetWindowBackground(render_plugin->ob_display, self->rgripright, px);
        XClearWindow(render_plugin->ob_display, self->rgripright);
        XSetWindowBackground(render_plugin->ob_display, self->rgriptop, px);
        XClearWindow(render_plugin->ob_display, self->rgriptop);
        XSetWindowBackground(render_plugin->ob_display, self->rgripbottom, px);
        XClearWindow(render_plugin->ob_display, self->rgripbottom);

        /* don't use the separator color for shaded windows */
        if (!self->client->shaded)
            px = (self->focused ?
                  RrColorPixel(render_plugin->ob_rr_theme->title_separator_focused_color) :
                  RrColorPixel(render_plugin->ob_rr_theme->title_separator_unfocused_color));

        XSetWindowBackground(render_plugin->ob_display, self->titlebottom, px);
        XClearWindow(render_plugin->ob_display, self->titlebottom);
    }

    if (self->decorations & OB_FRAME_DECOR_TITLEBAR) {
        RrAppearance *t, *l, *m, *n, *i, *d, *s, *c, *clear;
        if (self->focused) {

            t = self->a_focused_title;
            l = self->a_focused_label;

            m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
            		render_plugin->ob_rr_theme->a_disabled_focused_max :
                 (self->client->max_vert || self->client->max_horz ?
                  (self->max_press ?
                		  render_plugin->ob_rr_theme->a_toggled_focused_pressed_max :
                   (self->max_hover ?
                		   render_plugin->ob_rr_theme->a_toggled_hover_focused_max :
                   render_plugin->ob_rr_theme->a_toggled_focused_unpressed_max)) :
                  (self->max_press ?
                		  render_plugin->ob_rr_theme->a_focused_pressed_max :
                   (self->max_hover ?
                		   render_plugin->ob_rr_theme->a_hover_focused_max :
                   render_plugin->ob_rr_theme->a_focused_unpressed_max))));
            n = self->a_icon;
            i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
            		render_plugin->ob_rr_theme->a_disabled_focused_iconify :
                 (self->iconify_press ?
                		 render_plugin->ob_rr_theme->a_focused_pressed_iconify :
                  (self->iconify_hover ?
                		  render_plugin->ob_rr_theme->a_hover_focused_iconify :
                  render_plugin->ob_rr_theme->a_focused_unpressed_iconify)));
            d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
            		render_plugin->ob_rr_theme->a_disabled_focused_desk :
                 (self->client->desktop == DESKTOP_ALL ?
                  (self->desk_press ?
                		  render_plugin->ob_rr_theme->a_toggled_focused_pressed_desk :
                   (self->desk_hover ?
                		   render_plugin->ob_rr_theme->a_toggled_hover_focused_desk :
                   render_plugin->ob_rr_theme->a_toggled_focused_unpressed_desk)) :
                  (self->desk_press ?
                		  render_plugin->ob_rr_theme->a_focused_pressed_desk :
                   (self->desk_hover ?
                		   render_plugin->ob_rr_theme->a_hover_focused_desk :
                   render_plugin->ob_rr_theme->a_focused_unpressed_desk))));
            s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
            		render_plugin->ob_rr_theme->a_disabled_focused_shade :
                 (self->client->shaded ?
                  (self->shade_press ?
                		  render_plugin->ob_rr_theme->a_toggled_focused_pressed_shade :
                   (self->shade_hover ?
                		   render_plugin->ob_rr_theme->a_toggled_hover_focused_shade :
                   render_plugin->ob_rr_theme->a_toggled_focused_unpressed_shade)) :
                  (self->shade_press ?
                		  render_plugin->ob_rr_theme->a_focused_pressed_shade :
                   (self->shade_hover ?
                		   render_plugin->ob_rr_theme->a_hover_focused_shade :
                   render_plugin->ob_rr_theme->a_focused_unpressed_shade))));
            c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
            		render_plugin->ob_rr_theme->a_disabled_focused_close :
                 (self->close_press ?
                		 render_plugin->ob_rr_theme->a_focused_pressed_close :
                  (self->close_hover ?
                		  render_plugin->ob_rr_theme->a_hover_focused_close :
                  render_plugin->ob_rr_theme->a_focused_unpressed_close)));
        } else {
            t = self->a_unfocused_title;
            l = self->a_unfocused_label;
            m = (!(self->decorations & OB_FRAME_DECOR_MAXIMIZE) ?
            		render_plugin->ob_rr_theme->a_disabled_unfocused_max :
                 (self->client->max_vert || self->client->max_horz ?
                  (self->max_press ?
                		  render_plugin->ob_rr_theme->a_toggled_unfocused_pressed_max :
                   (self->max_hover ?
                		   render_plugin->ob_rr_theme->a_toggled_hover_unfocused_max :
                   render_plugin->ob_rr_theme->a_toggled_unfocused_unpressed_max)) :
                  (self->max_press ?
                		  render_plugin->ob_rr_theme->a_unfocused_pressed_max :
                   (self->max_hover ?
                		   render_plugin->ob_rr_theme->a_hover_unfocused_max :
                   render_plugin->ob_rr_theme->a_unfocused_unpressed_max))));
            n = self->a_icon;
            i = (!(self->decorations & OB_FRAME_DECOR_ICONIFY) ?
            		render_plugin->ob_rr_theme->a_disabled_unfocused_iconify :
                 (self->iconify_press ?
                		 render_plugin->ob_rr_theme->a_unfocused_pressed_iconify :
                  (self->iconify_hover ?
                		  render_plugin->ob_rr_theme->a_hover_unfocused_iconify :
                  render_plugin->ob_rr_theme->a_unfocused_unpressed_iconify)));
            d = (!(self->decorations & OB_FRAME_DECOR_ALLDESKTOPS) ?
            		render_plugin->ob_rr_theme->a_disabled_unfocused_desk :
                 (self->client->desktop == DESKTOP_ALL ?
                  (self->desk_press ?
                		  render_plugin->ob_rr_theme->a_toggled_unfocused_pressed_desk :
                   (self->desk_hover ?
                		   render_plugin->ob_rr_theme->a_toggled_hover_unfocused_desk :
                   render_plugin->ob_rr_theme->a_toggled_unfocused_unpressed_desk)) :
                  (self->desk_press ?
                		  render_plugin->ob_rr_theme->a_unfocused_pressed_desk :
                   (self->desk_hover ?
                		   render_plugin->ob_rr_theme->a_hover_unfocused_desk :
                   render_plugin->ob_rr_theme->a_unfocused_unpressed_desk))));
            s = (!(self->decorations & OB_FRAME_DECOR_SHADE) ?
            		render_plugin->ob_rr_theme->a_disabled_unfocused_shade :
                 (self->client->shaded ?
                  (self->shade_press ?
                		  render_plugin->ob_rr_theme->a_toggled_unfocused_pressed_shade :
                   (self->shade_hover ?
                		   render_plugin->ob_rr_theme->a_toggled_hover_unfocused_shade :
                   render_plugin->ob_rr_theme->a_toggled_unfocused_unpressed_shade)) :
                  (self->shade_press ?
                		  render_plugin->ob_rr_theme->a_unfocused_pressed_shade :
                   (self->shade_hover ?
                		   render_plugin->ob_rr_theme->a_hover_unfocused_shade :
                   render_plugin->ob_rr_theme->a_unfocused_unpressed_shade))));
            c = (!(self->decorations & OB_FRAME_DECOR_CLOSE) ?
            		render_plugin->ob_rr_theme->a_disabled_unfocused_close :
                 (self->close_press ?
                		 render_plugin->ob_rr_theme->a_unfocused_pressed_close :
                  (self->close_hover ?
                		  render_plugin->ob_rr_theme->a_hover_unfocused_close :
                  render_plugin->ob_rr_theme->a_unfocused_unpressed_close)));
        }
        clear = render_plugin->ob_rr_theme->a_clear;

        RrPaint(t, self->title, self->width, render_plugin->ob_rr_theme->title_height);

        clear->surface.parent = t;
        clear->surface.parenty = 0;

        clear->surface.parentx = render_plugin->ob_rr_theme->grip_width;

        RrPaint(clear, self->topresize,
                self->width - render_plugin->ob_rr_theme->grip_width * 2,
                render_plugin->ob_rr_theme->paddingy + 1);

        clear->surface.parentx = 0;

        if (render_plugin->ob_rr_theme->grip_width > 0)
            RrPaint(clear, self->tltresize,
            		render_plugin->ob_rr_theme->grip_width, render_plugin->ob_rr_theme->paddingy + 1);
        if (render_plugin->ob_rr_theme->title_height > 0)
            RrPaint(clear, self->tllresize,
            		render_plugin->ob_rr_theme->paddingx + 1, render_plugin->ob_rr_theme->title_height);

        clear->surface.parentx = self->width - render_plugin->ob_rr_theme->grip_width;

        if (render_plugin->ob_rr_theme->grip_width > 0)
            RrPaint(clear, self->trtresize,
            		render_plugin->ob_rr_theme->grip_width, render_plugin->ob_rr_theme->paddingy + 1);

        clear->surface.parentx = self->width - (render_plugin->ob_rr_theme->paddingx + 1);

        if (render_plugin->ob_rr_theme->title_height > 0)
            RrPaint(clear, self->trrresize,
            		render_plugin->ob_rr_theme->paddingx + 1, render_plugin->ob_rr_theme->title_height);

        /* set parents for any parent relative guys */
        l->surface.parent = t;
        l->surface.parentx = self->label_x;
        l->surface.parenty = render_plugin->ob_rr_theme->paddingy;

        m->surface.parent = t;
        m->surface.parentx = self->max_x;
        m->surface.parenty = render_plugin->ob_rr_theme->paddingy + 1;

        n->surface.parent = t;
        n->surface.parentx = self->icon_x;
        n->surface.parenty = render_plugin->ob_rr_theme->paddingy;

        i->surface.parent = t;
        i->surface.parentx = self->iconify_x;
        i->surface.parenty = render_plugin->ob_rr_theme->paddingy + 1;

        d->surface.parent = t;
        d->surface.parentx = self->desk_x;
        d->surface.parenty = render_plugin->ob_rr_theme->paddingy + 1;

        s->surface.parent = t;
        s->surface.parentx = self->shade_x;
        s->surface.parenty = render_plugin->ob_rr_theme->paddingy + 1;

        c->surface.parent = t;
        c->surface.parentx = self->close_x;
        c->surface.parenty = render_plugin->ob_rr_theme->paddingy + 1;

        framerender_label(self, l);
        framerender_max(self, m);
        framerender_icon(self, n);
        framerender_iconify(self, i);
        framerender_desk(self, d);
        framerender_shade(self, s);
        framerender_close(self, c);
    }

    if (self->decorations & OB_FRAME_DECOR_HANDLE &&
    		render_plugin->ob_rr_theme->handle_height > 0)
    {
        RrAppearance *h, *g;

        h = (self->focused ?
             self->a_focused_handle : self->a_unfocused_handle);

        RrPaint(h, self->handle, self->width, render_plugin->ob_rr_theme->handle_height);

        if (self->decorations & OB_FRAME_DECOR_GRIPS) {
            g = (self->focused ?
            		render_plugin->ob_rr_theme->a_focused_grip : render_plugin->ob_rr_theme->a_unfocused_grip);

            if (g->surface.grad == RR_SURFACE_PARENTREL)
                g->surface.parent = h;

            g->surface.parentx = 0;
            g->surface.parenty = 0;

            RrPaint(g, self->lgrip,
            		render_plugin->ob_rr_theme->grip_width, render_plugin->ob_rr_theme->handle_height);

            g->surface.parentx = self->width - render_plugin->ob_rr_theme->grip_width;
            g->surface.parenty = 0;

            RrPaint(g, self->rgrip,
            		render_plugin->ob_rr_theme->grip_width, render_plugin->ob_rr_theme->handle_height);
        }
    }

    XFlush(render_plugin->ob_display);
}

static void framerender_label(ObDefaultFrame *self, RrAppearance *a)
{
    if (!self->label_on) return;
    /* set the texture's text! */
    a->texture[0].data.text.string = self->client->title;
    RrPaint(a, self->label, self->label_width, render_plugin->ob_rr_theme->label_height);
}

static void framerender_icon(ObDefaultFrame *self, RrAppearance *a)
{
    const ObClientIcon *icon;

    if (!self->icon_on) return;

    icon = client_icon(self->client,
    		render_plugin->ob_rr_theme->button_size + 2,
    		render_plugin->ob_rr_theme->button_size + 2);
    if (icon) {
        a->texture[0].type = RR_TEXTURE_RGBA;
        a->texture[0].data.rgba.width = icon->width;
        a->texture[0].data.rgba.height = icon->height;
        a->texture[0].data.rgba.alpha = 0xff;
        a->texture[0].data.rgba.data = icon->data;
    } else
        a->texture[0].type = RR_TEXTURE_NONE;

    RrPaint(a, self->icon,
    		render_plugin->ob_rr_theme->button_size + 2, render_plugin->ob_rr_theme->button_size + 2);
}

static void framerender_max(ObDefaultFrame *self, RrAppearance *a)
{
    if (!self->max_on) return;
    RrPaint(a, self->max, render_plugin->ob_rr_theme->button_size, render_plugin->ob_rr_theme->button_size);
}

static void framerender_iconify(ObDefaultFrame *self, RrAppearance *a)
{
    if (!self->iconify_on) return;
    RrPaint(a, self->iconify,
    		render_plugin->ob_rr_theme->button_size, render_plugin->ob_rr_theme->button_size);
}

static void framerender_desk(ObDefaultFrame *self, RrAppearance *a)
{
    if (!self->desk_on) return;
    RrPaint(a, self->desk, render_plugin->ob_rr_theme->button_size, render_plugin->ob_rr_theme->button_size);
}

static void framerender_shade(ObDefaultFrame *self, RrAppearance *a)
{
    if (!self->shade_on) return;
    RrPaint(a, self->shade,
    		render_plugin->ob_rr_theme->button_size, render_plugin->ob_rr_theme->button_size);
}

static void framerender_close(ObDefaultFrame *self, RrAppearance *a)
{
    if (!self->close_on) return;
    RrPaint(a, self->close,
    		render_plugin->ob_rr_theme->button_size, render_plugin->ob_rr_theme->button_size);
}
