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