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