function SelectableRowViewPart()
{
    /**
     * is this row view part selectable? The  answer is true for a 
     * selectable row view part
     * @return true or false as to whether this row view part is selectable
     * @type boolean
     */
    this.isSelectable = function() { return true; }

    /**
     * return the next view element in the same row as this one which is selectable
     * @return the next view element in the same row as this one which is selectable
     *         or null if there is no such element
     *
     * @type SelectableRowViewPart
     */
    this.nextSelectable = function() {
	var obj = this.next;
	while( obj != null ) {
	    if( obj != null && obj.isSelectable() )
		break;
	    obj = obj.next;	    
	}
	return obj;
    }

    /**
     * return the previous view element in the same row as this one which is selectable
     * @return the previous view element in the same row as this one which is selectable
     *         or null if there is no such element
     * @type SelectableRowViewPart
     */
    this.prevSelectable = function() {
	var obj = this.prev;
	while( obj != null ) {
	    if( obj != null && obj.isSelectable() )
		break;
	    obj = obj.prev;	    
	}
	return obj;
    }

    /**
     * (protected) are we in insert mode? Derived classes meant to override this to 
     * allow insert mode @return true if insert mode is supported, false otherwise
     * @type boolean
     */
    this.insertMode = function() { return false; }

    /**
     * (protected) while in insert mode, are we still editing the object we just
     * inserted
     */
    this.editingInserted = function() { return false; }

    /**
     * select or deselect this swara
     * @param {boolean} val	true or false indicating if view should be selected or deselected
     */
    this.select = function(val,highlight) {
	this.fSelected = val;
	this.fHighlighted = ((highlight) ? true : false);
	this.updateSelection(highlight);
	if( this.fSelected ) this.onselect();
	return true;
    }

    /**
     * update appearance based on selection change
     */
    this.updateSelection = function() {
	if( this.fSelectableElem ) {
	    if( this.isSelectable() && this.fSelected ) {
		    if( this.editingInserted() ) {
			this.fSelectableElem.style.border = "thin solid #0000ff";	// blue border
			this.fSelectableElem.style.background = LookAndFeel.url("insert-caret.gif") + ' bottom right no-repeat';
		    }
		    else if( this.insertMode() ) {
			this.fSelectableElem.style.border     = "thin solid "+ this.fBackgroundColor;
			this.fSelectableElem.style.background = LookAndFeel.url("insert-caret.gif") + ' bottom left no-repeat';
		    }

		else {
		    if( this.fHighlighted ) {
			this.fSelectableElem.style.border     = "thin solid "+ this.fBackgroundColor;
			this.fSelectableElem.style.background = "yellow";
		    }
		    else {
			this.fSelectableElem.style.border = "thin solid #0000ff";	// blue border
			this.fSelectableElem.style.background = "none";
		    }
		}
	    }
	    else {
		this.fSelectableElem.style.border     = "thin solid "+ this.fBackgroundColor;
		this.fSelectableElem.style.background = "none";
	    }
	}
    }

    /**
     * called when background color changes
     * @protected
     */
    this.baseOnBackgroundColorChange = this.onBackgroundColorChange;
    this.onBackgroundColorChange = function() {
	this.baseOnBackgroundColorChange();
	if( this.fSelectableElem )  {
	    this.fSelectableElem.style.backgroundColor = this.fBackgroundColor;
	    this.updateSelection();
	}
    }

    /**
     * (protected) called when the view is selected - derived classes can override
     * this to implement view specific functionality
     * @private
     */
    this.onselect = function() {
    }

    /**
     * (protected) event handler called when mouse enters this view - derived classes
     * should set this as the hover function for the approp dom elem in the view
     * to provide visual indication that item is selectable
     * @private
     */
    function labelHoverEnter() {
	var view = this; 
	if( view && view.isSelectable() && !view.fSelected && view.fSelectableElem ) {
	    if( view.insertMode()  )
		view.fSelectableElem.style.background = LookAndFeel.url("insert-caret-light.png") + ' bottom left no-repeat';
	    else {
		view.fSelectableElem.style.background = "none";
		view.fSelectableElem.style.border = "thin solid #000000";
	    }
	}
    }
    this.labelHoverEnter = labelHoverEnter;

    /**
     * event handler called when mouse leaves this view
     */
    function labelHoverExit() {
	var view = this;
	if( view && view.isSelectable() && !view.fSelected && view.fSelectableElem ) {
	    view.fSelectableElem.style.background = "none";
	    view.fSelectableElem.style.border = "thin solid " + view.fBackgroundColor;
	}
    }
    this.labelHoverExit = labelHoverExit;

    /**
     * event handler called when mouse is clicked on this view
     */
    function labelClicked(e) {
	if(!e )
	    e = event;
	var view = this;
	if( view && view.isSelectable() ) {
	    if(e.shiftKey == true )
		view.shiftClicked();
	    else if(e.controlKey == true )
		view.controlClicked();
	    else
		view.clicked();
	    //e.cancelBubble = true;
	    //if( e.stopProgapation ) e.stopPropagation();
	}
    }
    this.labelClicked = labelClicked;

    /**
     * called when this view is clicked on by the mouse
     */
    this.clicked = function() {
	var songView = this.rowView().pageView().songView();
	songView.selectObject(this);
    }

    /**
     * called when this view is clicked on by the mouse with shift key down
     */
    this.shiftClicked = function() {
	// default is to treat as a click
	this.clicked();
    }

    /**
     * called when this view is clicked on by the mouse with shift key down
     */
    this.controlClicked = function() {
	// default is to treat as a click
	this.clicked();
    }

    /**
     * set the select mode to "highlight" (as opposed normal => to box around)
     * Should call before initSelectable
     */
    this.setHighlightSelectMode = function(val) {
	    this.fNormalSelectMode = !val;
    }


    /**
     * set the text color of the view
     * @param {String} color	the text color of the view as a string usable
     *				in a css style
     */
    this.setColor = function(color)  {
	this.fColor = color;
	this.oncolorChange();
    }

    /**
     * (protected) called when text color is changed - derived classes can override this
     * @private
     */
    this.oncolorChange = function() {
    }

    /**
     * (protected) derived classes must call this on rendering to enable
     * selectability
     * @param {DOMElement}	the element that is selectable
     * @param {boolean}	   dontSetStyle	   if true, dont set style elem
     */
    this.initSelectable = function(selectableElem, dontSetStyle) {
	//if(!theSongView.isInteractive()) return; // if not interactive, nothing is selected
	this.fSelectableElem       = selectableElem;
	selectableElem.onmousedown = _labelClicked;
	selectableElem.onmouseover = _labelHoverEnter;
	selectableElem.onmouseout  = _labelHoverExit;
	selectableElem.id          = Utils.getNewId("sel"+this.partType());
	Utils.addToIdMap(selectableElem, this);
	// selectableElem.view        = this;
	if(!dontSetStyle) {
	    selectableElem.style.border = "thin solid " + this.fBackgroundColor;
	}
    }

    /**
     * (protected) the DOM element of the content that contains the selectable part (derived classes
     * should set this appropriately on rendering)
     * @type DOMElement
     * @private
     */
    this.fSelectableElem= null;


    /**
     * (protected) the text color of this view as a string one would specify in css style
     * @type String
     * @private
     */
    this.fColor = "#000000";

    this.fNormalSelectMode = true;

}
/**
 * @class
 * base class represents a selectable row view part, which would be part of a {@link SwaraLyricRowView}
 */
@class
base class represents a selectable row view part, which would be part of a  SwaraLyricRowView
@class base class represents a selectable row view part which would be part of a SwaraLyricRowView
function SelectableRowViewPart()
{
    this.isSelectable = function() { return true; }
    this.nextSelectable = function() {
	var obj = this.next;
	while( obj != null ) {
	    if( obj != null && obj.isSelectable() )
		break;
	    obj = obj.next;	    
	}
	return obj;
    }
    this.prevSelectable = function() {
	var obj = this.prev;
	while( obj != null ) {
	    if( obj != null && obj.isSelectable() )
		break;
	    obj = obj.prev;	    
	}
	return obj;
    }
    this.insertMode = function() { return false; }
    this.editingInserted = function() { return false; }
    this.select = function(val,highlight) {
	this.fSelected = val;
	this.fHighlighted = ((highlight) ? true : false);
	this.updateSelection(highlight);
	if( this.fSelected ) this.onselect();
	return true;
    }
    this.updateSelection = function() {
	if( this.fSelectableElem ) {
	    if( this.isSelectable() && this.fSelected ) {
		    if( this.editingInserted() ) {
			this.fSelectableElem.style.border = "thin solid #0000ff";	
			this.fSelectableElem.style.background = LookAndFeel.url("insert-caret.gif") + ' bottom right no-repeat';
		    }
		    else if( this.insertMode() ) {
			this.fSelectableElem.style.border     = "thin solid "+ this.fBackgroundColor;
			this.fSelectableElem.style.background = LookAndFeel.url("insert-caret.gif") + ' bottom left no-repeat';
		    }
		else {
		    if( this.fHighlighted ) {
			this.fSelectableElem.style.border     = "thin solid "+ this.fBackgroundColor;
			this.fSelectableElem.style.background = "yellow";
		    }
		    else {
			this.fSelectableElem.style.border = "thin solid #0000ff";	
			this.fSelectableElem.style.background = "none";
		    }
		}
	    }
	    else {
		this.fSelectableElem.style.border     = "thin solid "+ this.fBackgroundColor;
		this.fSelectableElem.style.background = "none";
	    }
	}
    }
    this.baseOnBackgroundColorChange = this.onBackgroundColorChange;
    this.onBackgroundColorChange = function() {
	this.baseOnBackgroundColorChange();
	if( this.fSelectableElem )  {
	    this.fSelectableElem.style.backgroundColor = this.fBackgroundColor;
	    this.updateSelection();
	}
    }
    this.onselect = function() {
    }
    function labelHoverEnter() {
	var view = this; 
	if( view && view.isSelectable() && !view.fSelected && view.fSelectableElem ) {
	    if( view.insertMode()  )
		view.fSelectableElem.style.background = LookAndFeel.url("insert-caret-light.png") + ' bottom left no-repeat';
	    else {
		view.fSelectableElem.style.background = "none";
		view.fSelectableElem.style.border = "thin solid #000000";
	    }
	}
    }
    this.labelHoverEnter = labelHoverEnter;
    function labelHoverExit() {
	var view = this;
	if( view && view.isSelectable() && !view.fSelected && view.fSelectableElem ) {
	    view.fSelectableElem.style.background = "none";
	    view.fSelectableElem.style.border = "thin solid " + view.fBackgroundColor;
	}
    }
    this.labelHoverExit = labelHoverExit;
    function labelClicked(e) {
	if(!e )
	    e = event;
	var view = this;
	if( view && view.isSelectable() ) {
	    if(e.shiftKey == true )
		view.shiftClicked();
	    else if(e.controlKey == true )
		view.controlClicked();
	    else
		view.clicked();
	}
    }
    this.labelClicked = labelClicked;
    this.clicked = function() {
	var songView = this.rowView().pageView().songView();
	songView.selectObject(this);
    }
    this.shiftClicked = function() {
	this.clicked();
    }
    this.controlClicked = function() {
	this.clicked();
    }
    this.setHighlightSelectMode = function(val) {
	    this.fNormalSelectMode = !val;
    }
    this.setColor = function(color)  {
	this.fColor = color;
	this.oncolorChange();
    }
    this.oncolorChange = function() {
    }
    this.initSelectable = function(selectableElem, dontSetStyle) {
	this.fSelectableElem       = selectableElem;
	selectableElem.onmousedown = _labelClicked;
	selectableElem.onmouseover = _labelHoverEnter;
	selectableElem.onmouseout  = _labelHoverExit;
	selectableElem.id          = Utils.getNewId("sel"+this.partType());
	Utils.addToIdMap(selectableElem, this);
	if(!dontSetStyle) {
	    selectableElem.style.border = "thin solid " + this.fBackgroundColor;
	}
    }
    this.fSelectableElem= null;
    this.fColor = "#000000";
    this.fNormalSelectMode = true;
}
function SelectableRowViewPart ( ) { this . isSelectable = function ( ) { return true ; } this . nextSelectable = function ( ) { var obj = this . next ; while ( obj != null ) { if ( obj != null && obj . isSelectable ( ) ) break ; obj = obj . next ; } return obj ; } this . prevSelectable = function ( ) { var obj = this . prev ; while ( obj != null ) { if ( obj != null && obj . isSelectable ( ) ) break ; obj = obj . prev ; } return obj ; } this . insertMode = function ( ) { return false ; } this . editingInserted = function ( ) { return false ; } this . select = function ( val , highlight ) { this . fSelected = val ; this . fHighlighted = ( ( highlight ) ? true : false ) ; this . updateSelection ( highlight ) ; if ( this . fSelected ) this . onselect ( ) ; return true ; } this . updateSelection = function ( ) { if ( this . fSelectableElem ) { if ( this . isSelectable ( ) && this . fSelected ) { if ( this . editingInserted ( ) ) { this . fSelectableElem . style . border = "thin solid #0000ff" ; this . fSelectableElem . style . background = LookAndFeel . url ( "insert-caret.gif" ) + ' bottom right no-repeat' ; } else if ( this . insertMode ( ) ) { this . fSelectableElem . style . border = "thin solid " + this . fBackgroundColor ; this . fSelectableElem . style . background = LookAndFeel . url ( "insert-caret.gif" ) + ' bottom left no-repeat' ; } else { if ( this . fHighlighted ) { this . fSelectableElem . style . border = "thin solid " + this . fBackgroundColor ; this . fSelectableElem . style . background = "yellow" ; } else { this . fSelectableElem . style . border = "thin solid #0000ff" ; this . fSelectableElem . style . background = "none" ; } } } else { this . fSelectableElem . style . border = "thin solid " + this . fBackgroundColor ; this . fSelectableElem . style . background = "none" ; } } } this . baseOnBackgroundColorChange = this . onBackgroundColorChange ; this . onBackgroundColorChange = function ( ) { this . baseOnBackgroundColorChange ( ) ; if ( this . fSelectableElem ) { this . fSelectableElem . style . backgroundColor = this . fBackgroundColor ; this . updateSelection ( ) ; } } this . onselect = function ( ) { } function labelHoverEnter ( ) { var view = this ; if ( view && view . isSelectable ( ) && ! view . fSelected && view . fSelectableElem ) { if ( view . insertMode ( ) ) view . fSelectableElem . style . background = LookAndFeel . url ( "insert-caret-light.png" ) + ' bottom left no-repeat' ; else { view . fSelectableElem . style . background = "none" ; view . fSelectableElem . style . border = "thin solid #000000" ; } } } this . labelHoverEnter = labelHoverEnter ; function labelHoverExit ( ) { var view = this ; if ( view && view . isSelectable ( ) && ! view . fSelected && view . fSelectableElem ) { view . fSelectableElem . style . background = "none" ; view . fSelectableElem . style . border = "thin solid " + view . fBackgroundColor ; } } this . labelHoverExit = labelHoverExit ; function labelClicked ( e ) { if ( ! e ) e = event ; var view = this ; if ( view && view . isSelectable ( ) ) { if ( e . shiftKey == true ) view . shiftClicked ( ) ; else if ( e . controlKey == true ) view . controlClicked ( ) ; else view . clicked ( ) ; } } this . labelClicked = labelClicked ; this . clicked = function ( ) { var songView = this . rowView ( ) . pageView ( ) . songView ( ) ; songView . selectObject ( this ) ; } this . shiftClicked = function ( ) { this . clicked ( ) ; } this . controlClicked = function ( ) { this . clicked ( ) ; } this . setHighlightSelectMode = function ( val ) { this . fNormalSelectMode = ! val ; } this . setColor = function ( color ) { this . fColor = color ; this . oncolorChange ( ) ; } this . oncolorChange = function ( ) { } this . initSelectable = function ( selectableElem , dontSetStyle ) { this . fSelectableElem = selectableElem ; selectableElem . onmousedown = _labelClicked ; selectableElem . onmouseover = _labelHoverEnter ; selectableElem . onmouseout = _labelHoverExit ; selectableElem . id = Utils . getNewId ( "sel" + this . partType ( ) ) ; Utils . addToIdMap ( selectableElem , this ) ; if ( ! dontSetStyle ) { selectableElem . style . border = "thin solid " + this . fBackgroundColor ; } } this . fSelectableElem = null ; this . fColor = "#000000" ; this . fNormalSelectMode = true ; }
@class
 base class represents a selectable row view part, which would be part of a {@link SwaraLyricRowView}
@class base class represents a selectable row view part which would be part of a { @link SwaraLyricRowView }
/**
     * is this row view part selectable? The  answer is true for a 
     * selectable row view part
     * @return true or false as to whether this row view part is selectable
     * @type boolean
     */ /**
     * return the next view element in the same row as this one which is selectable
     * @return the next view element in the same row as this one which is selectable
     *         or null if there is no such element
     *
     * @type SelectableRowViewPart
     */ /**
     * return the previous view element in the same row as this one which is selectable
     * @return the previous view element in the same row as this one which is selectable
     *         or null if there is no such element
     * @type SelectableRowViewPart
     */ /**
     * (protected) are we in insert mode? Derived classes meant to override this to 
     * allow insert mode @return true if insert mode is supported, false otherwise
     * @type boolean
     */ /**
     * (protected) while in insert mode, are we still editing the object we just
     * inserted
     */ /**
     * select or deselect this swara
     * @param {boolean} val	true or false indicating if view should be selected or deselected
     */ /**
     * update appearance based on selection change
     */ // blue border
 // blue border
 /**
     * called when background color changes
     * @protected
     */ /**
     * (protected) called when the view is selected - derived classes can override
     * this to implement view specific functionality
     * @private
     */ /**
     * (protected) event handler called when mouse enters this view - derived classes
     * should set this as the hover function for the approp dom elem in the view
     * to provide visual indication that item is selectable
     * @private
     */ /**
     * event handler called when mouse leaves this view
     */ /**
     * event handler called when mouse is clicked on this view
     */ //e.cancelBubble = true;
 //if( e.stopProgapation ) e.stopPropagation();
 /**
     * called when this view is clicked on by the mouse
     */ /**
     * called when this view is clicked on by the mouse with shift key down
     */ // default is to treat as a click
 /**
     * called when this view is clicked on by the mouse with shift key down
     */ // default is to treat as a click
 /**
     * set the select mode to "highlight" (as opposed normal => to box around)
     * Should call before initSelectable
     */ /**
     * set the text color of the view
     * @param {String} color	the text color of the view as a string usable
     *				in a css style
     */ /**
     * (protected) called when text color is changed - derived classes can override this
     * @private
     */ /**
     * (protected) derived classes must call this on rendering to enable
     * selectability
     * @param {DOMElement}	the element that is selectable
     * @param {boolean}	   dontSetStyle	   if true, dont set style elem
     */ //if(!theSongView.isInteractive()) return; // if not interactive, nothing is selected
 // selectableElem.view        = this;
 /**
     * (protected) the DOM element of the content that contains the selectable part (derived classes
     * should set this appropriately on rendering)
     * @type DOMElement
     * @private
     */ /**
     * (protected) the text color of this view as a string one would specify in css style
     * @type String
     * @private
     */