Rationalize button disabling/enabling throughout UI
[scpubgit/stemmaweb.git] / root / js / detach_helpers.js
1 function edges_of( ellipse ) {
2   var edges = new Array();
3   var node_id = ellipse.parent().attr('id');
4   var edge_outgoing_pattern = new RegExp( '^' + node_id + '-' );
5   var edge_incoming_pattern = new RegExp( node_id + '$' );
6   $.each( $('#svgenlargement .edge'), function(index) {
7       title = $(this).children('title').text();
8       if( edge_outgoing_pattern.test(title) || edge_incoming_pattern.test(title) ) {
9           var edge = new Edge( $(this) );
10           edge.node_id = node_id;
11           if( edge_incoming_pattern.test(title) ) {
12               edge.is_incoming  = true;
13           }
14           edges.push( edge );
15       }
16   } );
17   return edges;
18 }
19
20 function Edge( g_elem ) {
21     
22     var self = this;
23     
24     this.g_elem = g_elem;
25     this.witnesses = g_elem.children('text').text().split( /,\s*/ );
26     this.is_incoming = false;
27     this.start_node_id = g_elem.children('title').text().split('-')[0];
28     this.end_node_id = g_elem.children('title').text().split('>')[1];
29     
30     this.detach_witnesses = function( witnesses_to_detach ) {
31         var detached = [];
32         var left = '';
33         var clone = null;
34         $.each( witnesses_to_detach, function( index, witness_to_detach ) {
35             witness_index = self.witnesses.indexOf( witness_to_detach );
36             if( witness_index > -1 ) {  
37                 self.witnesses.splice( witness_index, 1 );
38                 detached.push( witness_to_detach );
39             }
40         } );
41         if( detached != '' ) {
42             clone = self.clone_for( detached );
43         }
44         var remaining = self.create_label( self.witnesses );
45         if( remaining == '' ) {
46             self.g_elem.remove();
47         } else {
48             self.g_elem.children('text').text( remaining );
49         }
50         return clone;
51     }
52     
53     this.get_label = function() {
54         return self.g_elem.children('text').text();
55     }
56     
57     this.create_label = function( witnesses ) {
58         var label = '';
59         $.each( witnesses, function( index, witness ) {
60             label = label + witness + ', ';
61         } );
62         label = label.replace( /, $/, '' );
63         return label;
64     }
65     
66     this.clone_for = function( witnesses ) {
67         var label = self.create_label( witnesses );
68         var clone = g_elem.clone();
69         clone.children('text').text( label );
70         var duplicate_data = g_elem.data( 'repositioned' );
71         if( duplicate_data != null ) {
72             clone.data( 'repositioned', duplicate_data );
73         }
74         clone = new Edge( clone );        
75         clone.is_incoming = self.is_incoming;
76         return clone;
77     }
78     
79     this.attach_witnesses = function( witnesses ) {
80         self.witnesses = self.witnesses.concat( witnesses );
81         self.g_elem.children( 'text' ).text( self.create_label( self.witnesses ) );
82         var edge_weight = 0.8 + ( 0.2 * self.witnesses.length );
83         self.g_elem.children( 'path' ).attr( 'stroke-width', edge_weight );
84     }
85     
86     this.attach_endpoint = function( target_node_id ) {
87         // first let's find out if the startpoint might also be linked to the target already
88         // in that case we need to remove this edge and transfer the witnesses to the 
89         // appropriate edge of the target_node
90         $.each( edges_of( get_ellipse( target_node_id ) ), function( index, target_edge ) {
91             if( (self != null) && (target_edge.is_incoming == true) ) {
92                 if( self.start_node_id == target_edge.start_node_id) {
93                     target_edge.attach_witnesses( self.witnesses );
94                     self.g_elem.remove();
95                     self = null;
96                 }
97             }
98         } );
99         // if not let's really move the end pointer towards the target node
100         if( self != null ) {
101             var polygon = self.g_elem.children( 'polygon' ); 
102             if( polygon.size() > 0 ) {
103                 var end_point_arrowhead = new svgshape( polygon );
104                 var path_segments = self.g_elem.children('path')[0].pathSegList;
105                 var edge_path = new svgpath( path_segments.getItem(path_segments.numberOfItems - 1), self.g_elem.children('path') );
106                 var target_ellipse = get_ellipse( target_node_id );
107                 var target_cx = parseFloat( target_ellipse.attr( 'cx' ) );
108                 var target_cy = parseFloat( target_ellipse.attr( 'cy' ) );
109                 var target_rx = parseFloat( target_ellipse.attr( 'rx' ) );
110                 var source_ellipse = get_ellipse( self.end_node_id );
111                 var source_cx = parseFloat( source_ellipse.attr( 'cx' ) );
112                 var source_cy = parseFloat( source_ellipse.attr( 'cy' ) );
113                 var source_rx = parseFloat( source_ellipse.attr( 'rx' ) );
114                 var dx = (target_cx - target_rx) - (source_cx - source_rx);
115                 var dy = (target_cy - source_cy);
116                 end_point_arrowhead.reposition( dx, dy );
117                 edge_path.reposition( dx, dy );
118                 // var new_title = g_elem.children('title').text().replace( self.end_node_id, target_node_id );
119                 // console.log( new_title );
120             }
121         }
122     }
123
124     this.attach_startpoint = function( target_node_id ) {
125         // first let's find out if the endpoint might also be linked to the target already
126         // in that case we need to remove this edge and transfer the witnesses to the 
127         // appropriate edge of the target_node
128         $.each( edges_of( get_ellipse( target_node_id ) ), function( index, target_edge ) {
129             if( (self != null) && (target_edge.is_incoming != true ) ) {
130                 if( self.end_node_id == target_edge.end_node_id) {
131                     target_edge.attach_witnesses( self.witnesses );
132                     self.g_elem.remove();
133                     self = null;
134                 }
135             }
136         } );
137         // if not let's really move the start point towards the target node
138         if( self != null ) {
139             var path_segments = self.g_elem.children('path')[0].pathSegList;                
140             var edge_path = new svgpath( path_segments.getItem(0), self.g_elem.children('path') );
141             var target_ellipse = get_ellipse( target_node_id );
142             var target_cx = parseFloat( target_ellipse.attr( 'cx' ) );
143             var target_cy = parseFloat( target_ellipse.attr( 'cy' ) );
144             var target_rx = parseFloat( target_ellipse.attr( 'rx' ) );
145             var source_ellipse = get_ellipse( self.start_node_id );
146             var source_cx = parseFloat( source_ellipse.attr( 'cx' ) );
147             var source_cy = parseFloat( source_ellipse.attr( 'cy' ) );
148             var source_rx = parseFloat( source_ellipse.attr( 'rx' ) );
149             var dx = (target_cx + target_rx) - (source_cx + source_rx);
150             var dy = (target_cy - source_cy);
151             edge_path.reposition( dx, dy );
152         }
153     }
154     
155 }