#!/usr/bin/env python
# --------------------------------------------
# reshape - Reshape current desktop windows to show 'em all
# --------------------------------------------
# Module:    reshape
# File:      reshape
# Author:    Lluis Vilanova <xscript@gmx.net>
# CVS Id:    $Id: $
#
# Copyright (C) 2007, Lluis Vilanova <xscript@gmx.net> {{{
#
# 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.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
# }}}

import wnck
import math

class Geometry:
    def __init__ (self, width, height):
        self.xoff = 0
        self.yoff = 0
        self.width = width
        self.height = height


class Workspace:
    def __init__ (self, workspacen=None):
        screen = wnck.screen_get_default()
        screen.force_update()
        if workspacen != None:
            workspace = screen.get_workspace(workspacen)
        else:
            workspace = screen.get_active_workspace()
        windows = screen.get_windows()

        self.geometry = Geometry(workspace.get_width(),workspace.get_height())
        self.windows = []

        for window in windows:
            if window.get_window_type() == wnck.WINDOW_DOCK:
                (xoff,yoff,xsize,ysize) = window.get_geometry()
                if xsize < self.geometry.width:
                    self.geometry.width -= xsize
                    if xoff == 0:
                       self. geometry.xoff += xsize
                if ysize < self.geometry.height:
                    self.geometry.height -= ysize
                    if yoff == 0:
                        self.geometry.yoff += ysize
            elif window.get_workspace() == workspace:
                self.windows.append(window)


class ReshapeParams:
    def __init__ (self, reshaper):
        self.width  = reshaper.workspace.geometry.width  / reshaper.ncols
        self.height = reshaper.workspace.geometry.height / reshaper.nrows
        self.xpos = reshaper.workspace.geometry.xoff
        self.ypos = reshaper.workspace.geometry.yoff
        self.col = 0
        self.row = 0
        self.reshaper = reshaper
        self.count = 1

    def recompute (self):
        nwleft = len(self.reshaper.workspace.windows) - self.count
        if self.reshaper.firstrows:
            self.row += 1
            if self.row == self.reshaper.nrows:
                self.row  = 0
                self.col += 1
                if self.col == self.reshaper.ncols - 1:
                    self.height = int(self.reshaper.workspace.geometry.height / nwleft)
        else:
            self.col += 1
            if self.col == self.reshaper.ncols:
                self.col  = 0
                self.row += 1
                if self.row == self.reshaper.nrows - 1:
                    self.width = int(self.reshaper.workspace.geometry.width / nwleft)
        self.xpos = (self.col * self.width) + self.reshaper.workspace.geometry.xoff
        self.ypos = (self.row * self.height) + self.reshaper.workspace.geometry.yoff
        self.count += 1


class Reshaper:
    def __init__ (self, workspace=None, firstrows=True):
        if workspace == None:
            self.workspace = Workspace()
        else:
            self.workspace = Workspace(workspace)
        self.firstrows = firstrows

        nwindows = len(self.workspace.windows)

        if self.firstrows:
            self.nrows = int(math.floor(math.sqrt(nwindows)))
            self.ncols = nwindows / self.nrows
        else:
            self.ncols = int(math.floor(math.sqrt(nwindows)))
            self.nrows = nwindows / self.ncols

    def reshape (self):
        params = ReshapeParams(self)

        gravity = wnck.WINDOW_GRAVITY_CURRENT
        geomask = wnck.WINDOW_CHANGE_HEIGHT | wnck.WINDOW_CHANGE_WIDTH | wnck.WINDOW_CHANGE_X | wnck.WINDOW_CHANGE_Y

        for window in self.workspace.windows:
            print window, params.xpos, params.ypos, params.width, params.height
            window.set_geometry(gravity, geomask, params.xpos, params.ypos, params.width, params.height)
            params.recompute()



def main ():
    reshaper = Reshaper()
    reshaper.reshape()



if __name__ == "__main__":
    main()

# vim:set ts=4 sw=4 tw=80 foldmethod=marker expandtab:
