#!/usr/bin/python2.6
# -*- encoding: UTF-8 -*-

# Created By ...
# mosky (mosky9180 at gmail dot com)
# http://moskyat.pixnet.net/blog
# LGPL or CC-BY
# Version 0.1.0 (090831)

class SeekerError: pass
class ChildNotFound(SeekerError):
	def __init__(self, idx):
		self.idx = idx

	def __repr__(self):
		return '\''+self.idx+'\' is not in this Seeker.'

class SeekerChild:
	def __init__(self, seeker, val, dict_idx, list_idx):
		self.seeker = seeker
		self.val = val
		self.dict_idx = dict_idx
		self.list_idx = list_idx
	
	def __str__(self):
		return self.val
	
	def ruinself(self):
		self.seeker.ruin(self.list_idx)

class Seeker:
	def __init__(self, d1=None, d2=None):
		self.dict = {}
		self.list = []
		self.length = 0
		if d1: self.update(d1, d2)
	
	# d1 = index or else
	# d2 = value or None
	def update(self, d1, d2=None):
		# standard given
		if d1 and d2:
			# give them a readable name
			idx = d1
			val = d2
			del d1, d2
			if idx in self.dict:
				self.dict[idx].val = val
				self.list[self.chgidx(idx)].val = val	
			elif idx < self.length:
				self.list[idx].val = val
				self.dict[self.chgidx(idx)].val = val
			else:
				tmp = SeekerChild(self, val, idx, self.length)
				self.dict[idx] = tmp
				self.list += [tmp]
				self.length += 1
		# special given
		elif d1:
			# give d1 a readable name
			data = d1
			del d1
			if data.__iter__:
				for stuff in data:
					self.update(stuff, stuff)
			elif data.keys and data.values:
				for (idx, val) in (data.keys(), data.values()):
					self.update(idx, val)
			else:
				self.update(data, data)
	# get value from dict or list
	def seek(self, idx):
		if idx in self.dict:
			return self.dict[idx]
		elif idx < self.length:
			return self.list[idx]
		else:
			raise ChildNotFound(idx)
	
	# idx of dict <-> idx of list
	def chgidx(self, idx):
		tmp = self.seek(idx)
		if tmp.dict_idx == idx:
			return tmp.list_idx
		elif tmp.list_idx == idx:
			return tmp.dict_idx
	
	def getval(self, idx):
		return self.seek(idx).val
	
	def ruin(self, idx):
		tmp = self.seek(idx)
		del self.dict[tmp.dict_idx], self.list[tmp.list_idx]
		del tmp
		self.length -= 1
	
	# <idx> in <Seeker>
	def contains(self, idx):
		return (idx in self.dict) or idx < self.length
	
	# len(<Seeker>)
	def __len__(self): return self.length
	
	def __getitem__(self, idx): return self.seek(idx)
	def __setitem__(self, idx, val): return self.update(idx, val)
	def __delitem__(self, idx): return self.ruin(idx)
	def __contains__(self, idx): return self.contains(idx)
	
	def __getslice__(self,i ,j): return self.list[i:j]
	
	def __delslice__(self,i ,j):
		for i in xrange(i, j):
			self.ruin(i)
	
	def __iter__(self):
		return self.list.__iter__()
		
	def keys(self):
		return self.dict.keys()
		
	def values(self):
		return self.dict.values()
