OSDN Git Service

add url validator
[pettanr/pettanr.git] / app / models / panel.rb
1 class Panel < ActiveRecord::Base
2   belongs_to :comic
3   belongs_to :author
4   belongs_to :resource_picture
5 #  belongs_to :background_picture, :class_name => 'ResourcePicture'
6   has_many :panel_pictures, :dependent => :destroy
7   has_many :speech_balloons, :dependent => :destroy
8   accepts_nested_attributes_for :panel_pictures, :allow_destroy => true
9   accepts_nested_attributes_for :speech_balloons, :allow_destroy => true
10
11 #  validates :comic_id, :presence => true, :numericality => true, :existence => true, :uniqueness => {:scope => :t} 
12   validates :resource_picture_id, :numericality => {:allow_blank => true}
13   validates :width, :presence => true, :numericality => true, :natural_number => true
14   validates :height, :presence => true, :numericality => true, :natural_number => true
15   validates :border, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
16   validates :x, :numericality => {:allow_blank => true}
17   validates :y, :numericality => {:allow_blank => true}
18   validates :z, :numericality => {:allow_blank => true, :greater_than => 0}
19   validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
20   validates :author_id, :presence => true, :numericality => true, :existence => true
21   
22   def supply_default au
23     return false unless au
24     c = self.comic_id ? Comic.show(self.comic_id, au) : nil
25     if c
26       self.width = c.width if self.width.blank?
27       self.height = c.height if self.height.blank?
28       self.t = Panel.new_t(c.id) if self.t.blank? and self.new_record?
29     end
30     self.border = 0 if self.border.blank?
31     self.author_id = au.id
32   end
33   
34   def self.new_t comic_id
35     r = Panel.max_t(comic_id)
36     r.blank? ? 0 : r.to_i + 1
37   end
38   
39   def self.max_t comic_id
40     Panel.maximum(:t, :conditions => ['comic_id = ?', comic_id])
41   end
42   
43   def self.find_t comic_id, t
44     Panel.find(:first, :conditions => ['comic_id = ? and t = ?', comic_id, t])
45   end
46
47   #更新する時にPanelIDをチェックしとかないと勝手に所属先を変えられるゾ!?
48   
49   def store
50    self.speech_balloons
51     f = nil
52     f = Panel.find_t(self.comic_id, self.t) if self.t
53     if f
54       Panel.update_all('t = t + 1', ['comic_id = ? and t >= ?', self.comic_id, self.t])
55     else
56       self.t = Panel.new_t self.comic_id
57     end
58     self.save
59   end
60   
61   def move_to new_t
62     return true if self.t == new_t
63     if self.t > new_t
64       Panel.update_all('t = t + 1', ['comic_id = ? and (t >= ? and t < ?)', self.comic_id, new_t, self.t])
65     else
66       nf = Panel.find_t(self.comic_id, new_t)
67       max_t = Panel.max_t.to_i self.comic_id
68       new_t = max_t if new_t > max_t
69       Panel.update_all('t = t - 1', ['comic_id = ? and (t > ? and t <= ?)', self.comic_id, self.t, new_t])
70     end
71     self.t = new_t
72     self.save
73   end
74   
75   def destroy_and_shorten
76     Panel.update_all('t = t - 1', ['comic_id = ? and (t > ?)', self.comic_id, self.t])
77     self.destroy
78   end
79   
80   def self.default_page_size
81     25
82   end
83   
84   def self.max_page_size
85     100
86   end
87   
88   def self.page prm = nil
89     page = prm.to_i
90     page = 1 if page < 1
91     page
92   end
93   
94   def self.page_size prm = self.default_page_size
95     page_size = prm.to_i
96     page_size = self.max_page_size if page_size > self.max_page_size
97     page_size = self.default_page_size if page_size < 1
98     page_size
99   end
100   
101   def self.offset cnt, prm = nil
102     offset = prm.to_i
103     offset = cnt - 1 if offset >= cnt
104     offset = cnt - offset.abs if offset < 0
105     offset = 0 if offset < 0
106     offset
107   end
108   
109   def self.list opt = {}, page = 1, page_size = self.default_page_size
110     opt.merge!(self.list_opt) unless opt[:include]
111     opt.merge!({:order => 'updated_at desc', :limit => page_size, :offset => (page -1) * page_size})
112     Panel.find(:all, opt)
113   end
114   
115   def self.list_opt
116     {:include => {
117       :comic => :author, 
118       :panel_pictures => {
119         :resource_picture => {:artist => {}, :license => {}}
120       }, 
121       :speech_balloons => {:balloons => {}, :speeches => {}},
122       :author => {}
123     }}
124   end
125   
126   def self.list_json_opt
127     {:include => {
128       :comic => {:author => {}}, 
129       :panel_pictures => {
130         :resource_picture => {:artist => {}, :license => {}}
131       }, 
132       :speech_balloons => {:balloons => {}, :speeches => {}},
133       :author => {}
134     }}
135   end
136   
137   def self.show rid, au, opt = {}
138     r = Panel.find(rid, :include => self.show_include_opt(opt))
139     raise ActiveRecord::Forbidden unless r.visible?(au)
140     r
141   end
142   
143   def self.show_include_opt opt = {}
144     res = {
145       :comic => :author, 
146       :panel_pictures => {
147         :resource_picture => {:artist => {}, :license => {}}
148       }, 
149       :speech_balloons => {:balloons => {}, :speeches => {}},
150       :author => {}
151     }
152     res.merge!(opt[:include]) if opt[:include]
153     res
154   end
155   
156   def self.show_json_include_opt
157     {:include => {
158       :comic => {:author => {}}, 
159       :panel_pictures => {
160         :resource_picture => {:artist => {}, :license => {}}
161       }, 
162       :speech_balloons => {:balloons => {}, :speeches => {}},
163       :author => {}
164     }}
165   end
166   
167   def visible? au
168     return false unless au
169     return false unless self.comic
170     self.comic.visible?(au) or self.author_id == au.id
171   end
172   
173   def own? author
174     return false unless author
175     self.author_id == author.id
176   end
177   
178   def sort_by_time
179     pe = []
180     self.panel_pictures.each do |picture|
181       pe[picture.t] = picture
182     end
183     self.speech_balloons.each do |sb|
184       pe[sb.t] = sb
185     end
186     pe
187   end
188   
189   def each_element
190     self.sort_by_time.each do |e|
191       yield e
192     end
193   end
194   
195   def panel_elements
196     res = []
197     self.each_element do |elm|
198       if elm.kind_of?(PanelPicture)
199         res[elm.t] = elm.to_json({:include => :resource_picture})
200       end
201       if elm.kind_of?(SpeechBalloon)
202         res[elm.t] = elm.to_json({:include => {:balloons => {}, :speeches => {}}})
203       end
204     end
205     res
206   end
207   
208   def to_json_play
209     self.to_json :methods => :panel_elements
210   end
211   
212   def self.visible_count
213     Panel.count
214   end
215   
216 end