#! /usr/bin/env python
# encoding: utf-8
# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file

import os,textwrap,shutil
from waflib import Logs,Context,ConfigSet,Options,Build,Configure
class Odict(dict):
	def __init__(self,data=None):
		self._keys=[]
		dict.__init__(self)
		if data:
			if isinstance(data,dict):
				self.append_from_dict(data)
			elif type(data)==list:
				self.append_from_plist(data)
			else:
				raise Exception("expected a dict or a tuple list")
	def append_from_dict(self,dict):
		map(self.__setitem__,dict.keys(),dict.values())
	def append_from_plist(self,plist):
		for pair in plist:
			if len(pair)!=2:
				raise Exception("invalid pairs list")
		for(k,v)in plist:
			self.__setitem__(k,v)
	def __delitem__(self,key):
		if not key in self._keys:
			raise KeyError(key)
		dict.__delitem__(self,key)
		self._keys.remove(key)
	def __setitem__(self,key,item):
		dict.__setitem__(self,key,item)
		if key not in self._keys:
			self._keys.append(key)
	def clear(self):
		dict.clear(self)
		self._keys=[]
	def copy(self):
		return Odict(self.plist())
	def items(self):
		return zip(self._keys,self.values())
	def keys(self):
		return list(self._keys)
	def values(self):
		return map(self.get,self._keys)
	def plist(self):
		p=[]
		for k,v in self.items():
			p.append((k,v))
		return p
	def __str__(self):
		s="{"
		l=len(self._keys)
		for k,v in self.items():
			l-=1
			strkey=str(k)
			if isinstance(k,basestring):strkey="'"+strkey+"'"
			strval=str(v)
			if isinstance(v,basestring):strval="'"+strval+"'"
			s+=strkey+":"+strval
			if l>0:s+=", "
		s+="}"
		return s
review_options=Odict()
review_defaults={}
old_review_set=None
new_review_set=None
class OptionsReview(Options.OptionsContext):
	def __init__(self,**kw):
		super(self.__class__,self).__init__(**kw)
	def prepare_config_review(self):
		gr=self.get_option_group('configure options')
		for opt in gr.option_list:
			if opt.action!='store'or opt.dest in("out","top"):
				continue
			review_options[opt.dest]=opt
			review_defaults[opt.dest]=opt.default
			if gr.defaults.has_key(opt.dest):
				del gr.defaults[opt.dest]
			opt.default=None
	def parse_args(self):
		self.prepare_config_review()
		self.parser.get_option('--prefix').help='installation prefix'
		super(OptionsReview,self).parse_args()
		Context.create_context('review').refresh_review_set()
class ReviewContext(Context.Context):
	'''reviews the configuration values'''
	cmd='review'
	def __init__(self,**kw):
		super(self.__class__,self).__init__(**kw)
		out=Options.options.out
		if not out:
			out=getattr(Context.g_module,Context.OUT,None)
		if not out:
			out=Options.lockfile.replace('.lock-waf','')
		self.build_path=(os.path.isabs(out)and self.root or self.path).make_node(out).abspath()
		self.cache_path=os.path.join(self.build_path,Build.CACHE_DIR)
		self.review_path=os.path.join(self.cache_path,'review.cache')
	def execute(self):
		if not self.compare_review_set(old_review_set,new_review_set):
			self.invalidate_cache()
		self.store_review_set(new_review_set)
		print(self.display_review_set(new_review_set))
	def invalidate_cache(self):
		try:
			Logs.warn("Removing the cached configuration since the options have changed")
			shutil.rmtree(self.cache_path)
		except:
			pass
	def refresh_review_set(self):
		global old_review_set,new_review_set
		old_review_set=self.load_review_set()
		new_review_set=self.update_review_set(old_review_set)
		self.import_review_set(new_review_set)
	def load_review_set(self):
		if os.path.isfile(self.review_path):
			return ConfigSet.ConfigSet(self.review_path)
		return ConfigSet.ConfigSet()
	def store_review_set(self,review_set):
		if not os.path.isdir(self.cache_path):
			os.makedirs(self.cache_path)
		review_set.store(self.review_path)
	def update_review_set(self,old_set):
		def val_to_str(val):
			if val==None or val=='':
				return''
			return str(val)
		new_set=ConfigSet.ConfigSet()
		opt_dict=Options.options.__dict__
		for name in review_options.keys():
			if name in opt_dict:
				if val_to_str(opt_dict[name])!=val_to_str(review_defaults[name]):
					new_set[name]=opt_dict[name]
			elif name in old_set:
				new_set[name]=old_set[name]
		return new_set
	def import_review_set(self,review_set):
		for name in review_options.keys():
			if name in review_set:
				value=review_set[name]
			else:
				value=review_defaults[name]
			setattr(Options.options,name,value)
	def compare_review_set(self,set1,set2):
		if len(set1.keys())!=len(set2.keys()):return False
		for key in set1.keys():
			if not key in set2 or set1[key]!=set2[key]:
				return False
		return True
	def display_review_set(self,review_set):
		term_width=Logs.get_term_cols()
		lines=[]
		for dest in review_options.keys():
			opt=review_options[dest]
			name=", ".join(opt._short_opts+opt._long_opts)
			help=opt.help
			actual=None
			if dest in review_set:actual=review_set[dest]
			default=review_defaults[dest]
			lines.append(self.format_option(name,help,actual,default,term_width))
		return"Configuration:\n\n"+"\n\n".join(lines)+"\n"
	def format_option(self,name,help,actual,default,term_width):
		def val_to_str(val):
			if val==None or val=='':
				return"(void)"
			return str(val)
		max_name_len=20
		sep_len=2
		w=textwrap.TextWrapper()
		w.width=term_width-1
		if w.width<60:w.width=60
		out=""
		out+=w.fill(help)+"\n"
		name_len=len(name)
		out+=Logs.colors.CYAN+name+Logs.colors.NORMAL
		w.subsequent_indent=" ".rjust(max_name_len+sep_len)
		w.width-=(max_name_len+sep_len)
		if name_len>max_name_len:
			out+="\n"+w.subsequent_indent
		else:
			out+=" ".rjust(max_name_len+sep_len-name_len)
		if actual!=None:
			out+=Logs.colors.BOLD+w.fill(val_to_str(actual))+Logs.colors.NORMAL+"\n"+w.subsequent_indent
		default_fmt=val_to_str(default)
		if actual!=None:
			default_fmt="default: "+default_fmt
		out+=Logs.colors.NORMAL+w.fill(default_fmt)+Logs.colors.NORMAL
		return out
old_configure_execute=Configure.ConfigurationContext.execute
def new_configure_execute(self):
	old_configure_execute(self)
	Context.create_context('review').store_review_set(new_review_set)
Configure.ConfigurationContext.execute=new_configure_execute
