The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
package Spreadsheet::Wright::OpenDocumentXML;

use 5.010;
use common::sense;

BEGIN {
	$Spreadsheet::Wright::OpenDocumentXML::VERSION   = '0.104';
	$Spreadsheet::Wright::OpenDocumentXML::AUTHORITY = 'cpan:TOBYINK';
}

use Carp;
use XML::LibXML;

use parent qw(Spreadsheet::Wright);
use constant {
	OFFICE_NS => "urn:oasis:names:tc:opendocument:xmlns:office:1.0",
	STYLE_NS  => "urn:oasis:names:tc:opendocument:xmlns:style:1.0",
	TEXT_NS   => "urn:oasis:names:tc:opendocument:xmlns:text:1.0",
	TABLE_NS  => "urn:oasis:names:tc:opendocument:xmlns:table:1.0",
	META_NS   => "urn:oasis:names:tc:opendocument:xmlns:meta:1.0",
	NUMBER_NS => "urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0",
	};

sub new
{
	my ($class, %args) = @_;
	
	my $self = bless { 'options' => \%args }, $class;
	
	$self->{'_FILENAME'} = $args{'file'} // $args{'filename'}
		or croak "Need filename.";

	return $self;
}

sub _prepare
{
	my $self = shift;
	
	return $self if $self->{'document'};
	
	my $namespaces = {
		office  => OFFICE_NS,
		style   => STYLE_NS,
		text    => TEXT_NS,
		table   => TABLE_NS,
		meta    => META_NS,
		number  => NUMBER_NS,
		};
	
	$self->{'document'} = XML::LibXML->createDocument;
	$self->{'document'}->setDocumentElement(
		$self->{'document'}->createElement('root')
		);
	while (my ($prefix, $nsuri) = each %$namespaces)
	{
		$self->{'document'}->documentElement->setNamespace($nsuri, $prefix, $prefix eq 'office' ? 1 : 0);
	}
	$self->{'document'}->documentElement->setNodeName('office:document-content');
	$self->{'document'}->documentElement->setAttribute(OFFICE_NS, 'version', '1.0');
	$self->{'body'} = $self->{'document'}->documentElement
		->addNewChild(OFFICE_NS, 'body')
		->addNewChild(OFFICE_NS, 'spreadsheet');
	$self->addsheet($self->{'options'}->{'sheet'} // 'Sheet 1');
	
	return $self;
}

sub addsheet
{
	my ($self, $caption) = @_;

	$self->{'tbody'} = $self->{'body'}->addNewChild(TABLE_NS, 'table');

	if (defined $caption)
	{
		$self->{'tbody'}->setAttributeNS(TABLE_NS, 'name', $caption);
	}
	
	return $self;
}

sub _add_prepared_row
{
	my $self = shift;

	my $tr = $self->{'tbody'}->addNewChild(TABLE_NS, 'table-row');
	
	foreach my $cell (@_)
	{
		my $tcell = $tr->addNewChild(TABLE_NS, 'table-cell');
		$tcell->setAttributeNS(OFFICE_NS, 'value-type', 'string');
		
		my $td = $tcell->addNewChild(TEXT_NS, 'p');
		
		my $content = $cell->{'content'};
		$content = sprintf($cell->{'sprintf'}, $content)
			if defined $cell->{'sprintf'};
		
		$td->appendText($content);
		
		if ($cell->{'font_weight'} eq 'bold'
		&&  $cell->{'font_style'} eq 'italic')
		{
			$td->setAttributeNS(TEXT_NS, 'style-name', 'BoldItalic');
		}
		elsif ($cell->{'font_weight'} eq 'bold')
		{
			$td->setAttributeNS(TEXT_NS, 'style-name', 'Bold');
		}
		elsif ($cell->{'font_style'} eq 'italic')
		{
			$td->setAttributeNS(TEXT_NS, 'style-name', 'Italic');
		}
	}
}

sub close
{
	my $self=shift;
	return if $self->{'_CLOSED'};
	$self->{'_FH'}->print( $self->_make_output );
	$self->{'_FH'}->close;
	$self->{'_CLOSED'}=1;
	return $self;
}

sub _make_output
{
	my $self = shift;
	return $self->{'document'}->toString;
}

1;