function NewSwaraSpacerView(block) 
{
    // we are selectable ONLY in insert mode
    //this.isSelectable = function() { return NotationEditModeController.insertMode(); }

    /**
     * the block to which new swara spacer belongs to (i.e. swaras added using the
     * spacer would get added to this block
     * @type SongBlock
     * @private
     */
    this.fBlock = block;

    /**
     * a dummy swara model on which spacer is based up
     * @type Swara
     * @private
     */
    this.fModel = null;

    /**
     * get the song block associated with the swara spacer
     */
    this.getSongBlock = function() { return this.fBlock; }

    /**
     * get previous swara in the same row as the spacer (if any)
     * @return previous swara in the same row as the spacer (if any)
     * @type SwaraView
     */
    this.previousSwara = function() {
	var prevS = this.prevSelectable();
	while( prevS ) {
	    if( prevS.partType() == ROWVIEWPART_SWARA )
		break;
	    prev = prev.prevSelectable();
	}
	return prevS;
    }

    /**
     * get the underlying model
     * @return the underlying model
     * @type Swara
     */
    this.getModel = function() { 
	var p= null;
	var pm = null;
	var prevS = this.previousSwara();
	if( prevS ) pm = prevS.getModel();
	if( !p )  {
	    var speed = 0;
	    if( pm )
		speed = pm.getSpeed();
	    else if( this.rowView() ) {
		speed = this.rowView().pageView().songView().getSong().getDefaultSpeed();
	    }

	    if( !this.fModel )
		this.fModel = new Swara( "", false, 0, 1, speed );
	    else  {
		this.fModel.setOctave(0);
		this.fModel.setSpeed(speed);
	    }
	}
	else
	{
	    if( !this.fModel )
		this.fModel = new Swara( "", false, p.getOctave(), 1, p.getSpeed() );
	    else {
		this.fModel.setOctave(p.setOctave);
		this.fModel.setSpeed(p.setSpeed);
	    }
	}
	return this.fModel; 
    }

    /**
     * called by the base-class when this view is selected
     */
    this.onselect = function() {
	var m = this.getModel();
	EventManager.postEvent(EventManager.EVENT_NEWSWARASPACER_SELECTED, this, m );
    }

    /**
     * override of {@link SelectableRowViewPart#insertMode} to indicate
     * if we are in insert mode for swaras
     */
    this.insertMode = function() {
	// we are always in insert mode
	// return true;
	return NotationEditModeController.insertMode();
    }

    /**
     * override of {@link SelectableRowViewPart#editingInserted} to indicate
     * if are we still editing the object we just inserted
     */
    this.editingInserted = function() { 
	// we will never be in a mode where we have a valid swara which was
	// inserted and user is editing it.
	return this.fSelected;
    }

    /**
     * generate the HTML contents for the inner part of the spacer as div - this
     * inner part is meant to go into a table cell (renderd by call to 
     * {@link NewSwaraSpacerView#render} or {@link NewSwaraSpacerView#renderAsHTML})
     * <p>
     * The inner content is saved in a hold area and used later during render.
     *
     * @param {boolean} wholeAsHTML	(IGNORED) are we generating the whole cell 
     *					(as opposed to just inner contents) as HTML?
     *
     * @param {int}  nCols	 	the column span of the spacer (used later
     *				 	when render is called)
     * @return NOTHING MEANINGFUL
     */
    this.renderInner = function( wholeAsHTML, nCols ) {
	this.fNCols = nCols;
	var s = new Array();
	var i = 0;
	// padding 6: kludge to account for speed rows
	s[i++] = '<div class="sselem" style="padding-top:6px;width:100%;height:100%"><div class="newswaraspacer" style="'; 
	if(theSongView.isInteractive())
	    s[i++] = 'cursor pointer;';
	else
	    s[i++] = 'cursor:default;';
	s[i++] = 'border:thin solid ';
	s[i++] = this.fBackgroundColor;
	s[i++] = ';width:0.63em;">&nbsp;</div></div>';	
	this.fInnerHTML = s.join("");
	return this.fInnerHTML;
    }

    /**
     * render the view contents inside a table cell on a row-view
     * @param {SwaraLyricRow}	row		the row-view
     * @param {int}		partInRow	the nth tala part in this row
     *						to which this view goes into
     * @param {int}		cellidx		overall cell (column) index in
     *						the row
     * @return the table cell
     * @type DOMElement_TD
     */
    this.render = function(row, partInRow, cellidx) {
	if(!partInRow) partInRow = 0;

	if( !this.fInnerHTML ) return null;	// renderInner not called

	var ret = row.addDOMCell(false, partInRow, null, this.fNCols, cellidx);
	var td = ret.td;
	cellidx = ret.cellidx;

	// generate and set inner content
	td.innerHTML = this.generateHTML(row, partInRow);
	this.fInnerHTML = null;

	this.attach(td,cellidx);

	// add ourselves to the row
	row.addPart(this);
	return td;
    }

    /**
     * generate HTML content for entire swara view (table-cell) - assumes
     * renderInner is already called
     * <p>
     * The contents are added to the hold area of the row
     *
     * @param {SwaraLyricRowView } rowview   the row view
     * @param {int} 		   partInRow n as in nth tala part in the row 
     */
    this.renderAsHTML = function( row, partInRow) {
	// add speeds
	var s = this.generateHTML(row, partInRow);
	// join the contents and add it the hold area of our row
	row.addDOMCellAsHTML(false, partInRow, s);
	this.fInnerHTML = null;

	// add ourselves to the row
	row.addPart(this);
    }

    /**
     * generate the HTML contents of this view as a string and return it
     * @param {SwaraLyricRowView } rowview   the row view
     * @param {int} 		   partInRow n as in nth tala part in the row 
     * @param {boolean} innerOnly	generate only inner content
     * @type String
     * @return the HTML contents of the view
     */
    this.generateHTML = function(row, partInRow, innerOnly) {
	// add speeds
	var s = new Array();
	var i = 0;
	if(!innerOnly)
	    s[i++] = '<td colspan="' + this.fNCols + '" style="padding:0 0 0 0;">';
	s[i++] = '<table style="width:100%;padding:0 0 0 0;border-collapse:collapse;">';
	s[i++] = '<tr><td style="padding:0 0 0 0;">';
	s[i++] = '<div style="padding:0 0 0 0;overflow:hidden;height:';
	if( row.haveGamakas())
	    s[i++] = row.getGamakaHeight() + "px;";
	else
	    s[i++] = "1px;display:none;"; 	     // smallest
	s[i++] = '"></div></td></tr>';
	s[i++] = '<tr><td style="padding:0 0 0 0">'; // VERY IMPORTANT for speed markers to be continous across swaras
	s[i++] = this.fInnerHTML;
	s[i++] = '</td>';
	// filler: a width a MUST for IE (no adverse affects on FireFox)
	// a % value doesnt work on IE as it may expand table
	// DOES NOT WORK NICELY 
	//s[i++] = '<td style="width:100%;overflow:hidden;"></td>';
	s[i++] = '</tr></table>';
	if( !innerOnly )
	    s[i++] = '</td>';
	return s.join("");
    }

    /**
     * attach ourselves to a table-cell whose HTML content we generated earlier
     */
    this.attach = function( td, cellidx ) {
	// td.view     = this; 
	this.fTableCell = td;	// set table cell
	td.id          = Utils.getNewId("sw"); Utils.addToIdMap(td, this);
	this.domid     = td.id;
	this.fCellIdx = cellidx;

	var ow = Utils._findNodeByClass(td, "sselem");
	if(!ow ) return false;
	this.fInner = ow;
	var spacer = Utils._findNodeByClass(ow,"newswaraspacer");
	if(!spacer ) return false;
	this.initSelectable(spacer, true);
	return true;
    }

    /**
     * @ignore
     */
    this.fPartType = ROWVIEWPART_NEWSWARASPACER;
    block = null;

    /**
     * Hold area for inner HTML content - populated by 
     * {@link NewSwaraSpacerView#renderInner} and later used during rendering
     *
     * @type String
     * @private
     */
    this.fInnerHTML = null;
}
/**
 * @class
 * represents the view that is a place holder for appending new swaras
 * <p>
 * <b>Rendering</b>: There are 2 kinds of rendering 
 * <ul>
 * <li> the progressive rendering used in WYSIWYG mode where rendering creates 
 * the actual DOM elements for the heading - done by {@link NewSwaraSpacerView#render} 
 * <li> non-progressive rendering used in start-up where render simply generates
 * the HTML content in a string. 
 *
 * In <u>both</u> cases, {@link NewSwaraSpacerView#renderInner} which <b>must</b> 
 * called first and it sets up {@link NewSwaraSpacerView#fInnerHTML} to indicate
 * what rendering should do.
 * <p>
 * In both cases, inner content is generated as a whole and rendered, there
 * is a need for a call to {@link SwaraView#attach} to associate the DOM with
 * the view. In case of progressive rendering, this is automatic. In case of
 * non-progressive, an separate call to attach is expected later.
 */
@class
represents the view that is a place holder for appending new swaras

Rendering: There are 2 kinds of rendering

 the progressive rendering used in WYSIWYG mode where rendering creates
the actual DOM elements for the heading - done by  NewSwaraSpacerView#render
 non-progressive rendering used in start-up where render simply generates
the HTML content in a string.

In both cases,  NewSwaraSpacerView#renderInner which must
called first and it sets up  NewSwaraSpacerView#fInnerHTML to indicate
what rendering should do.

In both cases, inner content is generated as a whole and rendered, there
is a need for a call to  SwaraView#attach to associate the DOM with
the view. In case of progressive rendering, this is automatic. In case of
non-progressive, an separate call to attach is expected later.
@class represents the view that is a place holder for appending new swaras Rendering : There are 2 kinds of rendering the progressive rendering used in WYSIWYG mode where rendering creates the actual DOM elements for the heading - done by NewSwaraSpacerView#render non - progressive rendering used in start - up where render simply generates the HTML content in a string . In both cases NewSwaraSpacerView#renderInner which must called first and it sets up NewSwaraSpacerView#fInnerHTML to indicate what rendering should do . In both cases inner content is generated as a whole and rendered there is a need for a call to SwaraView#attach to associate the DOM with the view . In case of progressive rendering this is automatic . In case of non - progressive an separate call to attach is expected later .
function NewSwaraSpacerView(block) 
{
    this.fBlock = block;
    this.fModel = null;
    this.getSongBlock = function() { return this.fBlock; }
    this.previousSwara = function() {
	var prevS = this.prevSelectable();
	while( prevS ) {
	    if( prevS.partType() == ROWVIEWPART_SWARA )
		break;
	    prev = prev.prevSelectable();
	}
	return prevS;
    }
    this.getModel = function() { 
	var p= null;
	var pm = null;
	var prevS = this.previousSwara();
	if( prevS ) pm = prevS.getModel();
	if( !p )  {
	    var speed = 0;
	    if( pm )
		speed = pm.getSpeed();
	    else if( this.rowView() ) {
		speed = this.rowView().pageView().songView().getSong().getDefaultSpeed();
	    }
	    if( !this.fModel )
		this.fModel = new Swara( "", false, 0, 1, speed );
	    else  {
		this.fModel.setOctave(0);
		this.fModel.setSpeed(speed);
	    }
	}
	else
	{
	    if( !this.fModel )
		this.fModel = new Swara( "", false, p.getOctave(), 1, p.getSpeed() );
	    else {
		this.fModel.setOctave(p.setOctave);
		this.fModel.setSpeed(p.setSpeed);
	    }
	}
	return this.fModel; 
    }
    this.onselect = function() {
	var m = this.getModel();
	EventManager.postEvent(EventManager.EVENT_NEWSWARASPACER_SELECTED, this, m );
    }
    this.insertMode = function() {
	return NotationEditModeController.insertMode();
    }
    this.editingInserted = function() { 
	return this.fSelected;
    }
    this.renderInner = function( wholeAsHTML, nCols ) {
	this.fNCols = nCols;
	var s = new Array();
	var i = 0;
	s[i++] = '<div class="sselem" style="padding-top:6px;width:100%;height:100%"><div class="newswaraspacer" style="'; 
	if(theSongView.isInteractive())
	    s[i++] = 'cursor pointer;';
	else
	    s[i++] = 'cursor:default;';
	s[i++] = 'border:thin solid ';
	s[i++] = this.fBackgroundColor;
	s[i++] = ';width:0.63em;">&nbsp;</div></div>';	
	this.fInnerHTML = s.join("");
	return this.fInnerHTML;
    }
    this.render = function(row, partInRow, cellidx) {
	if(!partInRow) partInRow = 0;
	if( !this.fInnerHTML ) return null;	
	var ret = row.addDOMCell(false, partInRow, null, this.fNCols, cellidx);
	var td = ret.td;
	cellidx = ret.cellidx;
	td.innerHTML = this.generateHTML(row, partInRow);
	this.fInnerHTML = null;
	this.attach(td,cellidx);
	row.addPart(this);
	return td;
    }
    this.renderAsHTML = function( row, partInRow) {
	var s = this.generateHTML(row, partInRow);
	row.addDOMCellAsHTML(false, partInRow, s);
	this.fInnerHTML = null;
	row.addPart(this);
    }
    this.generateHTML = function(row, partInRow, innerOnly) {
	var s = new Array();
	var i = 0;
	if(!innerOnly)
	    s[i++] = '<td colspan="' + this.fNCols + '" style="padding:0 0 0 0;">';
	s[i++] = '<table style="width:100%;padding:0 0 0 0;border-collapse:collapse;">';
	s[i++] = '<tr><td style="padding:0 0 0 0;">';
	s[i++] = '<div style="padding:0 0 0 0;overflow:hidden;height:';
	if( row.haveGamakas())
	    s[i++] = row.getGamakaHeight() + "px;";
	else
	    s[i++] = "1px;display:none;"; 	     
	s[i++] = '"></div></td></tr>';
	s[i++] = '<tr><td style="padding:0 0 0 0">'; 
	s[i++] = this.fInnerHTML;
	s[i++] = '</td>';
	s[i++] = '</tr></table>';
	if( !innerOnly )
	    s[i++] = '</td>';
	return s.join("");
    }
    this.attach = function( td, cellidx ) {
	this.fTableCell = td;	
	td.id          = Utils.getNewId("sw"); Utils.addToIdMap(td, this);
	this.domid     = td.id;
	this.fCellIdx = cellidx;
	var ow = Utils._findNodeByClass(td, "sselem");
	if(!ow ) return false;
	this.fInner = ow;
	var spacer = Utils._findNodeByClass(ow,"newswaraspacer");
	if(!spacer ) return false;
	this.initSelectable(spacer, true);
	return true;
    }
    this.fPartType = ROWVIEWPART_NEWSWARASPACER;
    block = null;
    this.fInnerHTML = null;
}
function NewSwaraSpacerView ( block ) { this . fBlock = block ; this . fModel = null ; this . getSongBlock = function ( ) { return this . fBlock ; } this . previousSwara = function ( ) { var prevS = this . prevSelectable ( ) ; while ( prevS ) { if ( prevS . partType ( ) == ROWVIEWPART_SWARA ) break ; prev = prev . prevSelectable ( ) ; } return prevS ; } this . getModel = function ( ) { var p = null ; var pm = null ; var prevS = this . previousSwara ( ) ; if ( prevS ) pm = prevS . getModel ( ) ; if ( ! p ) { var speed = 0 ; if ( pm ) speed = pm . getSpeed ( ) ; else if ( this . rowView ( ) ) { speed = this . rowView ( ) . pageView ( ) . songView ( ) . getSong ( ) . getDefaultSpeed ( ) ; } if ( ! this . fModel ) this . fModel = new Swara ( "" , false , 0 , 1 , speed ) ; else { this . fModel . setOctave ( 0 ) ; this . fModel . setSpeed ( speed ) ; } } else { if ( ! this . fModel ) this . fModel = new Swara ( "" , false , p . getOctave ( ) , 1 , p . getSpeed ( ) ) ; else { this . fModel . setOctave ( p . setOctave ) ; this . fModel . setSpeed ( p . setSpeed ) ; } } return this . fModel ; } this . onselect = function ( ) { var m = this . getModel ( ) ; EventManager . postEvent ( EventManager . EVENT_NEWSWARASPACER_SELECTED , this , m ) ; } this . insertMode = function ( ) { return NotationEditModeController . insertMode ( ) ; } this . editingInserted = function ( ) { return this . fSelected ; } this . renderInner = function ( wholeAsHTML , nCols ) { this . fNCols = nCols ; var s = new Array ( ) ; var i = 0 ; s [ i ++ ] = '<div class="sselem" style="padding-top:6px;width:100%;height:100%"><div class="newswaraspacer" style="' ; if ( theSongView . isInteractive ( ) ) s [ i ++ ] = 'cursor pointer;' ; else s [ i ++ ] = 'cursor:default;' ; s [ i ++ ] = 'border:thin solid ' ; s [ i ++ ] = this . fBackgroundColor ; s [ i ++ ] = ';width:0.63em;">&nbsp;</div></div>' ; this . fInnerHTML = s . join ( "" ) ; return this . fInnerHTML ; } this . render = function ( row , partInRow , cellidx ) { if ( ! partInRow ) partInRow = 0 ; if ( ! this . fInnerHTML ) return null ; var ret = row . addDOMCell ( false , partInRow , null , this . fNCols , cellidx ) ; var td = ret . td ; cellidx = ret . cellidx ; td . innerHTML = this . generateHTML ( row , partInRow ) ; this . fInnerHTML = null ; this . attach ( td , cellidx ) ; row . addPart ( this ) ; return td ; } this . renderAsHTML = function ( row , partInRow ) { var s = this . generateHTML ( row , partInRow ) ; row . addDOMCellAsHTML ( false , partInRow , s ) ; this . fInnerHTML = null ; row . addPart ( this ) ; } this . generateHTML = function ( row , partInRow , innerOnly ) { var s = new Array ( ) ; var i = 0 ; if ( ! innerOnly ) s [ i ++ ] = '<td colspan="' + this . fNCols + '" style="padding:0 0 0 0;">' ; s [ i ++ ] = '<table style="width:100%;padding:0 0 0 0;border-collapse:collapse;">' ; s [ i ++ ] = '<tr><td style="padding:0 0 0 0;">' ; s [ i ++ ] = '<div style="padding:0 0 0 0;overflow:hidden;height:' ; if ( row . haveGamakas ( ) ) s [ i ++ ] = row . getGamakaHeight ( ) + "px;" ; else s [ i ++ ] = "1px;display:none;" ; s [ i ++ ] = '"></div></td></tr>' ; s [ i ++ ] = '<tr><td style="padding:0 0 0 0">' ; s [ i ++ ] = this . fInnerHTML ; s [ i ++ ] = '</td>' ; s [ i ++ ] = '</tr></table>' ; if ( ! innerOnly ) s [ i ++ ] = '</td>' ; return s . join ( "" ) ; } this . attach = function ( td , cellidx ) { this . fTableCell = td ; td . id = Utils . getNewId ( "sw" ) ; Utils . addToIdMap ( td , this ) ; this . domid = td . id ; this . fCellIdx = cellidx ; var ow = Utils . _findNodeByClass ( td , "sselem" ) ; if ( ! ow ) return false ; this . fInner = ow ; var spacer = Utils . _findNodeByClass ( ow , "newswaraspacer" ) ; if ( ! spacer ) return false ; this . initSelectable ( spacer , true ) ; return true ; } this . fPartType = ROWVIEWPART_NEWSWARASPACER ; block = null ; this . fInnerHTML = null ; }
@class
 represents the view that is a place holder for appending new swaras
 <p>
 <b>Rendering</b>: There are 2 kinds of rendering
 <ul>
 <li> the progressive rendering used in WYSIWYG mode where rendering creates
 the actual DOM elements for the heading - done by {@link NewSwaraSpacerView#render}
 <li> non-progressive rendering used in start-up where render simply generates
 the HTML content in a string.
@class represents the view that is a place holder for appending new swaras <p > <b > Rendering< / b > : There are 2 kinds of rendering <ul > <li > the progressive rendering used in WYSIWYG mode where rendering creates the actual DOM elements for the heading - done by { @link NewSwaraSpacerView#render } <li > non - progressive rendering used in start - up where render simply generates the HTML content in a string .
// we are selectable ONLY in insert mode
 //this.isSelectable = function() { return NotationEditModeController.insertMode(); }
 /**
     * the block to which new swara spacer belongs to (i.e. swaras added using the
     * spacer would get added to this block
     * @type SongBlock
     * @private
     */ /**
     * a dummy swara model on which spacer is based up
     * @type Swara
     * @private
     */ /**
     * get the song block associated with the swara spacer
     */ /**
     * get previous swara in the same row as the spacer (if any)
     * @return previous swara in the same row as the spacer (if any)
     * @type SwaraView
     */ /**
     * get the underlying model
     * @return the underlying model
     * @type Swara
     */ /**
     * called by the base-class when this view is selected
     */ /**
     * override of {@link SelectableRowViewPart#insertMode} to indicate
     * if we are in insert mode for swaras
     */ // we are always in insert mode
 // return true;
 /**
     * override of {@link SelectableRowViewPart#editingInserted} to indicate
     * if are we still editing the object we just inserted
     */ // we will never be in a mode where we have a valid swara which was
 // inserted and user is editing it.
 /**
     * generate the HTML contents for the inner part of the spacer as div - this
     * inner part is meant to go into a table cell (renderd by call to 
     * {@link NewSwaraSpacerView#render} or {@link NewSwaraSpacerView#renderAsHTML})
     * <p>
     * The inner content is saved in a hold area and used later during render.
     *
     * @param {boolean} wholeAsHTML	(IGNORED) are we generating the whole cell 
     *					(as opposed to just inner contents) as HTML?
     *
     * @param {int}  nCols	 	the column span of the spacer (used later
     *				 	when render is called)
     * @return NOTHING MEANINGFUL
     */ // padding 6: kludge to account for speed rows
 /**
     * render the view contents inside a table cell on a row-view
     * @param {SwaraLyricRow}	row		the row-view
     * @param {int}		partInRow	the nth tala part in this row
     *						to which this view goes into
     * @param {int}		cellidx		overall cell (column) index in
     *						the row
     * @return the table cell
     * @type DOMElement_TD
     */ // renderInner not called
 // generate and set inner content
 // add ourselves to the row
 /**
     * generate HTML content for entire swara view (table-cell) - assumes
     * renderInner is already called
     * <p>
     * The contents are added to the hold area of the row
     *
     * @param {SwaraLyricRowView } rowview   the row view
     * @param {int} 		   partInRow n as in nth tala part in the row 
     */ // add speeds
 // join the contents and add it the hold area of our row
 // add ourselves to the row
 /**
     * generate the HTML contents of this view as a string and return it
     * @param {SwaraLyricRowView } rowview   the row view
     * @param {int} 		   partInRow n as in nth tala part in the row 
     * @param {boolean} innerOnly	generate only inner content
     * @type String
     * @return the HTML contents of the view
     */ // add speeds
 // smallest
 // VERY IMPORTANT for speed markers to be continous across swaras
 // filler: a width a MUST for IE (no adverse affects on FireFox)
 // a % value doesnt work on IE as it may expand table
 // DOES NOT WORK NICELY 
 //s[i++] = '<td style="width:100%;overflow:hidden;"></td>';
 /**
     * attach ourselves to a table-cell whose HTML content we generated earlier
     */ // td.view     = this; 
 // set table cell
 /**
     * @ignore
     */ /**
     * Hold area for inner HTML content - populated by 
     * {@link NewSwaraSpacerView#renderInner} and later used during rendering
     *
     * @type String
     * @private
     */