#!/usr/bin/env python

import sys
from qt import *

seed = 0.353535353535
KINDA_RAND_MAX = 32767

def kindaRand():
  global seed
  seed = seed * 147
  seed = seed - int(seed)
  return int(seed*(KINDA_RAND_MAX + 1))

velmax = 15
velmin = 4

def velocity(i):
  if i == 1 or i == 2:
    i = (kindaRand()&0x7fff % velmax)/3 + velmin
  else:
    i = (kindaRand()&0x7fff % velmax) + velmin
  return i

maxpoints = 5
maxcurves = 8

def poly():
  d = QApplication.desktop()
  d.setEraseColor(Qt.white)
  xvel = [ 0 ] * maxpoints
  yvel = [ 0 ] * maxpoints
  head = 0
  tail = -maxcurves + 2
  a = [ QPointArray() ] * maxcurves
  r = d.rect()
  for i in range(maxcurves):
    a[i].resize(maxpoints)
  p = a[0]
  for i in range(maxpoints):
    p.setPoint(i, (kindaRand()&0x7fff) % r.width(),
                  (kindaRand()&0x7fff) % r.height() )
    xvel[i] = velocity(i)
    yvel[i] = velocity(i)

  paint = QPainter()
  paint.begin(d)

  for ntimes in range(2000):
    paint.setBrush(QColor(kindaRand()%360,180,255, QColor.Hsv))
    paint.drawPolygon(a[head])
    tail = tail + 1
    if tail >= maxcurves:
      tail = 0
    minx = r.left()
    maxx = r.right()
    miny = r.top()
    maxy = r.bottom()
    p = a[head]
    head = head + 1
    if head >= maxcurves:
      head = 0
    for i in range(maxpoints):
      x, y = p.point(i)
      x = x + xvel[i]
      y = y + yvel[i]
      if x >= maxx:
        x = maxx - (x - maxx + 1)
        xvel[i] = -velocity(i)
      if x <= minx:
        x = minx + (minx - x + 1)
        xvel[i] = velocity(i)
      if y >= maxy:
        y = maxy - (y - maxy + 1)
        yvel[i] = -velocity(i)
      if y <= miny:
        y = miny + (miny - y + 1)
        yvel[i] = velocity(i)
      a[head].setPoint(i, x, y)
  paint.end()

def rotate():
  w = 64
  h = 64
  image = QImage(w, h, 8, 128)
  for i in range(128):
    image.setColor(i, qRgb(i,0,0))
  for y in range(h):
    for x in range(w):
      image.setPixel(x,y,(x+y)%128)
  
  pm = QPixmap()
  pm.convertFromImage(image)
  pm.setOptimization(QPixmap.BestOptim)

  d = QApplication.desktop()

  for i in range(0,361,2):
    m = QWMatrix()
    m.rotate(i)
    rpm = pm.xForm(m)
    d.setErasePixmap(rpm)
    d.update()

def generateStone(pm, c1, c2, c3):
  p = QPainter()
  p1 = QPen(c1, 0)
  p2 = QPen(c2, 0)
  p3 = QPen(c3, 0)

  p.begin(pm)
  for i in range(pm.width()):
    for j in range(pm.height()):
      r = kindaRand()
      if r < KINDA_RAND_MAX / 3:
        p.setPen(p1)
      elif r < KINDA_RAND_MAX / 3 * 2:
        p.setPen(p2)
      else:
        p.setPen(p3)
      p.drawPoint(i, j)
  p.end()

def drawShadeText(p, x, y, text, topColor, bottomColor, sw=2):
  if not p.isActive():
    return

  p.setPen(bottomColor)
  p.drawText(x+sw, y+sw, text)
  p.setPen(topColor)
  p.drawText(x, y, text)

class DesktopWidget(QWidget):
  def __init__(self, s, parent=None, name=''):
    QWidget.__init__(self, parent, name, Qt.WType_Desktop | Qt.WPaintDesktop)
    self.text = s
    self.pm = None

  def paintEvent(self, pe):
    c1 = self.eraseColor()
    c2 = c1.light(104)
    c3 = c1.dark(106)
    if not self.pm:
      self.pm = QPixmap(64, 64)
      generateStone(self.pm, c1, c2, c3)
      self.setErasePixmap(self.pm)
      self.update()
    br = self.fontMetrics().boundingRect(self.text)
    offscreen = QPixmap(br.width(), br.height())
    x = self.width()/2 - br.width()/2
    y = self.height()/2 - br.height()/2
    offscreen.fill(self, x, y)
    p = QPainter()
    p.begin(offscreen)
    drawShadeText(p, -br.x(), -br.y(), self.text, c2, c3, 3)
    p.end()
    bitBlt(self, x, y, offscreen)

def desktopWidget(s='Trolltech'):
  t = DesktopWidget(s)
  t.update()
  qApp.exec_loop()

def desktopText(s='Trolltech'):
  border = 20

  c1 = qApp.palette().normal().background()
  c2 = c1.light(104)
  c3 = c1.dark(106)

  pm = QPixmap(10, 10)
  p = QPainter()
  p.begin(pm)
  r = p.fontMetrics().boundingRect(s)
  p.end()

  appWidth = qApp.desktop().width()
  appHeight = qApp.desktop().height()
  if r.width() > appWidth - border*2:
    r.setWidth(appWidth - border*2)
  if r.height() > appHeight - border*2:
    r.setHeight(appHeight - border*2)

  pm.resize(r.size().width()+border*2,r.size().height()+border*2)
  generateStone(pm, c1, c2, c3)
  p.begin(pm)
  drawShadeText(p, -r.x()+border, -r.y()+border, s, c2, c3)
  p.end()

  qApp.desktop().setErasePixmap(pm)

a = QApplication(sys.argv)
if len(sys.argv) > 1:
  f = QFont('charter', 96, QFont.Black)
  f.setStyleHint(QFont.Times)
  a.setFont(f)

validOptions = 0

if len(sys.argv) == 2:
  validOptions = 1
  if sys.argv[1] == '-poly':
    poly()
  elif sys.argv[1] == '-rotate':
    rotate()
  elif sys.argv[1] == '-troll':
    desktopText()
  elif sys.argv[1] == '-trollwidget':
    desktopWidget()
  else:
    validOptions = 0

if len(sys.argv) == 3:
  validOptions = 1
  if sys.argv[1] == '-shadetext':
    desktopText(sys.argv[2])
  elif sys.argv[1] == '-shadewidget':
    desktopWidget(sys.argv[2])
  else:
    validOptions = 0

if not validOptions:
  print """Usage:
\tdesktop -poly
\tdesktop -rotate
\tdesktop -troll
\tdesktop -trollwidget
\tdesktop -shadetext <text>
\tdesktop -shadewidget <text>"""
  rotate()
