#!BPY

"""
Name: 'PDB_ChemFiles'
Blender: 248
Group: 'Misc'
Tooltip: 'Open PDB Chemical files.'
"""

__author__ = 'Malte Reimold'
__version__ = '1.2'
__url__ = ("http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Import/PDB2")

__bpydoc__ = """\
pdb Molecule 2 Blender 3d Model Converter

Modes: 

1. Ball

creates a ball model with overlapping spheres when using the standard parameters

the ball sizes can be adjusted by choosing a constant scaling factor (atom scale)

as well as a constant summand (atom sum) that is added to the ball size. 

With atom scale = 1	and atom sum = 0 one will get the covalent radius for any atom defined.

With atom scale = 0 and atom sum > 0 the model will have uniform ball sizes.

2. Sticks

creates a stick model. 

The stick diameter can be chosen here (Stick Thickness).

Until now the regular stick mode (as well as stick and ball) does only work for less than 

10000 atoms.

3. Sticks and Balls

A combination of ball and stick mode. When using standard parameters the atoms are scaled 

down a little bit.

4. DNA Backbone Follow

When turning on this option a stick model will be formed connecting the phosphorous atoms 

of oligonucleotide backbones.

This works even for systems with more than 10000 atoms.

Model refinement:

The refinement of spheres and sticks can be chosen.

With higher values the model becomes more detailed.

The pdb 2 blender converter is still experimental. Please report problems and errors to me.

Version History:
v1.2 Fixed some problems concerning pdb-file conventions. 
v1.1 Fixed some minor bugs.

"""

####################################################
#Copyright (C) 2008: Malte Reimold
####################################################
#-------------GPL LICENSE BLOCK-------------
#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 3 of the License, or
#(at your option) any later version.
#
#This program is distributed in the hopes 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.
####################################################


import Blender
from Blender import *
from Blender.Draw import *
from math import *


editmode = Window.EditMode()
if editmode: Window.EditMode(0)
scene = Blender.Scene.GetCurrent ()

matlist = str(Material.Get ())

if not ('[Material "C"]' in matlist):
	mat = Material.New('C')
	mat.R = 0.8
	mat.G = 0.8
	mat.B = 0.8

if not ('[Material "H"]' in matlist):
	mat = Material.New('H')
	mat.R = 0.6
	mat.G = 0.6
	mat.B = 0.6
	
if not ('[Material "B"]' in matlist):
	mat = Material.New('B')
	mat.R = 0.8
	mat.G = 0.6
	mat.B = 0.1
	
if not ('[Material "P"]' in matlist):
	mat = Material.New('P')
	mat.R = 0.9
	mat.G = 0.95
	mat.B = 0.1
	
if not ('[Material "N"]' in matlist):
	mat = Material.New('N')
	mat.R = 0.2
	mat.G = 0.1
	mat.B = 0.9
	
if not ('[Material "O"]' in matlist):
	mat = Material.New('O')
	mat.R = 1.0
	mat.G = 0.2
	mat.B = 0.1
	
if not ('[Material "anyatom"]' in matlist):
	mat = Material.New('anyatom')
	mat.R = 0.8
	mat.G = 1.0
	mat.B = 1.0
	
if not ('[Material "sticks"]' in matlist):
	mat = Material.New('sticks')
	mat.R = 0.8
	mat.G = 0.8
	mat.B = 0.8


def ball(name, type, x, y, z):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	# Objekt erstellen
	ob = Object.New('Mesh', name)
	# Mesh erstellen
	me = Mesh.New(name)
	# Ball erstellen
	a = 0.0000	
	b = 0.0000
	vcount = 0
	da = 360.00 / refineballs.val
	db = 360.00 / refineballs.val
	#da = 30.0
	#db = 30.0
	dx = 0.0
	dy = 0.0
	dz = 0.0
	pi = asin(1)
	if type == "C":	
		radius = 0.772
		mat = Material.Get('C')
	elif type == "H": 
		radius = 0.373
		mat = Material.Get('H')
	elif type == "B": 
		radius = 0.83
		mat = Material.Get('B')
	elif type == "N": 
		radius = 0.71
		mat = Material.Get('N')
	elif type == "O": 
		radius = 0.604
		mat = Material.Get('O')
	elif type == "P": 
		radius = 0.93
		mat = Material.Get('P')
	else: 
		radius = 0.8
		mat = Material.Get('anyatom')
		
	me.materials = [mat]
	
	radius = radius * scatom.val + sumatom.val
	
	
	# erster Punkt
	me.verts.extend(0, 0, radius)
	a = a + da
	
	# Kappe
		
	while b < 360:
		dz = radius*cos(a/90*pi)
		dx = radius*sin(a/90*pi)*sin(b/90*pi)
		dy = radius*sin(a/90*pi)*cos(b/90*pi)
		b = b + db
		me.verts.extend(dx, dy, dz)
		vcount = vcount + 1
		if vcount > 1:
			me.faces.extend([me.verts[0],me.verts[vcount],me.verts[vcount-1]])
	
	me.faces.extend([me.verts[0],me.verts[1],me.verts[vcount]])
	
	b = 0.00
	kcount = 0
	vvcount = 0
	a = a + da
	
	
	while a < 180:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0
		vvcount = 0
		a = a + da
		
	# letzter Punkt
	me.verts.extend(0, 0, -radius)
	vcount = vcount + 1
	b = 0
	while b < 360-db:
		me.faces.extend([me.verts[vcount],me.verts[vcount-int(b/db)-2],me.verts[vcount-int(b/db)-1]])
		b = b + db
	
	me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int((360-db)/db)-1]])
	eins = 1
	for face in me.faces:
		face.smooth=1
	

	ob.link (me)
	ob.loc = (x,y,z)
	scene.link (ob)
	
def stick1(x1, y1, z1, x2, y2, z2, radius):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	# Objekt erstellen
	ob = Object.New('Mesh')
	# Mesh erstellen
	me = Mesh.New()
	mat = Material.Get('sticks')
	me.materials = [mat]
	# Stick erstellen
	a = 0.0000	
	b = 0.0000
	vcount = 0
	da = 360.00 / refinesticks.val
	db = 360.00 / refinesticks.val
	dx = 0.0
	dy = 0.0
	dz = 0.0
	pi = asin(1)
	laenge = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))
	wsz = atan2((y1-y2), (x1-x2))
	wz = acos((z1-z2)/laenge)
	
	
	# erster Punkt
	me.verts.extend(0, 0, laenge/2+radius)
	a = a + da
	
	# Kappe
		
	while b < 360:
		dz = radius*cos(a/90*pi)
		dx = radius*sin(a/90*pi)*sin(b/90*pi)
		dy = radius*sin(a/90*pi)*cos(b/90*pi)
		b = b + db
		me.verts.extend(dx, dy, dz+laenge/2)
		vcount = vcount + 1
		if vcount > 1:
			me.faces.extend([me.verts[0],me.verts[vcount],me.verts[vcount-1]])
	
	me.faces.extend([me.verts[0],me.verts[1],me.verts[vcount]])
	
	b = 0.00
	kcount = 0
	vvcount = 0
	a = a + da
	
	
	while a < 90:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz+laenge/2)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0
		vvcount = 0
		a = a + da
		
	a = 90
	b = 0.00
	vvcount = 0
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, laenge/2)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0.00
	vvcount = 0	
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, -laenge/2)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0.00
	vvcount = 0	
	
	while a < 180:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz-laenge/2)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0.00
		vvcount = 0
		a = a + da
		
	# letzter Punkt
	me.verts.extend(0, 0, -laenge/2-radius)
	vcount = vcount + 1
	b = 0
	while b < 360-db:
		me.faces.extend([me.verts[vcount],me.verts[vcount-int(b/db)-2],me.verts[vcount-int(b/db)-1]])
		b = b + db
	
	me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int((360-db)/db)-1]])
	eins = 1
	for face in me.faces:
		face.smooth=1
	
	
	ob.link (me)
	x1 = float(x1)
	y1 = float(y1)
	z1 = float(z1)
	x2 = float(x2)
	y2 = float(y2)
	z2 = float(z2)
	ob.loc = (float(x1+x2)/2,(y1+y2)/2,(z1+z2)/2)
	ob.RotY = wz
	ob.RotZ = wsz
	scene.link (ob)

def stick2(x1, y1, z1, x2, y2, z2, radius):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	# Objekt erstellen
	ob = Object.New('Mesh')
	# Mesh erstellen
	me = Mesh.New()
	mat = Material.Get('sticks')
	me.materials = [mat]
	# Stick erstellen
	b = 0.0000
	vcount = -1
	db = 360.00 / refinesticks.val
	dx = 0.0
	dy = 0.0
	dz = 0.0
	pi = asin(1)
	laenge = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))
	wsz = atan2((y1-y2), (x1-x2))
	wz = acos((z1-z2)/laenge)
	
	
	# erster Punkt
	
	# Kappe	
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, laenge/2)
		me.verts.extend(dx, dy, -laenge/2)
		vcount = vcount + 2
		if vcount > 2:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-3],me.verts[vcount-2]])
			if b == 360-db:
				me.faces.extend([me.verts[0],me.verts[vcount-1],me.verts[vcount],me.verts[1]])
		b = b + db
	
	for face in me.faces:
		face.smooth=1
	
	ob.link (me)
	x1 = float(x1)
	y1 = float(y1)
	z1 = float(z1)
	x2 = float(x2)
	y2 = float(y2)
	z2 = float(z2)
	ob.loc = (float(x1+x2)/2,(y1+y2)/2,(z1+z2)/2)
	ob.RotY = wz
	ob.RotZ = wsz
	scene.link (ob)


def stick3(x1, y1, z1, type1, x2, y2, z2, type2, radius):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	# Objekt erstellen
	ob = Object.New('Mesh')
	# Mesh erstellen
	me = Mesh.New()
	if type1 in ['C', 'H', 'B', 'N', 'O', 'P']:
		mat = Material.Get(type1)
	else: mat = Material.Get('anyatom')
	me.materials = [mat]
	# Stick erste Haelfte erstellen
	a = 0.0000	
	b = 0.0000
	vcount = 0
	da = 360.00 / refinesticks.val
	db = 360.00 / refinesticks.val
	dx = 0.0
	dy = 0.0
	dz = 0.0
	pi = asin(1)
	laenge = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2))
	wsz = atan2((y1-y2), (x1-x2))
	wz = acos((z1-z2)/laenge)
	
	
	# erster Punkt
	me.verts.extend(0, 0, laenge/2+radius)
	a = a + da
	
	# Kappe
		
	while b < 360:
		dz = radius*cos(a/90*pi)
		dx = radius*sin(a/90*pi)*sin(b/90*pi)
		dy = radius*sin(a/90*pi)*cos(b/90*pi)
		b = b + db
		me.verts.extend(dx, dy, dz+laenge/2)
		vcount = vcount + 1
		if vcount > 1:
			me.faces.extend([me.verts[0],me.verts[vcount],me.verts[vcount-1]])
	
	me.faces.extend([me.verts[0],me.verts[1],me.verts[vcount]])
	
	b = 0
	kcount = 0
	vvcount = 0
	a = a + da
	
	
	while a < 90:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz+laenge/2)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0
		vvcount = 0
		a = a + da
		
	a = 90
	b = 0
	vvcount = 0
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, laenge/2)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0
	vvcount = 0	
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, 0)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0
	vvcount = 0	
	
	for face in me.faces:
		face.smooth=1
	
	
	ob.link (me)
	x1 = float(x1)
	y1 = float(y1)
	z1 = float(z1)
	x2 = float(x2)
	y2 = float(y2)
	z2 = float(z2)
	ob.loc = (float(x1+x2)/2,(y1+y2)/2,(z1+z2)/2)
	ob.RotY = wz
	ob.RotZ = wsz
	scene.link (ob)
	
	#zweite Haelfte vom Stick
	ob = Object.New('Mesh')
	# Mesh erstellen
	me = Mesh.New()
	if type2 in ['C', 'H', 'B', 'N', 'O', 'P']:
		mat = Material.Get(type2)
	else: mat = Material.Get('anyatom')
	me.materials = [mat]
	vcount = -1
			
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, 0)
		vcount = vcount + 1
		
		b = b + db
	
	kcount = kcount + 1
	b = 0
	vvcount = 0	
	
	while b < 360:
		dx = radius*sin(b/90*pi)
		dy = radius*cos(b/90*pi)
		me.verts.extend(dx, dy, -laenge/2)
		vcount = vcount + 1
		vvcount = vvcount + 1
		if vvcount > 1:
			me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
			if b == 360-db:
				me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
		b = b + db
	kcount = kcount + 1
	b = 0
	vvcount = 0	
	
	while a < 180:
		while b < 360:
			dz = radius*cos(a/90*pi)
			dx = radius*sin(a/90*pi)*sin(b/90*pi)
			dy = radius*sin(a/90*pi)*cos(b/90*pi)
			me.verts.extend(dx, dy, dz-laenge/2)
			vcount = vcount + 1
			vvcount = vvcount + 1
			if vvcount > 1:
				me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int(360/db)-1],me.verts[vcount-int(360/db)]])
				if b == 360-db:
					me.faces.extend([me.verts[vcount],me.verts[vcount-int(360/db)],me.verts[vcount-2*int(360/db)+1],me.verts[vcount-int(360/db)+1]])
			b = b + db
		kcount = kcount + 1
		b = 0
		vvcount = 0
		a = a + da
		
	# letzter Punkt
	me.verts.extend(0, 0, -laenge/2-radius)
	vcount = vcount + 1
	b = 0
	while b < 360-db:
		me.faces.extend([me.verts[vcount],me.verts[vcount-int(b/db)-2],me.verts[vcount-int(b/db)-1]])
		b = b + db
	
	me.faces.extend([me.verts[vcount],me.verts[vcount-1],me.verts[vcount-int((360-db)/db)-1]])
	eins = 1
	for face in me.faces:
		face.smooth=1
	
	
	ob.link (me)
	x1 = float(x1)
	y1 = float(y1)
	z1 = float(z1)
	x2 = float(x2)
	y2 = float(y2)
	z2 = float(z2)
	ob.loc = (float(x1+x2)/2,(y1+y2)/2,(z1+z2)/2)
	ob.RotY = wz
	ob.RotZ = wsz
	scene.link (ob)


def import_pdb(path):
	global structmode, scatom, sumatom, refineballs, refinesticks, scsticks, balls, sticks, hydros
	Blender.Window.WaitCursor(1)
	x, y, z, atom = [0], [0], [0], [0]
	file = open(path, 'r')
 	for line in file.readlines():
		if len(line) == 0 or line == ('END'):
			pass
		elif line[:6] == 'HETATM' or line[:4] == 'ATOM':
			name = line[7:11]
			while name[:1]==' ': name = name[1:]
			if len(line) > 76: 
				atom0 = line[77:(len(line)-1)]
				while atom0[-1] == ' ': atom0 = atom0[:-1]
			else:
				atom0 = line[13:16]
				while atom0[-1] == ' ': atom0 = atom0[:-1]
				esym = [' ','1','2','3','4','5','6','7','8','9']
				for a in esym:
					if atom0[-1] == a: atom0 = atom0[:-1]
					if atom0[0] == a: atom0 = atom0[1:]
			atom.append (atom0)
			x0 = line[31:38]
			while x0[:1]==' ': x0 = x0[1:]
			y0 = line[39:46]
			while y0[:1]==' ': y0 = y0[1:]
			z0 = line[47:54]
			while z0[:1]==' ': z0 = z0[1:]
			
			x.append (float(x0))
			y.append (float(y0))
			z.append (float(z0))
			
			
			if balls:
				if atom[int(name)] == 'H':
					if hydros: 
						ball(name, atom[int(name)], x[int(name)],y[int(name)],z[int(name)])
				else: ball(name, atom[int(name)], x[int(name)],y[int(name)],z[int(name)])
					
		elif line[:3] == 'TER':
			name = 'platzhalter'
			atom.append ('platzhalter')
			x.append (0)
			y.append (0)
			z.append (0)
		elif line[:6] == 'CONECT':
			if sticks:
				con0 = line[6:11]
				while con0[:1]==' ': con0 = con0[1:]
				for i in range(0,4):
					if len(line) > (15 + 5 * i):
						if not line[(11+5*i):(16+5*i)] == '     ':
							con1 = line[(11+5*i):(16+5*i)]
							while con1[:1]==' ': con1 = con1[1:]
							if int(con1)> int(con0):
								if hydros:
									stick3(x[int(con0)], y[int(con0)], z[int(con0)], atom[int(con0)], x[int(con1)], y[int(con1)], z[int(con1)], atom[int(con1)], scsticks.val)
								else:
									if not (atom[int(con0)]=='H' or atom[int(con1)]=='H'):
										stick3(x[int(con0)], y[int(con0)], z[int(con0)], atom[int(con0)], x[int(con1)], y[int(con1)], z[int(con1)], atom[int(con1)], scsticks.val)

	scene.update()
	Blender.Redraw()		     
	Blender.Window.WaitCursor(0)

def import_p_follow(path):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks
	Blender.Window.WaitCursor(1)
	x, y, z = 0, 0, 0
	pcount = 0
	file = open(path, 'r')
 	for line in file.readlines():
		if len(line) == 0 or line[:3] == ('END') or line[:6] == ('CONECT'):
			pass
		elif line[:6] == 'HETATM' or line[:4] == 'ATOM':
			if len(line) > 76: 
				atom0 = line[77:(len(line)-1)]
				while atom0[-1] == ' ': atom0 = atom0[:-1]
			else:
				atom0 = line[13:16]
				while atom0[-1] == ' ': atom0 = atom0[:-1]
				esym = [' ','1','2','3','4','5','6','7','8','9']
				for a in esym:
					if atom0[-1] == a: atom0 = atom0[:-1]
					if atom0[0] == a: atom0 = atom0[1:]
			if atom0 == 'P':
				xold = x
				yold = y
				zold = z
				x0 = line[31:38]
				while x0[:1]==' ': x0 = x0[1:]
				y0 = line[39:46]
				while y0[:1]==' ': y0 = y0[1:]
				z0 = line[47:54]
				while z0[:1]==' ': z0 = z0[1:]
				x = float(x0)
				y = float(y0)
				z = float(z0)
				if line[30] == '-': x = 0 - x
				if line[38] == '-': y = 0 - y
				if line[46] == '-': z = 0 - z	
				abstandq = (x - xold) * (x - xold) + (y - yold) * (y - yold) + (z - zold)*(z - zold)
				if pcount > 0 and abstandq < 100.00:
					stick1(xold, yold, zold, x, y, z, scsticks.val)
				pcount = pcount + 1
		elif line[:3] == 'TER':
			pcount = 0
	scene.update()
	Blender.Redraw()	
	Blender.Window.WaitCursor(0)

def gui():
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks, hydros, bbut, sbbut, sbut, pbut
	bbut = Toggle('Balls',3, 40, 240, 80, 19, bbut.val)
	sbbut = Toggle('Sticks and Balls',4, 120, 240, 150, 19, sbbut.val)
	sbut = Toggle('Sticks',5, 270, 240, 80, 19, sbut.val)
	pbut = Toggle('DNA Backbone Follow',12, 40, 220, 310, 19, pbut.val)
	if hydros: Button('Hydrogens on',11, 40, 190, 310, 19)
	else: Button('Hydrogens off',11, 40, 190, 310, 19)
	if balls: scatom = Slider('Atom Scale :', 6, 40, 160, 310,19, scatom.val, 0.00, 4.00)
	if balls: sumatom = Slider('Atom Sum :', 7, 40, 140, 310,19, sumatom.val, 0.00, 2.00)
	if balls: refineballs = Slider('Atom Refinement :', 8, 40, 120, 310,19, refineballs.val, 4, 36)
	if sticks or pbut.val: scsticks = Slider('Stick Thickness :', 9, 40, 90, 310,19, scsticks.val, 0.00, 4.00)
	if sticks or pbut.val: refinesticks = Slider('Stick Refinement :', 10, 40, 70, 310,19, refinesticks.val, 4, 36)
	Button('Import',1, 40, 40, 155, 19)
	Button('Cancel',2, 195, 40, 155, 19)
	
def event(evt, val):
	if (evt == QKEY and not val): Exit()
		
def bevent(evt):
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks, hydros, bbut, sbbut, sbut, pbut
	if evt == 2: Exit()
	elif evt == 1: 
		if structmode == 'Backbone':
			Blender.Window.FileSelector(import_p_follow, 'Import')
		else:
			Blender.Window.FileSelector(import_pdb, 'Import')
	elif evt == 3:
		structmode = "balls"
		scatom.val = 1.0
		sumatom.val = 0.4
		refineballs.val = 24
		balls = 1
		sticks = 0
		bbut.val = 1
		sbbut.val = 0
		sbut.val = 0
		pbut.val = 0
		Redraw()
	elif evt == 4:
		structmode = "sticks and balls"
		scatom.val = 0.75
		sumatom.val = 0.0
		refineballs.val = 20
		refinesticks.val = 12
		balls = 1
		scsticks.val = 0.16
		sticks = 1
		bbut.val = 0
		sbbut.val = 1
		sbut.val = 0
		pbut.val = 0
		Redraw()
	elif evt == 5:
		structmode = "sticks"
		scsticks.val = 0.24
		refinesticks.val = 12
		balls = 0
		sticks = 1
		bbut.val = 0
		sbbut.val = 0
		sbut.val = 1
		pbut.val = 0
		Redraw()
	elif evt == 12:
		structmode = "Backbone"
		scsticks.val = 1.00
		refinesticks.val = 8
		balls = 0
		sticks = 1
		bbut.val = 0
		sbbut.val = 0
		sbut.val = 0
		pbut.val = 1
		Redraw()
	elif evt == 11: 
		if hydros: hydros = 0
		else: hydros = 1
		Redraw()
	elif evt == 8:
		while not ((int(360/refineballs.val) == float(360.00/refineballs.val)) and (int(refineballs.val)/2) == (float(refineballs.val)/2)):
			refineballs.val = refineballs.val + 1
		Redraw()
	elif evt == 10:
		while not ((int(360/refinesticks.val) == float(360.00/refinesticks.val)) and (int(refinesticks.val)/2) == (float(refinesticks.val)/2)):
			refinesticks.val = refinesticks.val + 1
		Redraw()
	
def initialize():
	global structmode, scatom, sumatom, refineballs, refinesticks, balls, sticks, scsticks, hydros, bbut, sbbut, sbut, pbut
	structmode = Create("balls")
	scatom = Create(1.0)
	sumatom = Create(0.4)
	scsticks = Create(0.24)
	refineballs = Create(24)
	refinesticks = Create(12)
	balls = Create(1)
	sticks = Create(0)
	hydros = Create(1)
	bbut = Create(1)
	sbbut = Create(0)
	sbut = Create(0)
	pbut = Create(0)
	Register(gui, event, bevent)

initialize()

Blender.Redraw()