File Coverage

blib/lib/Video/CPL/Cue.pm
Criterion Covered Total %
statement 117 302 38.7
branch 44 164 26.8
condition 2 23 8.7
subroutine 29 54 53.7
pod 19 46 41.3
total 211 589 35.8


line stmt bran cond sub pod time code
1             package Video::CPL::Cue;
2              
3 1     1   3 use warnings;
  1         1  
  1         41  
4 1     1   3 use strict;
  1         2  
  1         15  
5 1     1   2 use Carp;
  1         1  
  1         53  
6 1     1   3 use Data::Dumper;
  1         1  
  1         35  
7 1     1   3 use XML::Writer;
  1         1  
  1         13  
8              
9 1     1   322 use Video::CPL::Annotation;
  1         2  
  1         22  
10 1     1   363 use Video::CPL::AnnotationList;
  1         2  
  1         21  
11 1     1   5 use Video::CPL::TargetList;
  1         0  
  1         2523  
12              
13             =head1 NAME
14              
15             Video::CPL::Cue - Create a Cue object.
16              
17             =head1 VERSION
18              
19             Version 0.09
20              
21             =cut
22              
23             our $VERSION = '0.09';
24              
25             =head1 SYNOPSIS
26              
27             use Video::CPL::Cue;
28              
29             my $foo = Video::CPL::Cue->new(cueType=>"regular",name=>"fooba",time=23.7,interestURL="http://foo.com");
30              
31             =head1 SUBROUTINES/METHODS
32              
33             =cut
34             our @FIELDS = qw(name cueType time tags interestURL query zeroLen cannotSkip pauseOnEntry modalOnEntry soft js backgroundHTML coincidentWebPoint pauseOnDisplay canBeDestination mxmlInCPL videoBottom useLayout webViewLayout videoHCenter webBottom);
35              
36             #WARNING be careful accessing time. $x->{time} will give the wrong results. time() can't be called
37             #directly in the module. foo(time=>1) and $x->time() work given Perl rules.
38             #
39 56 50   56 0 42 sub name { my $obj = shift; $obj->{'name'} = shift if @_; return $obj->{'name'}; }
  56         71  
  56         330  
40 0 0   0 0 0 sub cueType { my $obj = shift; $obj->{'cueType'} = shift if @_; return $obj->{'cueType'}; }
  0         0  
  0         0  
41 1 50   1 0 1 sub time { my $obj = shift; $obj->{'time'} = shift if @_; return $obj->{'time'}; }
  1         2  
  1         4  
42 3 100   3 0 4 sub tags { my $obj = shift; $obj->{tags} = shift if @_; return $obj->{tags}; }
  3         12  
  3         7  
43 3 100   3 0 5 sub interestURL { my $obj = shift; $obj->{interestURL} = shift if @_; return $obj->{interestURL}; }
  3         11  
  3         9  
44 3 100   3 0 3 sub query { my $obj = shift; $obj->{query} = shift if @_; return $obj->{query}; }
  3         8  
  3         8  
45 3 100   3 0 4 sub zeroLen { my $obj = shift; $obj->{zeroLen} = shift if @_; return $obj->{zeroLen}; }
  3         10  
  3         18  
46 3 100   3 0 4 sub cannotSkip { my $obj = shift; $obj->{cannotSkip} = shift if @_; return $obj->{cannotSkip}; }
  3         8  
  3         9  
47 3 100   3 0 4 sub pauseOnEntry { my $obj = shift; $obj->{pauseOnEntry} = shift if @_; return $obj->{pauseOnEntry}; }
  3         10  
  3         10  
48 3 100   3 0 11 sub modalOnEntry { my $obj = shift; $obj->{modalOnEntry} = shift if @_; return $obj->{modalOnEntry}; }
  3         9  
  3         9  
49 3 100   3 0 12 sub soft { my $obj = shift; $obj->{soft} = shift if @_; return $obj->{soft}; }
  3         15  
  3         8  
50 0 0   0 0 0 sub js { my $obj = shift; $obj->{js} = shift if @_; return $obj->{js}; }
  0         0  
  0         0  
51 3 100   3 0 6 sub backgroundHTML { my $obj = shift; $obj->{backgroundHTML} = shift if @_; return $obj->{backgroundHTML}; }
  3         7  
  3         10  
52 0 0   0 0 0 sub coincidentWebPoint { my $obj = shift; $obj->{coincidentWebPoint} = shift if @_; return $obj->{coincidentWebPoint}; }
  0         0  
  0         0  
53 3 100   3 0 7 sub pauseOnDisplay { my $obj = shift; $obj->{pauseOnDisplay} = shift if @_; return $obj->{pauseOnDisplay}; }
  3         9  
  3         8  
54 0 0   0 0 0 sub mxmlInCPL { my $obj = shift; $obj->{mxmlInCPL} = shift if @_; return $obj->{mxmlInCPL}; }
  0         0  
  0         0  
55 0 0   0 0 0 sub videoBottom { my $obj = shift; $obj->{videoBottom} = shift if @_; return $obj->{videoBottom}; }
  0         0  
  0         0  
56 0 0   0 0 0 sub useLayout { my $obj = shift; $obj->{useLayout} = shift if @_; return $obj->{useLayout}; }
  0         0  
  0         0  
57 3 100   3 0 5 sub webViewLayout { my $obj = shift; $obj->{webViewLayout} = shift if @_; return $obj->{webViewLayout}; }
  3         7  
  3         10  
58 0 0   0 0 0 sub videoHCenter { my $obj = shift; $obj->{videoHCenter} = shift if @_; return $obj->{videoHCenter}; }
  0         0  
  0         0  
59 0 0   0 0 0 sub webBottom { my $obj = shift; $obj->{webBottom} = shift if @_; return $obj->{webBottom}; }
  0         0  
  0         0  
60              
61 3 100   3 0 4 sub annotationList { my $obj = shift; $obj->{annotationList} = shift if @_; return $obj->{annotationList}; }
  3         6  
  3         12  
62 0 0   0 0 0 sub directoryList { my $obj = shift; $obj->{directoryList} = shift if @_; return $obj->{directoryList}; }
  0         0  
  0         0  
63 1 50   1 0 2 sub targetList { my $obj = shift; $obj->{targetList} = shift if @_; return $obj->{targetList}; }
  1         3  
  1         3  
64 1 50   1 0 1 sub story { my $obj = shift; $obj->{story} = shift if @_; return $obj->{story}; }
  1         3  
  1         3  
65             #not an attribute
66 1 50   1 0 1 sub parent { my $obj = shift; $obj->{parent} = shift if @_; return $obj->{parent}; }
  1         3  
  1         2  
67              
68             #cue new is normally called from CPL.pm. Newest model is that it sets story and TargetList correctly
69             #proposed
70             #story
71             #picLoc picOverLoc ballonText forever
72             #if present will create and add story
73             #target [accept array or scalar. Strings or cuePt. return array if wantarray else single target if only one else croak.]
74             #backgroundPicLoc
75             #operation
76             #headerText
77              
78             =head2 new();
79              
80             Return a new Cue object.
81              
82             =cut
83              
84             sub new {
85 2     2 1 4 my $pkg = shift;
86 2         10 my %parms = @_;
87 2         3 my $ret = {};
88 2         3 bless $ret,$pkg;
89              
90 2         5 foreach my $q (@FIELDS,'story','annotationList','targetList'){
91 50 100       75 $ret->{$q} = $parms{$q} if defined($parms{$q});
92             }
93 2   50     13 $ret->{parent} = $parms{parent} || undef;
94 2 50 33     20 $ret->{zerolen} = $parms{zerolen} || ($parms{cueType} =~ /(goto|regularEnd|returnEnd)/)?"true":"false";
95              
96 2         13 return $ret;
97             }
98              
99             =head2 adjust(parm1=>val,parm2=>val,...)
100              
101             Change arbitrary fields within a Cue point.
102              
103             =cut
104              
105             sub adjust {
106 0     0 1 0 my $obj = shift;
107 0         0 my %parms = @_;
108 0 0       0 %parms = $obj->parent()->converttarget(%parms) if defined $parms{target};
109 0 0 0     0 %parms = $obj->parent()->convertstory(%parms) if defined($parms{picLoc}) || defined($parms{picOverLoc}) || defined($parms{balloonText});
      0        
110 0         0 foreach my $q (@FIELDS,'story','annotationList','targetList'){
111 0 0       0 $obj->{$q} = $parms{$q} if defined($parms{$q});
112             }
113 0   0     0 $obj->{parent} = $parms{parent} || undef;
114 0 0 0     0 $obj->{zerolen} = $parms{zerolen} || ($parms{cueType} =~ /(goto|regularEnd|returnEnd)/)?"true":"false";
115 0         0 return $obj;
116             }
117              
118             =head2 fromxml()
119              
120             =cut
121              
122             sub fromxml {
123 1     1 1 2 my $parent = shift;
124 1         1 my $s = shift;
125 1         1 my %s = %{$s};
  1         10  
126 1         3 my $cueType = $s{cueType};
127 1         1 my %p;
128 1         2 foreach my $q (@FIELDS){
129 22 100       36 $p{$q} = $s{$q} if defined($s{$q});
130             }
131 1         2 $p{parent} = $parent;
132              
133 1 50       4 $p{story} = Video::CPL::Story::fromxml($s{story}[0]) if defined($s{story}[0]);
134 1 50       3 $p{targetList} = Video::CPL::TargetList::fromxml($s{targetList}[0]) if defined($s{targetList}[0]);
135 1 50       6 $p{annotationList} = Video::CPL::AnnotationList::fromxml($s{annotationList}[0]) if defined($s{annotationList}[0]);
136 1         9 return new Video::CPL::Cue(%p);
137             }
138              
139             =head2 setdl()
140              
141             =cut
142              
143             sub setdl {
144 0     0 1 0 my $obj = shift;
145 0         0 $obj->{dl} = shift;
146             }
147              
148             =head2 addanno()
149              
150             =cut
151              
152             sub addanno {
153 1     1 1 2 my $obj = shift;
154 1         2 my @annos = @_;
155 1         2 foreach my $x (@annos){
156 1 50       3 confess("Video::CPL::Cue::addanno needs a Video::CPL::Annotation\n") if ref($x) ne "Video::CPL::Annotation";
157 1         4 my $t = new Video::CPL::Target(cuePointRef=>$x->name());
158 1 50       3 if (defined $obj->{annotationList}){
159 0         0 $obj->annotationList()->pusht($t);
160             } else {
161 1         9 $obj->annotationList(new Video::CPL::AnnotationList(target=>[$t]));
162             }
163 1         1 push @{$obj->{annotations}},$t;
  1         3  
164             }
165             }
166              
167             =head2 annotations()
168              
169             =cut
170              
171             sub annotations {
172 0     0 1 0 my $obj = shift;
173 0 0       0 return @{$obj->{annotations}} if defined($obj->{annotations});
  0         0  
174 0         0 return ();
175             }
176              
177             =head2 setstory()
178              
179             =cut
180              
181             sub setstory {
182 0     0 1 0 my $obj = shift;
183 0         0 my %parms = @_;
184 0   0     0 my $text = $parms{text} || "no text";
185 0   0     0 my $pic = $parms{pic} || "picofself.jpg";
186 0         0 my $ret = Video::CPL::Story->new(balloon=>$text,pic=>$pic);
187 0         0 $obj->{image} = $pic;
188 0         0 $obj->{story} = $ret;
189             }
190              
191             =head2 dostandard()
192              
193             dostandard is an internal utility routine for adding a cuepoint
194              
195             =cut
196              
197             sub dostandard {
198 0     0 1 0 my $obj = shift;
199 0         0 my $cueType = shift;
200 0         0 my %parms = @_;
201 0 0       0 die "Tried to set cue point ($obj->{name}) at time ($obj->{time}) to $cueType but it has already been set.\n" if !$obj->{setoninit};
202 0         0 $obj->{cueType} = $cueType;
203 0 0       0 $obj->{canBeDestination} = $parms{canBeDestination} if defined($parms{canBeDestination});
204 0 0       0 $obj->{tags} = $parms{tags} if defined($parms{tags});
205 0 0       0 $obj->{interestURL} = $parms{URL} if defined($parms{URL});
206 0 0       0 $obj->{query} = $parms{query} if defined($parms{query});
207 0 0       0 $obj->{zerolen} = $parms{zerolen} if defined($parms{zerolen});
208 0 0       0 $obj->{dl} = $parms{dl} if $parms{dl};
209 0 0       0 $obj->{dlforever} = $parms{dlforever} if $parms{dlforever};
210 0 0       0 $obj->{al} = $parms{al} if $parms{al};
211 0 0       0 $obj->{tl} = $parms{tl} if $parms{tl};
212 0 0       0 $obj->{story} = $parms{story} if $parms{story};
213 0         0 $obj->{name} = $parms{name};
214 0         0 return $obj;
215             }
216              
217             =head2 regular()
218              
219             =cut
220              
221             sub regular {
222 0     0 1 0 my $obj = shift;
223 0         0 my %parms = @_;
224 0         0 return $obj->dostandard("regular",%parms);
225             }
226              
227             =head2 returnend()
228              
229             =cut
230              
231             sub returnend {
232 0     0 1 0 my $obj = shift;
233 0         0 my %parms = @_;
234 0         0 $obj->dostandard("returnEnd",%parms);
235 0         0 return;
236             }
237              
238             =head2 programend()
239              
240             =cut
241              
242             sub programend {
243 0     0 1 0 my $obj = shift;
244 0         0 my %parms = @_;
245 0         0 $obj->dostandard("programEnd",%parms);
246 0         0 return;
247             }
248              
249             =head2 choice()
250              
251             =cut
252              
253             sub choice {
254 0     0 1 0 my $obj = shift;
255 0         0 my %parms = @_;
256 0 0       0 die "Tried to set cue point ($obj->{name}) at time ($obj->{time}) to choice but it has already been set.\n" if !$obj->{setoninit};
257 0         0 $obj->{setoninit} = 0;
258 0         0 $obj->{cueType} = "userChoice";
259 0 0       0 $obj->{tl} = $parms{tl} if defined($parms{tl});
260             #set up target list;
261             #$ctv->numcue(1)->choice(tltext=>"Where do you want to go?",tl=>[@newlabels]);
262 0         0 return $obj;
263             }
264              
265             =head2 goto()
266              
267             =cut
268              
269             sub goto {
270             #OLD CODE
271             #my $obj = shift;
272             #my %parms = @_;
273             #if just a Video::CPL::Cue, throw a warning about deprecated, and make this a goto.
274             #otherwise we mean add a goto annotation to this cue point, which therefore
275             #needs to have its parent set.
276             #my $dest = shift;
277             #my $destcue;
278             #if (ref($dest) eq "Video::CPL::Cue"){
279             #$destcue = $dest;
280             #} else {
281             #$destcue = $obj->{parent}->cue($dest);
282             #}
283             #$obj->{cueType} = "goto";
284             #$obj->{tl} = [$parms{dest}];
285             #$obj->{story} = $parms{story} if defined($parms{story});
286             #return $obj;
287             #
288             #NEW CODE
289             # For the common case that we want to create a unique goto annotation right here
290             # That means creating an annotation,
291             # adding it to the CPL,
292             # and adding a cuePointRef to it to this Cue
293 0     0 1 0 my $obj = shift;
294 0 0       0 confess("Bad hash to Video::CPL::Cue::goto. Are you using an old version? Try creating a whole new Cue and adding it which will replace the old.\n") if $#_ == 0;
295 0         0 my %p = @_;
296 0 0       0 confess("Video::CPL::Cue::Annotation called without parent\n") if !defined $obj->parent();
297 0         0 $p{clickBehavior} = "goto";
298 0 0       0 $p{parent} = $obj->parent() if !exists $p{parent};
299 0 0       0 %p = $obj->parent()->converttarget(%p) if exists $p{target};
300 0 0       0 confess("Video::CPL::Cue::goto still has a target, this can not be happening.\n") if exists $p{target};
301 0         0 my $a = new Video::CPL::Annotation(%p);
302 0         0 $obj->parent()->addanno($a);
303 0         0 $obj->addanno($a);
304 0         0 return $a;
305             }
306              
307             =head2 decoration(%parms)
308              
309             Add a new clickBehavior=decoration annotation to this Video::CPL::Cue. Parameters are the same as for CPL::Annotation::new except that clickBehavior=decoration is implied.
310              
311             =cut
312              
313             sub decoration {
314 0     0 1 0 my $obj = shift;
315 0         0 my %p = @_;
316 0 0       0 confess("Video::CPL::Cue::Annotation called without parent\n") if !defined $obj->parent();
317 0         0 $p{clickBehavior} = "decoration";
318 0 0       0 $p{parent} = $obj->parent() if !exists $p{parent};
319 0         0 my $a = new Video::CPL::Annotation(%p);
320 0         0 $obj->parent()->addanno($a);
321 0         0 $obj->addanno($a);
322 0         0 return $a;
323             }
324              
325             =head2 javascript(%parms)
326              
327             Add a new clickBehavior=javascript annotation to this Video::CPL::Cue. Parameters are the same as for CPL::Annotation::new except that clickBehavior=javascript is implied.
328              
329             =cut
330              
331             sub javascript {
332 0     0 1 0 my $obj = shift;
333 0         0 my %p = @_;
334 0 0       0 confess("Video::CPL::Cue::javascript called without parent\n") if !defined $obj->parent();
335 0         0 $p{clickBehavior} = "javascript";
336 0 0       0 $p{parent} = $obj->parent() if !exists $p{parent};
337 0         0 my $a = new Video::CPL::Annotation(%p);
338 0         0 $obj->parent()->addanno($a);
339 0         0 $obj->addanno($a);
340 0         0 return $a;
341             }
342              
343             =head2 returnEnd(%parms)
344              
345             Add a new clickBehavior=returnEnd annotation to this Video::CPL::Cue. Parameters are the same as for Video::CPL::Annotation::new except that clickBehavior=returnEnd is implied.
346              
347             =cut
348              
349             sub returnEnd {
350 0     0 1 0 my $obj = shift;
351 0         0 my %p = @_;
352 0 0       0 confess("Video::CPL::Cue::Annotation called without parent\n") if !defined $obj->parent();
353 0         0 $p{clickBehavior} = "returnEnd";
354 0 0       0 $p{parent} = $obj->parent() if !exists $p{parent};
355 0         0 my $a = new Video::CPL::Annotation(%p);
356 0         0 $obj->parent()->addanno($a);
357 0         0 $obj->addanno($a);
358 0         0 return $a;
359             }
360              
361             =head2 xml()
362              
363             Return the text form of a Cue object.
364              
365             =cut
366              
367             sub xmlo {
368 1     1 0 1 my $obj = shift;
369 1         2 my $xo = shift;
370 1         1 my %p;
371 1         2 foreach my $q (@FIELDS){
372 22 100       42 $p{$q} = $obj->{$q} if defined($obj->{$q});
373             }
374 1         9 $xo->startTag("cuePt",%p);
375 1 50       154 $obj->story()->xmlo($xo) if defined $obj->story();
376             #$obj->mxmlInCPL()->xmlo($xo) if $obj->mxmlInCPL();#seems wrong, it is not a list
377             #$obj->directoryList()->xmlo($xo) if $obj->directoryList();
378 1 50       3 $obj->targetList()->xmlo($xo) if $obj->targetList();
379 1 50       3 $obj->annotationList()->xmlo($xo) if defined $obj->annotationList();
380 1         19 $xo->endTag("cuePt");
381 1         12 return;
382             }
383              
384             sub xml {
385 0     0 1   my $obj = shift;
386 0           my $ret;
387 0           my $a = "";
388 0           confess "Video::CPL::Cue::xml not updated\n";
389 0           my $xo = new XML::Writer(OUTPUT=>\$a);
390 0           my $cueType = $obj->{cueType};
391 0           my $name = $obj->{name};
392 0           $ret .= "
393 0           foreach my $q (@FIELDS){
394 0 0         $ret .= "$q=\"$obj->{$q}\" " if defined($obj->{$q});
395             }
396 0           $ret .= ">\n";
397 0 0         if ($obj->{story}){
398 0           my $st = $obj->{story};
399 0           $ret .= $st->xml();
400             #my $btext = $st->{balloonText};
401             #my $picloc = $st->{picLoc};
402             #$ret .= "\n";
403             }
404 0 0         if ($obj->{mxmlInCPL}){
405 0           $ret .= XMLout($obj->{mxmlInCPL});
406             }
407 0 0         if ($obj->{dl}){
408 0           my $dl = $obj->{dl};
409 0           my $dltext = $obj->{dltext};
410 0           $ret .= "
411 0 0         $ret .= "forever=\"$obj->{dlforever}\" " if $obj->{dlforever};
412 0           $ret .= "headerText=\"$dltext\">\n";
413 0           foreach my $t (@$dl){
414 0           $ret .= $t->printref($obj->{parent});
415             }
416 0           $ret .= "\n";
417             }
418 0 0         if ($obj->{tl}){
419             #and here, we will always have an array of cue points?
420             #YES until further notice
421 0           my $tl = $obj->{tl};
422 0           my $tltext = $obj->{tltext};
423 0           my $tlpic = $obj->{tlpic};
424 0           $ret .= "
425 0 0         $ret .= "headerText=\"$tltext\" " if $tltext;
426 0 0         $ret .= "backgroundPicLoc=\"$tlpic\"" if $tlpic;
427 0           $ret .= ">\n";
428 0           foreach my $t (@$tl){
429 0 0         if (ref($t)){
430 0           $ret .= $t->printref($obj->{parent});
431             } else {
432             #presumed string
433 0           $ret .= "\n";
434             }
435             }
436 0           $ret .= "\n";
437             }
438 0           my @anno = @{$obj->{annotations}};
  0            
439 0 0         if (@anno){
440 0           $ret .= "\n";
441 0           foreach my $x (@anno){
442 0 0 0       confess("Video::CPL::Cue::xml is trying to print out annotations but parent is missing obj(".Dumper($obj).") x(".Dumper($x).")anno(".Dumper(\@anno).")\n") if !$obj->{parent} || !$x;
443 0           $ret .= $x->printref($obj->{parent});
444             #my $name = $x->{name};
445             #$ret .= "\n";
446             }
447 0           $ret .= "\n";
448             }
449 0           $ret .= "\n";
450 0           return $ret;
451             }
452              
453             =head2 reffromobj($cplobj)
454              
455             return the string needed to refer to this in the context of a particular CPL object.
456              
457             =cut
458              
459             sub reffromobj {
460 0     0 1   my $obj = shift;
461 0           my $cpl = shift;
462 0 0         confess("reffromobj but no parent\n") if !defined($obj->{parent});
463 0 0         return $obj->{name} if $obj->parent() == $cpl;
464 0           my $ctvfile = $obj->parent()->{ctvfilename};
465 0           return "/$ctvfile\#$obj->{name}";
466             #TODO: support for CPL objects with a different domain, think about dynamic
467             }
468              
469             =head2 printref()
470              
471             =cut
472              
473             sub printref {
474 0     0 1   my $obj = shift;
475 0           my $par = shift;
476 0 0         confess("printref but no parent\n") if !defined($obj->{parent});
477 0 0         if ($par eq $obj->{parent}){
478             #local reference
479 0           return "{name}\"/>\n";
480             } else {
481             #This is a bit fragile and does not support remote or non-top level directories Thought needed
482             #remote reference
483             #my $ref = $obj->{parent}->{ref};
484 0           my $ctvfile = $obj->{parent}->{ctvfilename};
485             #return "{name}\"/>\n";
486 0           return "{name}\"/>\n";
487             }
488             }
489             =head1 AUTHOR
490              
491             Carl Rosenberg, C<< >>
492              
493             =head1 BUGS
494              
495             Please report any bugs or feature requests to Coincident TV.
496              
497             =head1 SUPPORT
498              
499             You can find documentation for this module with the perldoc command.
500              
501             perldoc Video::CPL::Cue
502              
503              
504             =head1 LICENSE AND COPYRIGHT
505              
506             Copyright 2010 Coincident TV
507              
508             Licensed under the Apache License, Version 2.0 (the "License");
509             you may not use this file except in compliance with the License.
510             You may obtain a copy of the License at
511              
512             http://www.apache.org/licenses/LICENSE-2.0
513              
514             Unless required by applicable law or agreed to in writing, software
515             distributed under the License is distributed on an "AS IS" BASIS,
516             WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
517             See the License for the specific language governing permissions and
518             limitations under the License.
519              
520             =cut
521              
522             1; # End of Video::CPL::Cue