# vPresent is an immersive presentation creation and display application.
# Copyright (C) 2007-2008 by Infiscape Corporation
#
# 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.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

from PyQt4 import QtCore


class Node(QtCore.QObject):
   # This is the default port for the initial connection that vPresent makes
   # to each node of the cluster in order to deliver configuration
   # information and other data before the OpenSG clustering starts up.
   sDefaultPort = 10145

   def __init__(self, name, address = "", port = None, parent = None):
      QtCore.QObject.__init__(self, parent)

      if port is None:
         port = self.sDefaultPort

      self.name    = name
      self.address = address
      self.port    = port
      self.pipes   = PipeList(self)

   def getDefaultPort():
      return Node.sDefaultPort

   getDefaultPort = staticmethod(getDefaultPort)

   def getName(self):
      return self.name

   def setName(self, name):
      if self.name != name:
         self.name = name
         self.emit(QtCore.SIGNAL("nameChanged()"))

   def getAddress(self):
      return self.address

   def setAddress(self, address):
      if self.address != address:
         self.address = address
         self.emit(QtCore.SIGNAL("addressChanged()"))

   def getPort(self):
      return self.port

   def setPort(self, port):
      if self.port != port:
         self.port = port
         self.emit(QtCore.SIGNAL("portChanged()"))

   def addPipe(self, pipe):
      self.pipes.append(pipe)

   def insertPipe(self, index, pipe):
      self.pipes.insert(index, pipe)

   def removePipe(self, index):
      pipe = self.pipes[index]
      del self.pipes[index]

   def getPipe(self, index):
      return self.pipes[index]

   def getPipes(self):
      return self.pipes

class PipeList(QtCore.QObject):
   '''
   This class represents a collection of graphics pipes for a cluster node as
   a sequence of cluster.display.Pipe objects. The interface for this class
   mimics a Python sequence, which makes its use convenient. Internally, Qt
   signals are emitted when the data changes, which makes it well-behaved in
   the context of a GUI.
   '''

   def __init__(self, parent = None):
      QtCore.QObject.__init__(self, parent)
      self.pipes = []

   def append(self, pipe):
      self.pipes.append(pipe)
      self.emit(QtCore.SIGNAL("pipeAdded(QObject*)"), pipe)

   def insert(self, index, pipe):
      self.pipes.insert(index, pipe)
      self.emit(QtCore.SIGNAL("pipeInserted(int,QObject*)"), index, pipe)

   def extend(self, iterable):
      self.pipes.extend(iterable)
      for n in iterable:
         self.emit(QtCore.SIGNAL("pipeAdded(QObject*)"), n)

   def remove(self, pipe):
      index = self.pipes.index(pipe)
      self.pipes.remove(pipe)
      self.emit(QtCore.SIGNAL("pipeRemoved(int,QObject*)"), index, pipe)

   def count(self, pipe):
      return self.pipes.count(pipe)

   def index(self, pipe):
      return self.pipes.index(pipe)

   def pop(self, index = None):
      if index is None:
         index = len(self.pipes) - 1

      pipe = self.pipes.pop(index)

      if pipe is not None:
         self.emit(QtCore.SIGNAL("pipeRemoved(int,QObject*)"), index, pipe)

      return pipe

   def reverse(self):
      self.pipes.reverse()
      self.emit(QtCore.SIGNAL("pipesSorted()"))

   def sort(self, cmpfunc = None):
      self.pipes.sort(cmpfunc)
      self.emit(QtCore.SIGNAL("pipesSorted()"))

   def __len__(self):
      return len(self.pipes)

   def __getitem__(self, index):
      return self.pipes[index]

   def __setitem__(self, index, pipe):
      old_pipe = self.pipes[index]
      self.pipes[index] = pipe
      self.emit(QtCore.SIGNAL("pipeChanged(int,QObject*,QObject*)"), index,
                old_pipe, pipe)

   def __delitem__(self, index):
      pipe = self.pipes[index]
      del self.pipes[index]
      self.emit(QtCore.SIGNAL("pipeRemoved(int,QObject*)"), index, pipe)

   def __iter__(self):
      return self.pipes.__iter__()

   def __contains__(self, item):
      return item in self.pipes

   def __add__(self, l):
      self.pipes.__add__(l)
      for n in l:
         self.emit(QtCore.SIGNAL("pipeAdded(QObject*)"), n)

   def __iadd__(self, l):
      self.pipes.__iadd__(l)
      for n in l:
         self.emit(QtCore.SIGNAL("pipeAdded(QObject*)"), n)

   def __mul__(self, l):
      self.pipes.__mul__(l)
      print "??? What signal to emit ???"

   def __imul__(self, l):
      self.pipes.__imul__(l)
      print "??? What signal to emit ???"

   def __getslice__(self, i, j):
      return self.pipes[i:j]

   def __str__(self):
      return str(self.pipes)
