Roo/bootstrap/LayoutMasonry.js
[roojs1] / Roo / bootstrap / LayoutMasonry.js
1 /**
2  *
3  * This is based on 
4  * http://masonry.desandro.com
5  *
6  * The idea is to render all the bricks based on vertical width...
7  *
8  * The original code extends 'outlayer' - we might need to use that....
9  * 
10  */
11
12
13 /**
14  * @class Roo.bootstrap.LayoutMasonry
15  * @extends Roo.bootstrap.Component
16  * Bootstrap Layout Masonry class
17  * 
18  * @constructor
19  * Create a new Element
20  * @param {Object} config The config object
21  */
22
23 Roo.bootstrap.LayoutMasonry = function(config){
24     Roo.bootstrap.LayoutMasonry.superclass.constructor.call(this, config);
25     
26     this.bricks = [];
27     
28 };
29
30 Roo.extend(Roo.bootstrap.LayoutMasonry, Roo.bootstrap.Component,  {
31     
32     /**
33      * @cfg {Boolean} isLayoutInstant = no animation?
34      */   
35     isLayoutInstant : false, // needed?
36    
37     /**
38      * @cfg {Number} boxWidth  width of the columns
39      */   
40     boxWidth : 450,
41     
42     /**
43      * @cfg {Number} padWidth padding below box..
44      */   
45     padWidth : 10, 
46     
47     /**
48      * @cfg {Number} gutter gutter width..
49      */   
50     gutter : 10, 
51     
52     /**
53      * @cfg {Boolean} isAutoInitial defalut true
54      */   
55     isAutoInitial : true, 
56     
57     containerWidth: 0,
58     
59     /**
60      * @cfg {Boolean} isHorizontal defalut false
61      */   
62     isHorizontal : false, 
63
64     currentSize : null,
65     
66     tag: 'div',
67     
68     cls: '',
69     
70     bricks: null, //CompositeElement
71     
72     cols : 1,
73     
74     _isLayoutInited : false,
75     
76 //    isAlternative : false, // only use for vertical layout...
77     
78     /**
79      * @cfg {Number} alternativePadWidth padding below box..
80      */   
81     alternativePadWidth : 50, 
82     
83     getAutoCreate : function(){
84         
85         var cfg = {
86             tag: this.tag,
87             cls: 'blog-masonary-wrapper ' + this.cls,
88             cn : {
89                 cls : 'mas-boxes masonary'
90             }
91         };
92         
93         return cfg;
94     },
95     
96     getChildContainer: function( )
97     {
98         if (this.boxesEl) {
99             return this.boxesEl;
100         }
101         
102         this.boxesEl = this.el.select('.mas-boxes').first();
103         
104         return this.boxesEl;
105     },
106     
107     
108     initEvents : function()
109     {
110         var _this = this;
111         
112         if(this.isAutoInitial){
113             Roo.log('hook children rendered');
114             this.on('childrenrendered', function() {
115                 Roo.log('children rendered');
116                 _this.initial();
117             } ,this);
118         }
119     },
120     
121     initial : function()
122     {
123         this.currentSize = this.el.getBox(true);
124         
125         Roo.EventManager.onWindowResize(this.resize, this); 
126
127         if(!this.isAutoInitial){
128             this.layout();
129             return;
130         }
131         
132         this.layout();
133         
134         return;
135         //this.layout.defer(500,this);
136         
137     },
138     
139     resize : function()
140     {
141         Roo.log('resize');
142         
143         var cs = this.el.getBox(true);
144         
145         if (this.currentSize.width == cs.width && this.currentSize.x == cs.x ) {
146             Roo.log("no change in with or X");
147             return;
148         }
149         
150         this.currentSize = cs;
151         
152         this.layout();
153         
154     },
155     
156     layout : function()
157     {   
158         this._resetLayout();
159         
160         var isInstant = this.isLayoutInstant !== undefined ? this.isLayoutInstant : !this._isLayoutInited;
161         
162         this.layoutItems( isInstant );
163       
164         this._isLayoutInited = true;
165         
166     },
167     
168     _resetLayout : function()
169     {
170         if(this.isHorizontal){
171             this.horizontalMeasureColumns();
172             return;
173         }
174         
175         this.verticalMeasureColumns();
176         
177     },
178     
179     verticalMeasureColumns : function()
180     {
181         this.getContainerWidth();
182         
183 //        if(Roo.lib.Dom.getViewWidth() < 768 && this.isAlternative){
184 //            this.colWidth = Math.floor(this.containerWidth * 0.8);
185 //            return;
186 //        }
187         
188         var boxWidth = this.boxWidth + this.padWidth;
189         
190         if(this.containerWidth < this.boxWidth){
191             boxWidth = this.containerWidth
192         }
193         
194         var containerWidth = this.containerWidth;
195         
196         var cols = Math.floor(containerWidth / boxWidth);
197         
198         this.cols = Math.max( cols, 1 );
199         
200         var totalBoxWidth = this.cols * boxWidth - this.padWidth;
201         
202         var avail = Math.floor((containerWidth - totalBoxWidth) / this.cols);
203         
204         this.colWidth = boxWidth + avail - this.padWidth;
205         
206         this.unitWidth = Math.floor((this.colWidth - (this.gutter * 2)) / 3);
207     },
208     
209     horizontalMeasureColumns : function()
210     {
211         this.getContainerWidth();
212         
213         var boxWidth = this.boxWidth;
214         
215         if(this.containerWidth < boxWidth){
216             boxWidth = this.containerWidth;
217         }
218         
219         this.unitWidth = Math.floor((boxWidth - (this.gutter * 2)) / 3);
220         
221         this.el.setHeight(boxWidth);
222         
223     },
224     
225     getContainerWidth : function()
226     {
227         this.containerWidth = this.el.getBox(true).width;  //maybe use getComputedWidth
228     },
229     
230     layoutItems : function( isInstant )
231     {
232         var items = Roo.apply([], this.bricks);
233         
234         if(this.isHorizontal){
235             this._horizontalLayoutItems( items , isInstant );
236             return;
237         }
238         
239 //        if(Roo.lib.Dom.getViewWidth() < 768 && this.isAlternative){
240 //            this._verticalAlternativeLayoutItems( items , isInstant );
241 //            return;
242 //        }
243         
244         this._verticalLayoutItems( items , isInstant );
245         
246     },
247     
248     _verticalLayoutItems : function ( items , isInstant)
249     {
250         if ( !items || !items.length ) {
251             return;
252         }
253         
254         var standard = [
255             ['xs', 'xs', 'xs', 'tall'],
256             ['xs', 'xs', 'tall'],
257             ['xs', 'xs', 'sm'],
258             ['xs', 'xs', 'xs'],
259             ['xs', 'tall'],
260             ['xs', 'sm'],
261             ['xs', 'xs'],
262             ['xs'],
263             
264             ['sm', 'xs', 'xs'],
265             ['sm', 'xs'],
266             ['sm'],
267             
268             ['tall', 'xs', 'xs', 'xs'],
269             ['tall', 'xs', 'xs'],
270             ['tall', 'xs'],
271             ['tall']
272         ];
273         
274         var queue = [];
275         
276         var boxes = [];
277         
278         var box = [];
279         
280         Roo.each(items, function(item, k){
281             
282             switch (item.size) {
283                 case 'md' :
284                 case 'md-left' :
285                 case 'md-right' :
286                 case 'wide' :
287                     
288                     if(box.length){
289                         boxes.push(box);
290                         box = [];
291                     }
292                     
293                     boxes.push([item]);
294                     
295                     break;
296                     
297                 case 'xs' :
298                 case 'sm' :
299                 case 'tall' :
300                     
301                     box.push(item);
302                     
303                     break;
304                 default :
305                     break;
306                     
307             }
308             
309         }, this);
310         
311         if(box.length){
312             boxes.push(box);
313             box = [];
314         }
315         
316         var filterPattern = function(box, length)
317         {
318             if(!box.length){
319                 return;
320             }
321             
322             var match = false;
323             
324             var pattern = box.slice(0, length);
325             
326             var format = [];
327             
328             Roo.each(pattern, function(i){
329                 format.push(i.size);
330             }, this);
331             
332             Roo.each(standard, function(s){
333                 
334                 if(String(s) != String(format)){
335                     return;
336                 }
337                 
338                 match = true;
339                 return false;
340                 
341             }, this);
342             
343             if(!match && length == 1){
344                 return;
345             }
346             
347             if(!match){
348                 filterPattern(box, length - 1);
349                 return;
350             }
351                 
352             queue.push(pattern);
353
354             box = box.slice(length, box.length);
355
356             filterPattern(box, 4);
357
358             return;
359             
360         }
361         
362         Roo.each(boxes, function(box, k){
363             
364             if(!box.length){
365                 return;
366             }
367             
368             if(box.length == 1){
369                 queue.push(box);
370                 return;
371             }
372             
373             filterPattern(box, 4);
374             
375         }, this);
376         
377         this._processVerticalLayoutQueue( queue, isInstant );
378         
379     },
380     
381 //    _verticalAlternativeLayoutItems : function( items , isInstant )
382 //    {
383 //        if ( !items || !items.length ) {
384 //            return;
385 //        }
386 //
387 //        this._processVerticalAlternativeLayoutQueue( items, isInstant );
388 //        
389 //    },
390     
391     _horizontalLayoutItems : function ( items , isInstant)
392     {
393         if ( !items || !items.length || items.length < 3) {
394             return;
395         }
396         
397         items.reverse();
398         
399         var eItems = items.slice(0, 3);
400         
401         items = items.slice(3, items.length);
402         
403         var pos = this.el.getBox(true);
404         
405         var minX = pos.x;
406         
407         var maxX = pos.right - this.unitWidth * 3 - this.gutter * 2 - this.padWidth;
408         
409         var standard = [
410             ['xs', 'xs', 'xs', 'wide'],
411             ['xs', 'xs', 'wide'],
412             ['xs', 'xs', 'sm'],
413             ['xs', 'xs', 'xs'],
414             ['xs', 'wide'],
415             ['xs', 'sm'],
416             ['xs', 'xs'],
417             ['xs'],
418             
419             ['sm', 'xs', 'xs'],
420             ['sm', 'xs'],
421             ['sm'],
422             
423             ['wide', 'xs', 'xs', 'xs'],
424             ['wide', 'xs', 'xs'],
425             ['wide', 'xs'],
426             ['wide']
427         ];
428         
429         var queue = [];
430         
431         var boxes = [];
432         
433         var box = [];
434         
435         Roo.each(items, function(item, k){
436             
437             switch (item.size) {
438                 case 'md' :
439                 case 'md-left' :
440                 case 'md-right' :
441                 case 'tall' :
442                     
443                     if(box.length){
444                         boxes.push(box);
445                         box = [];
446                     }
447                     
448                     boxes.push([item]);
449                     
450                     break;
451                     
452                 case 'xs' :
453                 case 'sm' :
454                 case 'wide' :
455                     
456                     box.push(item);
457                     
458                     break;
459                 default :
460                     break;
461                     
462             }
463             
464         }, this);
465         
466         if(box.length){
467             boxes.push(box);
468             box = [];
469         }
470         
471         var filterPattern = function(box, length)
472         {
473             if(!box.length){
474                 return;
475             }
476             
477             var match = false;
478             
479             var pattern = box.slice(0, length);
480             
481             var format = [];
482             
483             Roo.each(pattern, function(i){
484                 format.push(i.size);
485             }, this);
486             
487             Roo.each(standard, function(s){
488                 
489                 if(String(s) != String(format)){
490                     return;
491                 }
492                 
493                 match = true;
494                 return false;
495                 
496             }, this);
497             
498             if(!match && length == 1){
499                 return;
500             }
501             
502             if(!match){
503                 filterPattern(box, length - 1);
504                 return;
505             }
506                 
507             queue.push(pattern);
508
509             box = box.slice(length, box.length);
510
511             filterPattern(box, 4);
512
513             return;
514             
515         }
516         
517         Roo.each(boxes, function(box, k){
518             
519             if(!box.length){
520                 return;
521             }
522             
523             if(box.length == 1){
524                 queue.push(box);
525                 return;
526             }
527             
528             filterPattern(box, 4);
529             
530         }, this);
531         
532         
533         
534         
535         
536         
537         
538         var x = maxX;
539         
540         var queue = [];
541         
542         var box = [];
543         var size = 0;
544         var hit_end = false;
545         
546         Roo.each(items, function(item, k){
547             
548             item.el.setVisibilityMode(Roo.Element.DISPLAY);
549             item.el.show();
550             
551             if(hit_end){
552                 item.el.hide();
553                 return;
554             }
555             
556             if(size + item.y > 3){
557                 queue.push(box);
558                 box = [];
559                 size = 0;
560                 maxX = x;
561             }
562             
563             var width = Math.floor(this.unitWidth * item.x + (this.gutter * (item.x - 1)) + item.el.getPadding('lr'));
564             
565             x = Math.min(x, maxX - width - this.padWidth);
566             
567             if(x < minX){
568                 item.el.hide();
569                 hit_end = true;
570                 return;
571             }
572             
573             size = size + item.y;
574             
575             box.push(item);
576             
577             
578         }, this);
579         
580         if(box.length){
581             queue.push(box);
582         }
583         
584         this._processHorizontalLayoutQueue( queue, eItems, isInstant );
585     },
586     
587     /** Sets position of item in DOM
588     * @param {Element} item
589     * @param {Number} x - horizontal position
590     * @param {Number} y - vertical position
591     * @param {Boolean} isInstant - disables transitions
592     */
593     _processVerticalLayoutQueue : function( queue, isInstant )
594     {
595         var pos = this.el.getBox(true);
596         var x = pos.x;
597         var y = pos.y;
598         var maxY = [];
599         
600         for (var i = 0; i < this.cols; i++){
601             maxY[i] = pos.y;
602         }
603         
604         Roo.each(queue, function(box, k){
605             
606             var col = k % this.cols;
607             
608             Roo.each(box, function(b,kk){
609                 
610                 b.el.position('absolute');
611                 
612                 var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
613                 var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
614                 
615                 if(b.size == 'md-left' || b.size == 'md-right'){
616                     width = Math.floor(this.unitWidth * (b.x - 1) + (this.gutter * (b.x - 2)) + b.el.getPadding('lr'));
617                     height = Math.floor(this.unitWidth * (b.y - 1) + (this.gutter * (b.y - 2)) + b.el.getPadding('tb'));
618                 }
619                 
620                 b.el.setWidth(width);
621                 b.el.setHeight(height);
622                 
623             }, this);
624             
625             for (var i = 0; i < this.cols; i++){
626                 
627                 if(maxY[i] < maxY[col]){
628                     col = i;
629                     continue;
630                 }
631                 
632                 col = Math.min(col, i);
633                 
634             }
635             
636             x = pos.x + col * (this.colWidth + this.padWidth);
637             
638             y = maxY[col];
639             
640             var positions = [];
641             
642             switch (box.length){
643                 case 1 :
644                     positions = this.getVerticalOneBoxColPositions(x, y, box);
645                     break;
646                 case 2 :
647                     positions = this.getVerticalTwoBoxColPositions(x, y, box);
648                     break;
649                 case 3 :
650                     positions = this.getVerticalThreeBoxColPositions(x, y, box);
651                     break;
652                 case 4 :
653                     positions = this.getVerticalFourBoxColPositions(x, y, box);
654                     break;
655                 default :
656                     break;
657             }
658             
659             Roo.each(box, function(b,kk){
660                 
661                 b.el.setXY([positions[kk].x, positions[kk].y], isInstant ? false : true);
662                 
663                 var sz = b.el.getSize();
664                 
665                 maxY[col] = Math.max(maxY[col], positions[kk].y + sz.height + this.padWidth);
666                 
667             }, this);
668             
669         }, this);
670         
671         var mY = 0;
672         
673         for (var i = 0; i < this.cols; i++){
674             mY = Math.max(mY, maxY[i]);
675         }
676         
677         this.el.setHeight(mY - pos.y);
678         
679     },
680     
681 //    _processVerticalAlternativeLayoutQueue : function( items, isInstant )
682 //    {
683 //        var pos = this.el.getBox(true);
684 //        var x = pos.x;
685 //        var y = pos.y;
686 //        var maxX = pos.right;
687 //        
688 //        var maxHeight = 0;
689 //        
690 //        Roo.each(items, function(item, k){
691 //            
692 //            var c = k % 2;
693 //            
694 //            item.el.position('absolute');
695 //                
696 //            var width = Math.floor(this.colWidth + item.el.getPadding('lr'));
697 //
698 //            item.el.setWidth(width);
699 //
700 //            var height = Math.floor(this.colWidth * item.y / item.x + item.el.getPadding('tb'));
701 //
702 //            item.el.setHeight(height);
703 //            
704 //            if(c == 0){
705 //                item.el.setXY([x, y], isInstant ? false : true);
706 //            } else {
707 //                item.el.setXY([maxX - width, y], isInstant ? false : true);
708 //            }
709 //            
710 //            y = y + height + this.alternativePadWidth;
711 //            
712 //            maxHeight = maxHeight + height + this.alternativePadWidth;
713 //            
714 //        }, this);
715 //        
716 //        this.el.setHeight(maxHeight);
717 //        
718 //    },
719     
720     _processHorizontalLayoutQueue : function( queue, eItems, isInstant )
721     {
722         var pos = this.el.getBox(true);
723         
724         var minX = pos.x;
725         var minY = pos.y;
726         
727         var maxX = pos.right;
728         
729         this._processHorizontalEndItem(eItems, maxX, minX, minY, isInstant);
730         
731         var maxX = maxX - this.unitWidth * 3 - this.gutter * 2 - this.padWidth;
732         
733         Roo.each(queue, function(box, k){
734             
735             Roo.each(box, function(b, kk){
736                 
737                 b.el.position('absolute');
738                 
739                 var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
740                 var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
741                 
742                 if(b.size == 'md-left' || b.size == 'md-right'){
743                     width = Math.floor(this.unitWidth * (b.x - 1) + (this.gutter * (b.x - 2)) + b.el.getPadding('lr'));
744                     height = Math.floor(this.unitWidth * (b.y - 1) + (this.gutter * (b.y - 2)) + b.el.getPadding('tb'));
745                 }
746                 
747                 b.el.setWidth(width);
748                 b.el.setHeight(height);
749                 
750             }, this);
751             
752             if(!box.length){
753                 return;
754             }
755             
756             var positions = [];
757             
758             switch (box.length){
759                 case 1 :
760                     positions = this.getHorizontalOneBoxColPositions(maxX, minY, box);
761                     break;
762                 case 2 :
763                     positions = this.getHorizontalTwoBoxColPositions(maxX, minY, box);
764                     break;
765                 case 3 :
766                     positions = this.getHorizontalThreeBoxColPositions(maxX, minY, box);
767                     break;
768                 default :
769                     break;
770             }
771             
772             Roo.each(box, function(b,kk){
773                 
774                 b.el.setXY([positions[kk].x, positions[kk].y], isInstant ? false : true);
775                 
776                 maxX = Math.min(maxX, positions[kk].x - this.padWidth);
777                 
778             }, this);
779             
780         }, this);
781         
782     },
783     
784     _processHorizontalEndItem : function(eItems, maxX, minX, minY, isInstant)
785     {
786         Roo.each(eItems, function(b,k){
787             
788             b.size = (k == 0) ? 'sm' : 'xs';
789             b.x = (k == 0) ? 2 : 1;
790             b.y = (k == 0) ? 2 : 1;
791             
792             b.el.position('absolute');
793             
794             var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
795                 
796             b.el.setWidth(width);
797             
798             var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
799             
800             b.el.setHeight(height);
801             
802         }, this);
803
804         var positions = [];
805         
806         positions.push({
807             x : maxX - this.unitWidth * 2 - this.gutter,
808             y : minY
809         });
810         
811         positions.push({
812             x : maxX - this.unitWidth,
813             y : minY + (this.unitWidth + this.gutter) * 2
814         });
815         
816         positions.push({
817             x : maxX - this.unitWidth * 3 - this.gutter * 2,
818             y : minY
819         });
820         
821         Roo.each(eItems, function(b,k){
822             
823             b.el.setXY([positions[k].x, positions[k].y], isInstant ? false : true);
824
825         }, this);
826         
827     },
828     
829     getVerticalOneBoxColPositions : function(x, y, box)
830     {
831         var pos = [];
832         
833         var rand = Math.floor(Math.random() * ((4 - box[0].x)));
834         
835         if(box[0].size == 'md-left'){
836             rand = 0;
837         }
838         
839         if(box[0].size == 'md-right'){
840             rand = 1;
841         }
842         
843         pos.push({
844             x : x + (this.unitWidth + this.gutter) * rand,
845             y : y
846         });
847         
848         return pos;
849     },
850     
851     getVerticalTwoBoxColPositions : function(x, y, box)
852     {
853         var pos = [];
854         
855         if(box[0].size == 'xs'){
856             
857             pos.push({
858                 x : x,
859                 y : y + ((this.unitWidth + this.gutter) * Math.floor(Math.random() * box[1].y))
860             });
861
862             pos.push({
863                 x : x + (this.unitWidth + this.gutter) * (3 - box[1].x),
864                 y : y
865             });
866             
867             return pos;
868             
869         }
870         
871         pos.push({
872             x : x,
873             y : y
874         });
875
876         pos.push({
877             x : x + (this.unitWidth + this.gutter) * 2,
878             y : y + ((this.unitWidth + this.gutter) * Math.floor(Math.random() * box[0].y))
879         });
880         
881         return pos;
882         
883     },
884     
885     getVerticalThreeBoxColPositions : function(x, y, box)
886     {
887         var pos = [];
888         
889         if(box[0].size == 'xs' && box[1].size == 'xs' && box[2].size == 'xs'){
890             
891             pos.push({
892                 x : x,
893                 y : y
894             });
895
896             pos.push({
897                 x : x + (this.unitWidth + this.gutter) * 1,
898                 y : y
899             });
900             
901             pos.push({
902                 x : x + (this.unitWidth + this.gutter) * 2,
903                 y : y
904             });
905             
906             return pos;
907             
908         }
909         
910         if(box[0].size == 'xs' && box[1].size == 'xs'){
911             
912             pos.push({
913                 x : x,
914                 y : y
915             });
916
917             pos.push({
918                 x : x,
919                 y : y + ((this.unitWidth + this.gutter) * (box[2].y - 1))
920             });
921             
922             pos.push({
923                 x : x + (this.unitWidth + this.gutter) * 1,
924                 y : y
925             });
926             
927             return pos;
928             
929         }
930         
931         pos.push({
932             x : x,
933             y : y
934         });
935
936         pos.push({
937             x : x + (this.unitWidth + this.gutter) * 2,
938             y : y
939         });
940
941         pos.push({
942             x : x + (this.unitWidth + this.gutter) * 2,
943             y : y + (this.unitWidth + this.gutter) * (box[0].y - 1)
944         });
945             
946         return pos;
947         
948     },
949     
950     getVerticalFourBoxColPositions : function(x, y, box)
951     {
952         var pos = [];
953         
954         if(box[0].size == 'xs'){
955             
956             pos.push({
957                 x : x,
958                 y : y
959             });
960
961             pos.push({
962                 x : x,
963                 y : y + (this.unitWidth + this.gutter) * 1
964             });
965             
966             pos.push({
967                 x : x,
968                 y : y + (this.unitWidth + this.gutter) * 2
969             });
970             
971             pos.push({
972                 x : x + (this.unitWidth + this.gutter) * 1,
973                 y : y
974             });
975             
976             return pos;
977             
978         }
979         
980         pos.push({
981             x : x,
982             y : y
983         });
984
985         pos.push({
986             x : x + (this.unitWidth + this.gutter) * 2,
987             y : y
988         });
989
990         pos.push({
991             x : x + (this.unitWidth + this.gutter) * 2,
992             y : y + (this.unitWidth + this.gutter) * 1
993         });
994
995         pos.push({
996             x : x + (this.unitWidth + this.gutter) * 2,
997             y : y + (this.unitWidth + this.gutter) * 2
998         });
999
1000         return pos;
1001         
1002     },
1003     
1004     getHorizontalOneBoxColPositions : function(maxX, minY, box)
1005     {
1006         var pos = [];
1007         
1008         if(box[0].size == 'md-left'){
1009             pos.push({
1010                 x : maxX - this.unitWidth * (box[0].x - 1) - this.gutter * (box[0].x - 2),
1011                 y : minY
1012             });
1013             
1014             return pos;
1015         }
1016         
1017         if(box[0].size == 'md-right'){
1018             pos.push({
1019                 x : maxX - this.unitWidth * (box[0].x - 1) - this.gutter * (box[0].x - 2),
1020                 y : minY + (this.unitWidth + this.gutter) * 1
1021             });
1022             
1023             return pos;
1024         }
1025         
1026         var rand = Math.floor(Math.random() * (4 - box[0].y));
1027         
1028         pos.push({
1029             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1030             y : minY + (this.unitWidth + this.gutter) * rand
1031         });
1032         
1033         return pos;
1034         
1035     },
1036     
1037     getHorizontalTwoBoxColPositions : function(maxX, minY, box)
1038     {
1039         var pos = [];
1040         
1041         pos.push({
1042             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1043             y : minY
1044         });
1045
1046         pos.push({
1047             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1048             y : minY + (this.unitWidth + this.gutter) * (3 - box[1].y)
1049         });
1050         
1051         return pos;
1052         
1053     },
1054     
1055     getHorizontalThreeBoxColPositions : function(maxX, minY, box)
1056     {
1057         var pos = [];
1058         
1059         pos.push({
1060             x : maxX - this.unitWidth,
1061             y : minY
1062         });
1063         
1064         pos.push({
1065             x : maxX - this.unitWidth,
1066             y : minY - this.unitWidth - this.gutter
1067         });
1068         
1069         pos.push({
1070             x : maxX - this.unitWidth,
1071             y : minY - (this.unitWidth + this.gutter) * 2
1072         });
1073         
1074         return pos;
1075         
1076     }
1077     
1078 });
1079
1080  
1081
1082