from javax.swing import JFrame, JTabbedPane, JComponent, JToolBar, JPanel
from java.awt import GraphicsEnvironment, Toolkit, Container, BorderLayout
from java.lang import Double
from java.util import ResourceBundle

__ALL__=['Frame', 'TabbedPanel']

class Localizer:
    def __init__(self, basename):
        self.loc = ResourceBundle.getBundle(basename)
        
    def __getitem__(self, key):
        return self.loc.getString(key)
    
loc = Localizer('gee.display')

class JavaBeanSetHandler:
    def __setattr__(self, name, value):
        setterName =  'set%s' % (name[0].upper() + name[1:])
        if hasattr(self, setterName):
            getattr(self, setterName)(value)
        else:
            self.__dict__[name] = value
            
class SwingPyContainerMethods:

    def __getattr__(self, name):
        if name == 'container':
            if hasattr(self, 'swingContainer') and not self.swingContainer is None:
                return self.swingContainer
            else:
                return self
        raise AttributeError('No such attribute %s' % name)
    
    def __len__(self):
        return self.container.componentCount

    def __getitem__(self, key):
        if hasattr(key, 'start') and hasattr(key, 'stop'):
            return ArrayIter(self.container.components, key.start, key.stop)
        if key < 0:
            key = len(self) + key
        if key >= len(self):
            raise IndexError
        return self.container.getComponent(key)
    
    def __setitem__(self, key, value):
        del self[key]
        self.container.addImpl(value, None, key)
        
    def __iter__(self, start=0, stop=None):
        return ArrayIter(self.container.components, start, stop)
    
    def __delitem__(self, key):
        self.container.remove(key)
        
class ArrayIter:
    def __init__(self, array, start=0, stop=None):
        self.array = array
        self.pos = start
        if stop is None: stop = len(array)
        self.stop = stop
        
    def __iter__(self):
        return self
    
    def next(self):
        if self.stop == self.pos:
            raise StopIteration
        result = self.array[self.pos]
        self.pos += 1
        return result

def scaleInt(i, factor):
    return Double(i * factor).intValue()
    
class Frame(JFrame, JavaBeanSetHandler):
    visibleIfContentGiven=True
    
    def __init__(self, content=None, title=None, graphicsConfiguration=None):
        if not title:
            title = loc['default_frame_name']
        if graphicsConfiguration:
            JFrame.__init__(self, title, graphicsConfiguration)
        else:
            JFrame.__init__(self, title)
        if content: 
            self.content = content
            self.scaleAndPlace()
            self.visible = Frame.visibleIfContentGiven
            

    def setContent(self, value):
        self.contentPane = value
    
    def scaleAndPlace(self):
        size = self.graphicsConfiguration.bounds
        tk = Toolkit.getDefaultToolkit()
        insets = tk.getScreenInsets(self.graphicsConfiguration)
        usableSize = (size.width - (insets.left + insets.right), size.height - (insets.top + insets.bottom))
        HEIGHT_USAGE = .8
        WIDTH_USAGE = .8
        self.setSize(scaleInt(usableSize[0], WIDTH_USAGE), scaleInt(usableSize[1], HEIGHT_USAGE))
        self.setLocation(insets.left + scaleInt(usableSize[0], (1 - WIDTH_USAGE)/2),
                         insets.top + scaleInt(usableSize[0], (1 - HEIGHT_USAGE)/2))
            
    def __getattr__(self, name):
        if name == 'content': return self.contentPane
        raise AttributeError('No such attribute %s' % name)
        
class TabbedPanel(JPanel, JavaBeanSetHandler, SwingPyContainerMethods):
    """A panel that holds multiple components in tabs.
    
    If it contains only one component, that component is given all of the TabbedPanel's screen
    real estate.  The addition of a second component adds the tab bar and both components are added
    to it.
    """
    def __init__(self, contents=[]):
        """Create a TabbedPanel.
        
        Keyword arguments:
        contents -- either a single JComponent or a list of them to be added to the panel
        """
        JPanel.__init__(self, BorderLayout())
        self.swingContainer = None
        if isinstance(contents, JComponent):
            self.add(contents)
        else:
            for comp in contents: 
                self.add(comp)
    
    def addImpl(self, component, constraint, index):
        if self.swingContainer is None:
            if len(self) == 0:
                self.super__addImpl(component, constraint, index)
            else:
                curcomp = self[0]
                JPanel.remove(self, 0)
                self.swingContainer = JTabbedPane()
                self.super__addImpl(self.swingContainer, None, 0)
                self.swingContainer.add(curcomp)
                self.swingContainer.add(component)
        else:
            self.swingContainer.add(component)

    def remove(self, item):
        if self.swingContainer is None:
            JPanel.remove(self, item)
        elif item is self.swingContainer:
            JPanel.remove(self, 0)
            self.swingContainer = None
        else:
            self.swingContainer.remove(item)
            if len(self) == 1:
                self[0] = self.swingContainer.getComponent(0)
    
class Toolbar(JToolBar, JavaBeanSetHandler, SwingPyContainerMethods):
    def __init__(self, contents=[], defaultGroup='default'):
        JToolBar.__init__(self)
        self.floatable = False
        self.groups = [defaultGroup]
        if isinstance(contents, JComponent):
            self.add(contents)
        else: 
            for item in contents: self.add(item)
            
    def __getitem__(self, key):
        if isinstance(key, str):
            groupIndex = self.groups.index(key)
            return SwingPyContainerMethods.__iter__(self, 
                                                      self._firstGroupComponentIndex(groupIndex),
                                                      self._firstGroupComponentIndex(groupIndex + 1) - 1)
        else:
            return SwingPyContainerMethods.__getitem__(self, key)
    
    def _firstGroupComponentIndex(self, groupIndex):
        if groupIndex == 0: return 0
        groupsFound = 0
        for index, comp in enumerate(self):
            if isinstance(comp, JToolBar.Separator):
                groupsFound += 1
                if groupsFound == groupIndex:
                    return index + 1
        return len(self) + 1
                
    def add(self, item, group=None):
        if group is None:
            group = self.groups[0]
        if not group in self.groups:
            #programatically create Separator as addSeparator just calls add internally
            self.addImpl(JToolBar.Separator(), group, -1)
            self.groups.append(group)
            self.addImpl(item, group, -1)
        else:
            index = self._firstGroupComponentIndex(self.groups.index(group) + 1) - 1
            self.addImpl(item, group, index)
        return item        