""" Report renderer for Excel .xls format """

from trac.core import *
from trac.ticket.report import ITicketReportRenderer
from trac.ticket.web_ui import TicketModule
from trac.ticket.query import QueryModule
from pyExcelerator import * 
from datetime import datetime 
import copy
import types

class XlsDoc(CompoundDoc.XlsDoc): 
    def get(self, stream): 
        padding = '\x00' * (0x1000 - (len(stream) % 0x1000)) 
        self.book_stream_len = len(stream) + len(padding) 
        self.__build_directory() 
        self.__build_sat() 
        self.__build_header() 
        return '%s%s%s%s%s%s%s' % ( 
            self.header, 
            self.packed_MSAT_1st, 
            stream, 
            padding, 
            self.packed_MSAT_2nd, 
            self.packed_SAT, 
            self.dir_stream) 

class Workbook(Workbook): 
    def get(self): 
       doc = XlsDoc() 
       return doc.get(self.get_biff_data()) 


class ReportToExcel(Component):
	implements (ITicketReportRenderer)
	
	# ITicketRerportRenderer
	def get_report_format(self):
		return 'xls'
		
	def get_report_mimetype(self):
		return 'application/vnd.ms-excel'
		
	def get_report_linkname(self):
		return 'Excel'
		  
	def get_report_linkclass(self):
		return None #'xls'
					
	def render(self, req, cols, rows,id): 
		
	        req.send_response(200) 
	        req.send_header('Content-Type', self.get_report_mimetype()) 
	        req.send_header('Content-Disposition', 
	                        'filename=Report%s.xls' % id) 
	        req.end_headers() 
	 
	        wb = Workbook() 
	        sheetname = "Report%s" % id 
		
	        ws = wb.add_sheet(self.convertSheetName(sheetname)) 
	        
		ws.panes_frozen = True 
	        ro = 1 
	        ws.horz_split_pos = ro 
	        
	        
	        font0 = Font() 
	        font0.charset = font0.CHARSET_SYS_DEFAULT 
	        font0.name = 'MS UI Gothic' 
	        font1 = copy.copy(font0) 
	        font1.bold = True 
	        font2 = copy.copy(font0) 
	        font2.height = 0x00A0 
	        align0 = Alignment() 
	        align1 = copy.copy(align0) 
	        align1.vert = align1.VERT_TOP 
	        align2 = copy.copy(align1) 
	        align2.wrap = align2.WRAP_AT_RIGHT 
	 
	        self.style0 = XFStyle() 
	        self.style0.font = font0 
	        self.style0.alignment = align1 
	        self.style0.num_format_str = 'general' 
	        self.style_colheader = copy.copy(self.style0) 
	        self.style_colheader.num_format_str = '@' 
	        self.style_colheader.font = font1 
	        self.style_num = copy.copy(self.style0) 
	        self.style_str = copy.copy(self.style0) 
	        self.style_str.num_format_str = '@' 
	        self.style_wrap_str = copy.copy(self.style0) 
	        self.style_wrap_str.alignment = align2 
	        self.style_wrap_str.font = font2 
	        self.style_date = copy.copy(self.style0) 
	        self.style_date.num_format_str = 'yyyy/mm/dd' 
	 
	        for col, cx in map(lambda x, y: [x, y], cols, range(len(cols))): 
	           
		    name = str(col).replace('_','') 
	            ws.write(ro-1, cx, name.decode('utf-8'), self.style_colheader) 
	           
	            conv = self.convertComments
	
	            style = self.style_str 
	            
	            if name in ['time', 'date','changetime', 'created', 'modified',
	            		'hora', 'fecha','cambio'   ,'creado'  ,'modificado']: 
	                ws.col(cx).width = 0xb00 
	                conv = self.convertTimeStamp
	                style = self.style_date 
	                
	            elif name in ['summary','resumen']:
	            	ws.col(cx).width = 0x1a00 
	                style = self.style_wrap_str 
	                
	            elif name in ['description','descripcion']:
	                ws.col(cx).width = 0x7000 
	                style = self.style_wrap_str 
	                
	            elif name in ['color', 'ticket', 'id']: 
	                if name in ['color']: 
	                    ws.col(cx).hidden = 1 
	                conv = self.convertInteger 
	                style = self.style_num 
	            elif name in ['style']: 
	                ws.col(cx).hidden = 1 
	            elif name == "component":
			ws.col(cx).width = 0x1a00 
			
			
		    for value, rx in map(lambda x, y: [conv(x[cx]), ro + y], \
	                                 rows, range(len(rows))): 
	           	if type(value) is int:
	           		ws.write(rx, cx, value, self.style_num) 
	           	elif type(value) is datetime:
	           		ws.write(rx, cx, value, self.style_date) 
	           	elif type(value) is types.NoneType:
	           		ws.write(rx, cx, '-',self.style_str)
	           	else:
	           		ws.write(rx, cx, value, style) 
	           		
	           
	        req.write(wb.get())     

	def convertComments(self, x):
		try:	
			if type(x) is types.NoneType:
				return x
			else:
				return str(x).replace('\r','').rstrip('\r\n').decode('utf-8') 
	    	except:
			return x.replace('\r','').rstrip('\r\n')
		
	
	def convertTimeStamp(self,timestamp):
		
		try:
			return datetime.fromtimestamp(float(timestamp)) 
		except:
			return timestamp
		
	def convertInteger(self,value):
		try:
			return int(value)
		except:
			return value
			
	def convertSheetName(self, sheetname):
		
		sheetname = sheetname.replace('/','-') 
		
		try:
			return sheetname.decode('utf-8')
		except:
			return sheetname
			
		  
			
		
