--- /dev/null
+#include <time.h>
+#include "tstream.hh"
+#include "score.hh"
+#include "pscore.hh"
+#include "staff.hh"
+#include "misc.hh"
+#include "debug.hh"
+
+void
+Score::add(Command *c)
+{
+ commands_.bottom().add(new Command(*c));
+}
+
+void
+Score::add(Staff*s)
+{
+ s->score_ = this;
+ staffs_.bottom().add(s);
+}
+
+
+void
+Score::do_pcols()
+{
+ PCursor<Score_column*> sc(cols_);
+ for (;sc.ok(); sc++) {
+ pscore_->add(sc->pcol);
+ }
+}
+/*
+ this sux. Really makeshift.
+ */
+void
+Score::do_miscs()
+{
+ Command c;
+
+ c.when = 0.0;
+
+ c.code = BREAK_END;
+ commands_.top().insert(new Command(c));
+ c.code = BREAK_POST;
+ commands_.top().insert(new Command(c));
+ c.code = BREAK_MIDDLE;
+ commands_.top().insert(new Command(c));
+ c.code = BREAK_PRE;
+ commands_.top().insert(new Command(c));
+
+ PCursor<Command*> bot(commands_.bottom());
+ c.when = last();
+ while (bot.ok() && bot->when > c.when) {
+// mtor <<"removing "<< bot->code <<" at " << bot->when<<'\n';
+ bot.remove();
+ bot = commands_.bottom();
+ }
+
+ c.code = BREAK_PRE;
+ bot.add(new Command(c));
+ bot++;
+ c.code = BREAK_MIDDLE;
+ bot.add(new Command(c));
+ bot++;
+ c.code = BREAK_POST;
+ bot.add(new Command(c));
+ bot++;
+ c.code = BREAK_END;
+ bot.add(new Command(c));
+
+ commands_.OK();
+}
+
+Mtime
+Score::last() const
+{
+ Mtime l = 0;
+ for (PCursor<Staff*> stc(staffs_); stc.ok(); stc++) {
+ l = MAX(l, stc->last());
+ }
+ return l;
+}
+void
+Score::clean_commands()
+{
+ Mtime l= last();
+ for (PCursor<Command*> cc(commands_); cc.ok(); cc++) {
+ if (cc->when > l){
+ mtor << "remming \n";
+ cc.remove();
+ }
+ }
+}
+void
+Score::process()
+{
+ do_miscs();
+
+ /// distribute commands to disciples
+ distribute_commands();
+
+ pscore_ = new PScore;
+ for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
+ sc->set_output(pscore_);
+ sc->process();
+ }
+ do_pcols();
+ calc_idealspacing();
+ clean_cols();
+ OK();
+ // print();
+ pscore_->calc_breaking();
+}
+
+// remove empty cols with no spacing attached.
+/* should rethink ownership of cols
+ */
+void
+Score::clean_cols()
+{
+ for (PCursor<Staff * > sc(staffs_); sc.ok(); sc++)
+ sc->clean_cols();
+ for (PCursor<Score_column*> c(cols_); c.ok(); c++) {
+ if (!c->pcol->used) {
+// mtor << "removing : "; c->print();
+ c.remove();
+ }
+ }
+
+ pscore_->clean_cols();
+}
+/* this sux. We should have Score_column create the appropriate PCol.
+ Unfortunately, PCols don't know about their position.
+ */
+// todo
+PCursor<Score_column*>
+Score::create_cols(Mtime w)
+{
+ Score_column* c1 = new Score_column(w);
+ Score_column* c2 = new Score_column(w);
+
+ c1->musical = false;
+ c2->musical = true;
+
+ PCursor<Score_column*> scc(cols_);
+
+ for (; scc.ok(); scc++) {
+ assert(scc->when != w);
+ if (scc->when > w)
+ break;
+ }
+
+ if (!scc.ok()) {
+ cols_.bottom().add(c1);
+ cols_.bottom().add(c2);
+ scc = cols_.bottom();
+ scc --;
+ } else {
+ scc.insert(c1);
+ scc.insert(c2);
+ scc -= 2;
+ }
+ return scc;
+}
+
+Score_column*
+Score::find_col(Mtime w,bool mus)
+{
+ PCursor<Score_column*> scc(cols_);
+ for (; scc.ok(); scc++) {
+ if (scc->when == w && scc->musical == mus)
+ return scc;
+ if (scc->when > w)
+ break;
+ }
+ scc = create_cols(w);
+ if (mus)
+ scc++;
+ return scc;
+}
+
+void
+Score::distribute_commands(void)
+{
+ for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
+ sc->add_commands(commands_);
+ }
+}
+
+
+void
+Score::output(String s)
+{
+ OK();
+ mtor << "output to " << s << "...\n";
+
+ Tex_stream the_output(s);
+ the_output << "% Automatically generated by LilyPond 0.0 at";
+ time_t t(time(0));
+ the_output << ctime(&t)<<"\n";
+ the_output << "% from input file ..\n";
+ pscore_->output(the_output);
+}
+
+void
+Score::OK() const
+{
+ for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
+ sc->OK();
+ assert(sc->score_ == this);
+ }
+ staffs_.OK();
+ cols_.OK();
+ for (PCursor<Score_column*> cc(cols_); cc.ok() && (cc+1).ok(); cc++) {
+ assert(cc->when <= (cc+1)->when);
+ }
+ for (PCursor<Command*> cc(commands_); cc.ok() && (cc+1).ok(); cc++) {
+ assert(cc->when <= (cc+1)->when);
+ }
+
+}
+
+void
+Score::print() const
+{
+ mtor << "score {\n";
+ for (PCursor<Staff*> sc(staffs_); sc.ok(); sc++) {
+ sc->print();
+ }
+ for (PCursor<Score_column*> sc(cols_); sc.ok(); sc++) {
+ sc->print();
+ }
+ mtor << "}\n";
+}
+
+/****************************************************************/
+
+Score_column::Score_column(Mtime w)
+{
+ when = w;
+ pcol = new PCol(0);
+ musical = false;
+}
+
+bool
+Score_column::used() {
+ return pcol->used;
+}
+
+void
+Score_column::print() const
+{
+ mtor << "Score_column { mus "<< musical <<" at " << when<<'\n';
+ mtor << " # symbols: " << pcol->its.size() << "\n";
+ mtor << "durations: [" ;
+ for (int i=0; i < durations.sz(); i++)
+ mtor << durations[i] << " ";
+ mtor << "]\n}\n";
+}