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 standard = [
404             ['xs', 'xs', 'xs', 'wide'],
405             ['xs', 'xs', 'wide'],
406             ['xs', 'xs', 'sm'],
407             ['xs', 'xs', 'xs'],
408             ['xs', 'wide'],
409             ['xs', 'sm'],
410             ['xs', 'xs'],
411             ['xs'],
412             
413             ['sm', 'xs', 'xs'],
414             ['sm', 'xs'],
415             ['sm'],
416             
417             ['wide', 'xs', 'xs', 'xs'],
418             ['wide', 'xs', 'xs'],
419             ['wide', 'xs'],
420             ['wide']
421         ];
422         
423         var queue = [];
424         
425         var boxes = [];
426         
427         var box = [];
428         
429         Roo.each(items, function(item, k){
430             
431             switch (item.size) {
432                 case 'md' :
433                 case 'md-left' :
434                 case 'md-right' :
435                 case 'tall' :
436                     
437                     if(box.length){
438                         boxes.push(box);
439                         box = [];
440                     }
441                     
442                     boxes.push([item]);
443                     
444                     break;
445                     
446                 case 'xs' :
447                 case 'sm' :
448                 case 'wide' :
449                     
450                     box.push(item);
451                     
452                     break;
453                 default :
454                     break;
455                     
456             }
457             
458         }, this);
459         
460         if(box.length){
461             boxes.push(box);
462             box = [];
463         }
464         
465         var filterPattern = function(box, length)
466         {
467             if(!box.length){
468                 return;
469             }
470             
471             var match = false;
472             
473             var pattern = box.slice(0, length);
474             
475             var format = [];
476             
477             Roo.each(pattern, function(i){
478                 format.push(i.size);
479             }, this);
480             
481             Roo.each(standard, function(s){
482                 
483                 if(String(s) != String(format)){
484                     return;
485                 }
486                 
487                 match = true;
488                 return false;
489                 
490             }, this);
491             
492             if(!match && length == 1){
493                 return;
494             }
495             
496             if(!match){
497                 filterPattern(box, length - 1);
498                 return;
499             }
500                 
501             queue.push(pattern);
502
503             box = box.slice(length, box.length);
504
505             filterPattern(box, 4);
506
507             return;
508             
509         }
510         
511         Roo.each(boxes, function(box, k){
512             
513             if(!box.length){
514                 return;
515             }
516             
517             if(box.length == 1){
518                 queue.push(box);
519                 return;
520             }
521             
522             filterPattern(box, 4);
523             
524         }, this);
525         
526         
527         var prune = [];
528         
529         var pos = this.el.getBox(true);
530         
531         var minX = pos.x;
532         
533         var maxX = pos.right - this.unitWidth * 3 - this.gutter * 2 - this.padWidth;
534         
535         Roo.each(queue, function(box){
536             
537             var mx = 0;
538             
539             Roo.each(box, function(b){
540                 mx = Math.max(mx, b.x);
541             }, this);
542             
543             maxX = maxX - this.unitWidth * mx - this.gutter * (mx - 1) - this.padWidth;
544             
545             
546         }, this);
547         
548         
549         
550         
551         var x = maxX;
552         
553         var queue = [];
554         
555         var box = [];
556         var size = 0;
557         var hit_end = false;
558         
559         Roo.each(items, function(item, k){
560             
561             item.el.setVisibilityMode(Roo.Element.DISPLAY);
562             item.el.show();
563             
564             if(hit_end){
565                 item.el.hide();
566                 return;
567             }
568             
569             if(size + item.y > 3){
570                 queue.push(box);
571                 box = [];
572                 size = 0;
573                 maxX = x;
574             }
575             
576             var width = Math.floor(this.unitWidth * item.x + (this.gutter * (item.x - 1)) + item.el.getPadding('lr'));
577             
578             x = Math.min(x, maxX - width - this.padWidth);
579             
580             if(x < minX){
581                 item.el.hide();
582                 hit_end = true;
583                 return;
584             }
585             
586             size = size + item.y;
587             
588             box.push(item);
589             
590             
591         }, this);
592         
593         if(box.length){
594             queue.push(box);
595         }
596         
597         this._processHorizontalLayoutQueue( queue, eItems, isInstant );
598     },
599     
600     /** Sets position of item in DOM
601     * @param {Element} item
602     * @param {Number} x - horizontal position
603     * @param {Number} y - vertical position
604     * @param {Boolean} isInstant - disables transitions
605     */
606     _processVerticalLayoutQueue : function( queue, isInstant )
607     {
608         var pos = this.el.getBox(true);
609         var x = pos.x;
610         var y = pos.y;
611         var maxY = [];
612         
613         for (var i = 0; i < this.cols; i++){
614             maxY[i] = pos.y;
615         }
616         
617         Roo.each(queue, function(box, k){
618             
619             var col = k % this.cols;
620             
621             Roo.each(box, function(b,kk){
622                 
623                 b.el.position('absolute');
624                 
625                 var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
626                 var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
627                 
628                 if(b.size == 'md-left' || b.size == 'md-right'){
629                     width = Math.floor(this.unitWidth * (b.x - 1) + (this.gutter * (b.x - 2)) + b.el.getPadding('lr'));
630                     height = Math.floor(this.unitWidth * (b.y - 1) + (this.gutter * (b.y - 2)) + b.el.getPadding('tb'));
631                 }
632                 
633                 b.el.setWidth(width);
634                 b.el.setHeight(height);
635                 
636             }, this);
637             
638             for (var i = 0; i < this.cols; i++){
639                 
640                 if(maxY[i] < maxY[col]){
641                     col = i;
642                     continue;
643                 }
644                 
645                 col = Math.min(col, i);
646                 
647             }
648             
649             x = pos.x + col * (this.colWidth + this.padWidth);
650             
651             y = maxY[col];
652             
653             var positions = [];
654             
655             switch (box.length){
656                 case 1 :
657                     positions = this.getVerticalOneBoxColPositions(x, y, box);
658                     break;
659                 case 2 :
660                     positions = this.getVerticalTwoBoxColPositions(x, y, box);
661                     break;
662                 case 3 :
663                     positions = this.getVerticalThreeBoxColPositions(x, y, box);
664                     break;
665                 case 4 :
666                     positions = this.getVerticalFourBoxColPositions(x, y, box);
667                     break;
668                 default :
669                     break;
670             }
671             
672             Roo.each(box, function(b,kk){
673                 
674                 b.el.setXY([positions[kk].x, positions[kk].y], isInstant ? false : true);
675                 
676                 var sz = b.el.getSize();
677                 
678                 maxY[col] = Math.max(maxY[col], positions[kk].y + sz.height + this.padWidth);
679                 
680             }, this);
681             
682         }, this);
683         
684         var mY = 0;
685         
686         for (var i = 0; i < this.cols; i++){
687             mY = Math.max(mY, maxY[i]);
688         }
689         
690         this.el.setHeight(mY - pos.y);
691         
692     },
693     
694 //    _processVerticalAlternativeLayoutQueue : function( items, isInstant )
695 //    {
696 //        var pos = this.el.getBox(true);
697 //        var x = pos.x;
698 //        var y = pos.y;
699 //        var maxX = pos.right;
700 //        
701 //        var maxHeight = 0;
702 //        
703 //        Roo.each(items, function(item, k){
704 //            
705 //            var c = k % 2;
706 //            
707 //            item.el.position('absolute');
708 //                
709 //            var width = Math.floor(this.colWidth + item.el.getPadding('lr'));
710 //
711 //            item.el.setWidth(width);
712 //
713 //            var height = Math.floor(this.colWidth * item.y / item.x + item.el.getPadding('tb'));
714 //
715 //            item.el.setHeight(height);
716 //            
717 //            if(c == 0){
718 //                item.el.setXY([x, y], isInstant ? false : true);
719 //            } else {
720 //                item.el.setXY([maxX - width, y], isInstant ? false : true);
721 //            }
722 //            
723 //            y = y + height + this.alternativePadWidth;
724 //            
725 //            maxHeight = maxHeight + height + this.alternativePadWidth;
726 //            
727 //        }, this);
728 //        
729 //        this.el.setHeight(maxHeight);
730 //        
731 //    },
732     
733     _processHorizontalLayoutQueue : function( queue, eItems, isInstant )
734     {
735         var pos = this.el.getBox(true);
736         
737         var minX = pos.x;
738         var minY = pos.y;
739         
740         var maxX = pos.right;
741         
742         this._processHorizontalEndItem(eItems, maxX, minX, minY, isInstant);
743         
744         var maxX = maxX - this.unitWidth * 3 - this.gutter * 2 - this.padWidth;
745         
746         Roo.each(queue, function(box, k){
747             
748             Roo.each(box, function(b, kk){
749                 
750                 b.el.position('absolute');
751                 
752                 var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
753                 var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
754                 
755                 if(b.size == 'md-left' || b.size == 'md-right'){
756                     width = Math.floor(this.unitWidth * (b.x - 1) + (this.gutter * (b.x - 2)) + b.el.getPadding('lr'));
757                     height = Math.floor(this.unitWidth * (b.y - 1) + (this.gutter * (b.y - 2)) + b.el.getPadding('tb'));
758                 }
759                 
760                 b.el.setWidth(width);
761                 b.el.setHeight(height);
762                 
763             }, this);
764             
765             if(!box.length){
766                 return;
767             }
768             
769             var positions = [];
770             
771             switch (box.length){
772                 case 1 :
773                     positions = this.getHorizontalOneBoxColPositions(maxX, minY, box);
774                     break;
775                 case 2 :
776                     positions = this.getHorizontalTwoBoxColPositions(maxX, minY, box);
777                     break;
778                 case 3 :
779                     positions = this.getHorizontalThreeBoxColPositions(maxX, minY, box);
780                     break;
781                 default :
782                     break;
783             }
784             
785             Roo.each(box, function(b,kk){
786                 
787                 b.el.setXY([positions[kk].x, positions[kk].y], isInstant ? false : true);
788                 
789                 maxX = Math.min(maxX, positions[kk].x - this.padWidth);
790                 
791             }, this);
792             
793         }, this);
794         
795     },
796     
797     _processHorizontalEndItem : function(eItems, maxX, minX, minY, isInstant)
798     {
799         Roo.each(eItems, function(b,k){
800             
801             b.size = (k == 0) ? 'sm' : 'xs';
802             b.x = (k == 0) ? 2 : 1;
803             b.y = (k == 0) ? 2 : 1;
804             
805             b.el.position('absolute');
806             
807             var width = Math.floor(this.unitWidth * b.x + (this.gutter * (b.x - 1)) + b.el.getPadding('lr'));
808                 
809             b.el.setWidth(width);
810             
811             var height = Math.floor(this.unitWidth * b.y + (this.gutter * (b.y - 1)) + b.el.getPadding('tb'));
812             
813             b.el.setHeight(height);
814             
815         }, this);
816
817         var positions = [];
818         
819         positions.push({
820             x : maxX - this.unitWidth * 2 - this.gutter,
821             y : minY
822         });
823         
824         positions.push({
825             x : maxX - this.unitWidth,
826             y : minY + (this.unitWidth + this.gutter) * 2
827         });
828         
829         positions.push({
830             x : maxX - this.unitWidth * 3 - this.gutter * 2,
831             y : minY
832         });
833         
834         Roo.each(eItems, function(b,k){
835             
836             b.el.setXY([positions[k].x, positions[k].y], isInstant ? false : true);
837
838         }, this);
839         
840     },
841     
842     getVerticalOneBoxColPositions : function(x, y, box)
843     {
844         var pos = [];
845         
846         var rand = Math.floor(Math.random() * ((4 - box[0].x)));
847         
848         if(box[0].size == 'md-left'){
849             rand = 0;
850         }
851         
852         if(box[0].size == 'md-right'){
853             rand = 1;
854         }
855         
856         pos.push({
857             x : x + (this.unitWidth + this.gutter) * rand,
858             y : y
859         });
860         
861         return pos;
862     },
863     
864     getVerticalTwoBoxColPositions : function(x, y, box)
865     {
866         var pos = [];
867         
868         if(box[0].size == 'xs'){
869             
870             pos.push({
871                 x : x,
872                 y : y + ((this.unitWidth + this.gutter) * Math.floor(Math.random() * box[1].y))
873             });
874
875             pos.push({
876                 x : x + (this.unitWidth + this.gutter) * (3 - box[1].x),
877                 y : y
878             });
879             
880             return pos;
881             
882         }
883         
884         pos.push({
885             x : x,
886             y : y
887         });
888
889         pos.push({
890             x : x + (this.unitWidth + this.gutter) * 2,
891             y : y + ((this.unitWidth + this.gutter) * Math.floor(Math.random() * box[0].y))
892         });
893         
894         return pos;
895         
896     },
897     
898     getVerticalThreeBoxColPositions : function(x, y, box)
899     {
900         var pos = [];
901         
902         if(box[0].size == 'xs' && box[1].size == 'xs' && box[2].size == 'xs'){
903             
904             pos.push({
905                 x : x,
906                 y : y
907             });
908
909             pos.push({
910                 x : x + (this.unitWidth + this.gutter) * 1,
911                 y : y
912             });
913             
914             pos.push({
915                 x : x + (this.unitWidth + this.gutter) * 2,
916                 y : y
917             });
918             
919             return pos;
920             
921         }
922         
923         if(box[0].size == 'xs' && box[1].size == 'xs'){
924             
925             pos.push({
926                 x : x,
927                 y : y
928             });
929
930             pos.push({
931                 x : x,
932                 y : y + ((this.unitWidth + this.gutter) * (box[2].y - 1))
933             });
934             
935             pos.push({
936                 x : x + (this.unitWidth + this.gutter) * 1,
937                 y : y
938             });
939             
940             return pos;
941             
942         }
943         
944         pos.push({
945             x : x,
946             y : y
947         });
948
949         pos.push({
950             x : x + (this.unitWidth + this.gutter) * 2,
951             y : y
952         });
953
954         pos.push({
955             x : x + (this.unitWidth + this.gutter) * 2,
956             y : y + (this.unitWidth + this.gutter) * (box[0].y - 1)
957         });
958             
959         return pos;
960         
961     },
962     
963     getVerticalFourBoxColPositions : function(x, y, box)
964     {
965         var pos = [];
966         
967         if(box[0].size == 'xs'){
968             
969             pos.push({
970                 x : x,
971                 y : y
972             });
973
974             pos.push({
975                 x : x,
976                 y : y + (this.unitWidth + this.gutter) * 1
977             });
978             
979             pos.push({
980                 x : x,
981                 y : y + (this.unitWidth + this.gutter) * 2
982             });
983             
984             pos.push({
985                 x : x + (this.unitWidth + this.gutter) * 1,
986                 y : y
987             });
988             
989             return pos;
990             
991         }
992         
993         pos.push({
994             x : x,
995             y : y
996         });
997
998         pos.push({
999             x : x + (this.unitWidth + this.gutter) * 2,
1000             y : y
1001         });
1002
1003         pos.push({
1004             x : x + (this.unitWidth + this.gutter) * 2,
1005             y : y + (this.unitWidth + this.gutter) * 1
1006         });
1007
1008         pos.push({
1009             x : x + (this.unitWidth + this.gutter) * 2,
1010             y : y + (this.unitWidth + this.gutter) * 2
1011         });
1012
1013         return pos;
1014         
1015     },
1016     
1017     getHorizontalOneBoxColPositions : function(maxX, minY, box)
1018     {
1019         var pos = [];
1020         
1021         if(box[0].size == 'md-left'){
1022             pos.push({
1023                 x : maxX - this.unitWidth * (box[0].x - 1) - this.gutter * (box[0].x - 2),
1024                 y : minY
1025             });
1026             
1027             return pos;
1028         }
1029         
1030         if(box[0].size == 'md-right'){
1031             pos.push({
1032                 x : maxX - this.unitWidth * (box[0].x - 1) - this.gutter * (box[0].x - 2),
1033                 y : minY + (this.unitWidth + this.gutter) * 1
1034             });
1035             
1036             return pos;
1037         }
1038         
1039         var rand = Math.floor(Math.random() * (4 - box[0].y));
1040         
1041         pos.push({
1042             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1043             y : minY + (this.unitWidth + this.gutter) * rand
1044         });
1045         
1046         return pos;
1047         
1048     },
1049     
1050     getHorizontalTwoBoxColPositions : function(maxX, minY, box)
1051     {
1052         var pos = [];
1053         
1054         pos.push({
1055             x : maxX - this.unitWidth * box[0].x - this.gutter * (box[0].x - 1),
1056             y : minY
1057         });
1058
1059         pos.push({
1060             x : maxX - this.unitWidth * box[1].x - this.gutter * (box[1].x - 1),
1061             y : minY + (this.unitWidth + this.gutter) * (3 - box[1].y)
1062         });
1063         
1064         return pos;
1065         
1066     },
1067     
1068     getHorizontalThreeBoxColPositions : function(maxX, minY, box)
1069     {
1070         var pos = [];
1071         
1072         pos.push({
1073             x : maxX - this.unitWidth,
1074             y : minY
1075         });
1076         
1077         pos.push({
1078             x : maxX - this.unitWidth,
1079             y : minY - this.unitWidth - this.gutter
1080         });
1081         
1082         pos.push({
1083             x : maxX - this.unitWidth,
1084             y : minY - (this.unitWidth + this.gutter) * 2
1085         });
1086         
1087         return pos;
1088         
1089     }
1090     
1091 });
1092
1093  
1094
1095